I already have an application in place and am tweaking it now. In this regard, I am introducing a new signal, which has to be emitted when another signal is emitted. Is this possible in Qt?
Writing a slot just to emit this signal feels so primitive and lame...
Detailing further, I have to connect the button signalClicked() to my own signal say sendSignal(enumtype)...
EDIT: Forgot to mention that I need to send a data with the second signal.
Yes, it is possible without creating additional slot. Just connect signal to signal:
connect(this,SIGNAL(someSignal()),this,SIGNAL(anotherSignal()));
More information in doc.
Edit:
You can share data in connection as usual. Dirty example:
QWidget* obj = new QWidget;
obj->setWindowTitle("WindowTitle");
//share data, pass wrong data to the signal
QObject::connect(obj,SIGNAL(objectNameChanged(QString)),obj,SIGNAL(windowTitleChanged(QString)));
QObject::connect(obj,&QWidget::windowTitleChanged,[](QString str) {qDebug() << str;});
obj->setObjectName("ObjectName");
qDebug() << "But window title is"<< obj->windowTitle();
obj->show();
Output is:
"ObjectName"
But window title is "WindowTitle"
But there is no way to do something like:
connect(this,SIGNAL(someSignal()),this,SIGNAL(anotherSignal("with custom data")));
In this case, you need a separate slot.
Related
I am going to send data collected in the QMainWindow to an object of QDialog via signal-slot connections. Here is the relevant code fragment to do this in mainwindow.cpp:
void MainWindow::on_dialogA_clicked()
{
if(dialogA==NULL) dialogA =new MyDialog();
//'this' refers to MainWindow
connect(this,SIGNAL(sendData(QVector<bool>)), dialogA, SLOT(getData(QVector<bool>)), Qt::QueuedConnection);
dialogA->show();
}
However when working with dialogA, it seems that the data are not updated properly and the dialog interface becomes Not responding after while. I wonder if the signal-slot connection above is right or not, or that is the way to have data communication with a QDiaglog.
Two things...first, switch to the modern method of creating signal/slot connections:
connect (this, &MainWindow::sendData, dialogA, &MyDialog::getData, Qt::QueuedConnection);
If there's something wrong with the definition, using this format allows the compiler to catch it rather than a run-time warning. Assuming the parameters are defined correctly, there's nothing wrong with the "connect" statement except that it's in the wrong place, which is the second issue.
Every time the user clicks, an additional connection is being made between your main window and the dialog. Qt doesn't automatically ensure that only one connection is made between a given signal and slot. It'll create as many as you ask it for. The "connect" call should be part of the "if" block:
if (! dialogA)
{
dialogA =new MyDialog();
connect...
}
Depending on how much data is in that vector and what the dialog does with it, if you click enough times, it may be that you're just processing the data so many times that everything slows down tremendously.
In my project, I want to call a variable QImage image generated in the mainwindow.h, in other class files, e.g., called SegSetupDialog.h. Here the image is loaded by clicking a pushbutton in mainwindow.ui, and the SegSetupDialog is a QDialog, which pops up by clicking one pushbutton in mainwindow.ui.
I tried to use a signal-slot connection to send qimage of mainwindow to SegSetupDialog as follows.
For Class MainWindow:
SegSetupDialog *segsetup;
if(image.isNull()==false)
{
emit sendImgData(image);
qDebug()<<"sendImgData emitted!";
if(segsetup==NULL) segsetup = new SegSetupDialog();
connect(this, SIGNAL(sendImgData(QImage)),segsetup,SLOT(getImgData(QImage)),Qt::QueuedConnection);
}
In SegSetupDialog::getImgData
void SegSetupDialog::getImgData(QImage qimage)
{
qImg = qimage;
qDebug()<<"qimage received!";
}
The above connection seems not to work since the qDebug message in getImgData is not printed out. Anyone can help check something wrong with codes, or suggest other methods for accessing image of mainwindow? Thanks!!
You need to do the signal/slot connection before you emit the signal. Connections are done once, usually in the constructor.
However, you should probably do the connect() in the constructor of SegSetupDialog instead of the MainWindow one. It's SegSetupDialog that wants to be notified about image data updates, so you should establish the connection there.
Also, to make sure the signals and slots are specified correctly, don't use Qt 4 connect() calls. Use Qt 5 ones that are checked at compile-time:
connect(this, &MainWindow::sendImgData,
segsetup, &SegSetupDialog::getImgData, Qt::QueuedConnection);
(Of course change it appropriately if you move it to the SegSetupDialog constructor.)
I have a problem with slots and signals. I created buttons and connected them to the clicked() slot. Then i decided to connect signals and slots manually and since then when I click the button it calls its function twice.
connect(ui->okButton, SIGNAL(clicked()), this, SLOT(on_okButton_clicked()));
void settingswindow::on_okButton_clicked()
{
qDebug() << "ok clicked";
this->close();
}
I was looking for the answer on google, but all i found was this: Where is the generated code of qt signals slots editor but my *.ui file looks like this: pastebin to the code. As you can see there's only one line with and nothing more. I can't find where the information about signals and slots is saved. Rebuild and clean options won't help.
This is not a bug in Qt. If you look at the generated code for your ui_*.h file, you'll notice that the last statement executed in the setupUi() function is a call to QMetaObject::connectSlotsByName().
Since your slot already conforms to the naming convention that this function is looking for, your slot is automatically connected to the signal.
By manually connecting the signal to the slot, in your settingswindow class, you effectively duplicate the connection.
As #Devopia mentioned, this is a documented feature.
I've read lots of similar threads to this one but im not such a great programmer that i can make sense of it all. Im using qtcreator to make life simple and want to maka a program that can trigger another process, monitor its stdout and then kill it if necessary.
What I assume i want to do is create a QTextedit in the designer and plug a signal into it that updates the contained text whenever the stream updates, so far so good, but thats where i get fuzzy. My initial thought was to create a subclass of QObject that starts the process as a QProcess and whenever the stdout updates the QObject and appends new data to the QTextedit box.
So my program structure would run like this:
on button press create new QObject derived class.
The QObject derived class constructor starts a QProcess and connects the readyReadStdout() signal to the derived qObject class slot.
When the derived QObject is triggered it takes readyReadStdout() and appends any new data to the QTetEdit box.
on button press, call the derived QObject destructor and which kills the process.
Has anybody done something similar? Like i say ive read similar posts but sometimes it takes asking a question in your own words to be able to understand it
Thanks everyone (also my forst post, woo:)
Ok so heres my update:
I have added an instance of QProcess class (named proc) to my mainWindow class and also new instance of a QObject derived class (named procLog) to which I added a slot. I want this slot to take the readyReadStandardOutput() signal as a trigger to call readAllStandardOutput() and emit the new line to a new signal in procLog, I'm having trouble connecting the QProcess slot to the QObject derived class. heres what I'm trying:
connect(proc, SIGNAL(readyReadStandardOutput ()), procLog, SLOT(logReady()));
I get, error: QObject::connect: Cannot connect (null)::readyReadStandardOutput () to (null)::logReady()
Do you know why this is. Aslo is there a way to add code blocks to text in the comments?
thanks!
I'm trying to get the information of several of a class' member variables on the receiving end of a slot/signal setup, so I'd like to pass the entire class through. Unfortunately, after the class has been passed, the member variables seem to be empty. Here's some code snippets:
This sets up the signal to pass the class
signals:
void selected(const ControlIcon *controlIcon);
this is the slot/signal connection
connect(controllerList->serialController, SIGNAL(selected(const ControlIcon*)),
infoView, SLOT(serialControllerSelected(const ControlIcon*)));
I emit the signal from within the class to be passed
emit selected(this);
Here's the code to call on the class' member data
QLabel *ASCIIStringHolder = new QLabel;
ASCIIStringHolder->setText(controlIcon->m_ASCIIString);
Nothing shows up in the label, and when I set a breakpoint, I can see that there's nothing inside m_ASCIIString.
I looked to make sure that it was being assigned some text in the first place, and that's not the problem. I also tried the signal/slot setup with and without const.
Any help would be appreciated.
Qt signal/slot mechanism needs metainformation about your custom types, to be able to send them in emitted signals.
To achieve that, register your type with qRegisterMetaType<MyDataType>("MyDataType");
Consult official QMetaType documentation for more information about this.
First, since you are using an auto connection, do both sender and receiver live in the same thread? If not, it could happen that the call is queued and when it arrives, the data in the sender was already modified. You could try to use a direct connection just to make sure this isn't the problem.
Second, just for the fun of it, did you try to access the sender by using qobject_cast<ControlIcon*>(sender()) within the slot? This is how it is usually done if the signal doesn't pass this as an argument. Like this:
QLabel *ASCIIStringHolder = new QLabel;
// this is instead of the argument to the slot:
ControlIcon *controlIcon = qobject_cast<ControlIcon*>(sender());
ASCIIStringHolder->setText(controlIcon->m_ASCIIString);
The signal can't be declared to be passing a class and then actually pass the child of that class. I changed the signal, slot, and connect() to be SerialController (the child of ControllerIcon), and everything worked fine.