why do I get an error in this code - qt

I have looked at several different tutorials and all the code looks the same but when I try to compile it I get two errors. They are no match for call to '(QFile) (QString&)' no match for call to '(QTextSteam) (Qfile)'. Could you please explain why? The following is part of my code if you need more just ask.
my header chunk of code
private:
QLabel *label;
QTextEdit *left;
QTextEdit *right;
QLineEdit *user;
QTextStream file;
QFile namefile;
QString name;
QString n;
my source code
n ="name.txt";
namefile(n);
if (!namefile.open(QFile::ReadOnly))
{
return;
}
file(&namefile);
name=file.readLine();
right->setText(name);

Your question seems to have more to do with C++ than with Qt. In particular, it would be worthwhile for you to look into C++ initialization lists, and how class members are constructed in general.
In any event, I am assuming that the code you've listed as "my source code" is in the constructor of a class. One option is to first re-order the private members such that they are listed in order of initialization:
private:
QString n;
QFile namefile;
QTextStream file;
QString name;
Then to initialize them in the initialization list of the class constructor:
MyClass::MyClass()
:n("name.txt")
,namefile(n)
,file(&namefile)
{
if (!namefile.open(QIODevice::ReadOnly))
{
return;
}
name = file.readLine();
// Rest of your code goes here.
}
There are other ways of accomplishing this, but I'll leave it to you to research what I've suggested above.

Just change
file.setDevice(&namefile);

Related

qt share variables between slots

Im having trouble figuring out how to use variables across slots. I have read the signals and slots page a few times over and haven't been able to figure out exactly how to use the connect function. I'm trying to have one button to select the directory, and then have it sent over to the other slot for when I hit print, so it can use that directory. Thanks for the help.
void MainWindow::on_pushButton_clicked()
{
QApplication app(int argc, char** argv());
int n = 107;
for (int q = 1; q <= n; q++)
{
QString fileName =(folderName + "/batch_%1.jpg").arg(q);
// QPrinter printer;
//QPrintDialog *dlg = new QPrintDialog(&printer,0);
//if(dlg->exec() == QDialog::Accepted) {
QPrinter printer(QPrinter::HighResolution);
printer.setResolution(300);
printer.setCopyCount(1);
printer.setDoubleSidedPrinting(false);
printer.setDuplex(QPrinter::DuplexNone);
printer.setColorMode(QPrinter::Color);
printer.setPageSize(QPrinter::Letter);
printer.setPaperSize(QPrinter::Letter);
printer.setPaperSource(QPrinter::Auto);
printer.setOrientation(QPrinter::Portrait);
printer.setPageMargins(0.0, 0.0, 0.0, 0.0, QPrinter::Inch);
QString outputFileName = QStringLiteral("/Users/alexdotzler/Desktop/testing/test%1.pdf").arg(q);
printer.setOutputFileName(outputFileName);
printer.setOutputFormat(QPrinter::PdfFormat);
QImage img(fileName);
QPainter painter(&printer);
painter.drawImage(QPoint(0,0),img);
painter.end();
}
//delete dlg;
}
void MainWindow::on_pushButton_2_clicked()
{
QString folderName = QFileDialog::getExistingDirectory(0, ("Select file"), QDir::currentPath());
}
At first, remember about Minimal reproducible example. This is not only about example, but also about minimal. In this case, your printing code is not nessessary.
Following your question, slot is just a function of class. And in your case, you can jist create printing function, that will be called from both pushButton 1 and 2.
Also, don't be await of real magic from sig/slots. It looks like, but not. Connect slot to signal is just virtual call to function B when function A called.
Then let's go a bit deeply into the world of signals and slots.
You can connect (slots or signals) to signals . No other way.
Basically, signals and slots used to pass data between different objects or to inform them about something.
// foo.h
class First {
...
signals:
void newData(QVariant val);
};
// bar.h
class Another {...
public slots:
void getNewData(QVariant val);
};
// main.cpp
Another another1;
First first1;
QObject::connect(first1, &First::newData, another1, &Another::getNewData);
You can also create something can be called "Connections tree", when signal [Another::sig1] connected to [Third::sig2], which connected to signal [Fourth::sig3] and slot [Fifth::slot1], and so on. I'm not sure someone really need it, but be free to play with.
AFAIK, the only reason to use signal/slot connection inside single class, is when you need to pass some data to GUI thread from another thread running in GUI. Please, don't do that in real projects.
Make folderName a member of your MainWindow class so it will be accessible by your pushButton clicked slots. Then you can read/write it as necessary from those slots.

Remove first bytes from QByteArray

