简体   繁体   中英

C++ - QT - SIGNAL and SLOT understanding

I dont understand why this code doesnt work, maybe I haven't understanding the concept of SIGNAL and SLOT.

For example: I have a class named MainWindow , this class contains the ui components. On this UI I can start and shut down a local server. This server is defined in class MyServer . The MainWindow class has a reference to MyServer class '&myServer' . If i do this in class mainwindow.cpp it works:

connect(ui->startServer,SIGNAL(clicked()),&myServer,SLOT(startServer()));
connect(ui->shutdownServer,SIGNAL(clicked()),&myServer,SLOT(shutDownServer()));

but this line not:

connect(&myServer,SIGNAL(signalMessage()), this, SLOT(slotUpdate()));

This Problem is: I have a SIGNAL named void signalMessage(); in MyServer class, this signal is called in function void startServer(); and void shutDownServer()

signals:
    void signalMessage();

Normally after calling singalMessage() in MyServer class, the function slotUpdate() in MainWindow class should be called. But only signalMessage() is called and not slotUpadate() .

I hope anyone understand my problem. I can define slot and signal from MainWindow to MyServer but not reverse. :(

Edit: Okey, here some code for understanding my problem:

mainwindow.h

...
public:
    Ui::MainWindow *ui;
    MyServer myServer;


public slots:
    void slotUpdate();
...

mainwindow.cpp

...
connect(ui->startServer,SIGNAL(clicked()),&myServer,SLOT(startServer()));
connect(ui->shutdownServer,SIGNAL(clicked()),&myServer,SLOT(shutDownServer()));
connect(&myServer,SIGNAL(signalMessage()), this, SLOT(slotUpdate()));
...
void MainWindow::slotUpdate()
{
    qDebug()<< "update()";
}
...

myserver.h

public slots:
void startServer();//start the server on 127.0.0.1 port: 1234
void shutDownServer();//disconnect threads, shut down server

signals:
    void signalMessage();

myserver.cpp

...
void MyServer::startServer(){
if(!this->listen(QHostAddress::Any,1234)){
    message.append("Could not start server, because server is already running");
}else{
    message.append("Listening...");
}

emit signalMessage();
}

...
void MyServer::signalMessage()
{
  qDebug() << "getMessage()";
}

In order to receive/emit signals:

  1. Your class must be derived from QObject.
  2. Your class must contain Q_OBJECT macro within its declaration.
  3. Header file with this class must be processed with moc (happens automatically, when you use qmake to generate project file).

Troubleshooting:

  1. If your header didn't originally have classes with signal/slots and you added them, you'll need to re-run qmake and regenerate Makefile(or visual studio project file).
  2. Build debug versions of your program as console applications ( CONFIG += console in *.pro file) OR read debug output when you run your program. If you make a typo and qt can't connect to a signal it will print message about this problem either into debug output window or into stdout/stderr. That's the only way to notice that you failed to establish connection - connections are established when you RUN application (at runtime), not at compile-time.
  3. If you forget to add Q_OBJECT into class declaration or if you didn't run your headers (with classes that have signals/slot) through moc, you won't be able to connect to signals/slots.

There should be no need to write function body for signals. If you had to write function body, there's a problem with your code.

Also:
Qt has great documentation, so you should read it If you installed qt, documentation should be available via "assistant" program, and it is also available online .

如果必须定义signalMessage函数,则意味着您没有在MyServer类定义中使用Q_OBJECT宏。

The Solution:

@arne:

"You provided an implementation for the function in the source file, ie void MyServer::signalMessage() { qDebug() << "getMessage()"; }. That is not correct."

"The connection statement was correct already. The fact that your sever receives the other signal indicates that the QOBJECT macro is there. Just remove the function implementation, ie the code I quoted in my previous comment (from the cpp file)"

So I must delete the implementation of singalMessage(); in .cpp file. After this the line connect(&myServer, SIGNAL(singalMessage()), this, SLOT(slotUpdate())); works.

You must not implement signalMessage yourself, as you have done in your myserver.cpp file. This way, the one from QObject will be overridden and not signal is sent out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM