Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I emit a signal from another class?

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); 
like image 529
lagoru Avatar asked Mar 02 '13 16:03

lagoru


People also ask

How do you emit a signal in Qt?

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.


1 Answers

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.

like image 50
leemes Avatar answered Sep 30 '22 14:09

leemes