I want to write a function in which QByteArray is input to the function.
I want to remove some header from receive data and store it into global QByteArray.
void abc::CopyData(const QByteArray &data)
{
switch(RequestPacketCount)
{
case REQUEST_FIRST_PACKET:
{
ByteArrayData = data;
}
break;
case REQUEST_SECOND_PACKET:
case REQUEST_THIRD_PACKET:
ByteArrayData.append(data);
}
}
I want to remove 'n' no. of byte from start of 'data' and store remaining data into 'ByteArrayData'
Thanks in advance.
What you seem to want is simply copy the original array and use remove;
ByteArrayData = data;
ByteArrayData.remove(0, n); // Removes first n bytes of ByteArrayData,
// leaving data unchanged
Since a QByteArray is implicitly shared, the construction of the copy takes constant time, and the modification (deletion) is what will make the actual copy when needed.
To append efficiently, you can just use data to get to the byte array, and append the part you want. That will prevent un-necessary temporary objects. That would look something like;
ByteArrayData.append(data.data() + n, data.size() - n);
You can use QByteArray::mid:
ByteArrayData = data.mid(n);
//...
ByteArrayData.append(data.mid(n));
Adding to Joachim's answer, in C++ it's rather unfortunate that some implementation details leak into the interface, but it's still preferred for performance reasons to let the compiler do the copying by passing the argument as value. So, paraphrasing, the best solution would be:
void abc::CopyData(QByteArray data)
{
...
data.remove(0, n);
...
ByteArrayData.append(data);
}
The only place where you definitely do not want to have such arguments passed by value is a signal declaration - signals never modify their data. It's fine for a slot to do so, though:
class MyClass : public QObject {
Q_OBJECT
...
public:
// pass by const reference in signals
Q_SIGNAL void dataSource(const QByteArray &); // The only correct signal form
// pass by const reference or value in slots, depending on use
Q_SLOT void dataSink1(const QByteArray &); // Valid
Q_SLOT void dataSink2(QByteArray); // Valid as well.
};
Connecting to either slot uses the same code whether it's Qt4 or Qt5 connection style. Thus you don't have to worry about such interface changes due to leaked implementation details breaking your code.
// Qt4 - you should elide const and reference anyway
connect(src, SIGNAL(dataSource(QByteArray)), dst, SLOT(dataSink1(QByteArray));
connect(src, SIGNAL(dataSource(QByteArray)), dst, SLOT(dataSink2(QByteArray));
// Qt5
connect(src, &MyClass::dataSource, dst, &MyClass::dataSink1);
connect(src, &MyClass::dataSource, dst, &MyClass::dataSink2);

Qt C++ vector of QFiles error

I have the following:
QString themePath(":/themes/");
std::vector<QString> resourcePaths;
resourcePaths.push_back(QString("html/details.html"));
std::vector<QFile> resources;
for (std::vector<QString>::iterator it = resourcePaths.begin(); it != resourcePaths.end(); ++it) {
QString path = QString("%1%2/%3").arg(themePath, THEME, *it);
QFile resource(path);
resources.push_back(resource);
}
gives me the following error:
error: 'QFile::QFile(const QFile&)' is private.
I get the same error if I use QList instead of std::vector.
Thank you for your attention.
The problem, is that you use QFile values in the container which implicitly perform copying of items with using the copy constructor which is private member function of QFile class. The compiler tells you that. To solve this you can try to simply store QFile pointers instead.

How to pass argument through signal and slots?

My GUI consists of a LineEdit and a PushButton. When the PushButton is clicked, the slot clicked() is called. I want to setup a signal-slot relationship between clicked() as the signal and doSomething() as the slot. The issue is that doSomething() does not have access to the UI and doSomething() relies on the text of LineEdit to work.
I see two solutions:
Grant doSomething() access to the UI.
I want to be able to pass a QString to doSomething() as an argument. clicked() does not accept any arguments. Qsignalmapper might be what I'm looking for. However, it seems like the mapper only passes arguments based on what the signal is. The arguments therefore need to be setup in advance and it seems like it does not help me here.
How would I do solution 2?
Assuming a C++ solution, you might consider using an intermediate signal like the following for #2:
connect(thisWidget, SIGNAL(clicked()),
thisWidget, SLOT(slotClickHandler()));
then:
void slotClickHandler()
{
QString s = "my variable string here";
emit sigDoSomething(s);
}
and them:
void slotDoSomething(const QString &s)
{
// Do something interesting with s here
}
Note that this snippet assumes you've defined a new signal sigDoSomething(const QString &) and a private slot void slotDoSomething(const QString &).

Qt - Connected but doesn't work

I have problem with one class in my project, after click appears new window with QTableWidget and QPushButton, after clicking the button I should have "test" on stdout, but nothing shows, here are parts of this code:
Header:
class ClientsSelector : public QWidget {
Q_OBJECT
public:
ClientsSelector(InvoiceTab* parent);
QWidget *window;
private:
QPushButton *accept;
public slots:
void loadData();
Constructor:
window = new QWidget();
layout = new QGridLayout();
layout->addWidget(table, 0, 0);
/*code*/
accept = new QPushButton(QString::fromUtf8("Load data"));
connect(accept, SIGNAL(clicked()), this, SLOT(loadData()));
layout->addWidget(accept, 0, 1);
/*code*/
window->setLayout(layout);
window->show();
Method:
void ClientsSelector::loadData() {
QTextStream std(stdout);
std << "test" << endl;
}
I have not even one warning nor error. I have nothing on stdout, it looks like button was connected to wrong object(?)
How do you instantiate ClientsSelector? Isn't it a singleton or global variable by chance? Try moving the connect call to a separate init function which is called after the ClientsSelector constructor. It helped me in similar WTF situations. It has something to do with the fact that each QObject inheritor has a static metadata member and you can't be sure about when it is fully initialized until the constructor finishes. connect won't work without that metadata.
See for example here: http://www.qtcentre.org/threads/9479-connect-in-constructor
If still lost, go through this checklist. Qt signals are so easy to use, everybody sometimes forgets it also has some requirements.
Seems like you forgot a closing " on the test printout.
Try using
qDebug() << "test";
instead of QTextstream
You can do following to make sure that the connection was made and slot is called.
connect function returns status of connection. Check if the connection was made properly.
put a breakpoint and see if the loadData() is called when button is pressed.
This might help to find the cause.

Resources