I have a problem with my Qt application. I'm trying to emit a signal from within another class (it is a nested class of the one in which the signal is placed).
I already connected the signal with a slot, which should be fine. But when I try to emit this signal from within this nested class I get the compiler error:
cannot call member function without object
What is wrong? I looked for that in Qt documentation but couldn't find reasonable solution or even explanation.
The simplified class definition looks as follows.
class LogWriter : public QDialog { Q_OBJECT public: class Log : public QObject { Q_OBJECT public: bool print; Log(bool _print, QString _color, QObject *obj = NULL) : QObject(obj) { print = _print; color = _color; } }; LogWriter(QWidget * parent = 0); ~LogWriter(); public slots: void setMinVal(); void setMediumVal(); void setHighVal(); void cleanWindow(); void appendText(QString &text); signals: void signalLogAppend(QString); };
I connect the signal of an instance LOW
of the LogWriter in the client code to some slot using the following function call:
connect(&LOW, SIGNAL(signalLogAppend(QString)), this, SLOT(appendText(QString&)), Qt::DirectConnection);
In Qt, we have an alternative to the callback technique: We use signals and slots. A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal.
To understand the issue you have to understand how signals are emitted:
They are simply a non-static member function call and thus require an instance to be called on (the "sender"). Typically, this instance is this
(if you emit the signal from within another non-static member function of the same class), so the call syntax becomes a normal function call without any (literal) instance. The emit
keyword is optional and is simply a macro which expands to nothing. The following four versions are all the same when written in a member function of the same class which contains the signal:
emit this->signalLogAppend("foo"); emit signalLogAppend("foo"); this->signalLogAppend("foo"); signalLogAppend("foo");
If you emit the signal of the outer class from within the inner class, the this
pointer refers to an instance of the inner class and thus there is some instance missing for the outer class. It's the same like if you call any other function of the outer class from within the inner class: the compiler doesn't know on which object instance (of the outer class) to call it on. So you have to write something like:
emit someLogWriter->signalLogAppend("foo");
Here, someLogWriter
is the instance of LogWriter
for which you want to emit the signal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With