C++ - QT - SIGNAL and SLOT understanding



我不明白为什么这个代码不起作用,也许我不理解SIGNAL和SLOT的概念。

例如:我有一个名为MainWindow的类,这个类包含ui组件。在这个UI上,我可以启动和关闭本地服务器。该服务器是在类MyServer中定义的。MainWindow类具有对MyServer class '&myServer'的引用。如果我在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()));

这个问题是:我在MyServer类中有一个名为void signalMessage();的SIGNAL,这个信号在函数void startServer();void shutDownServer() 中被调用

signals:
    void signalMessage();

通常在调用MyServer类中的singalMessage()之后,应该调用MainWindow类中的函数slotUpdate()。但只调用signalMessage(),而不调用slotUpadate()

我希望任何人都能理解我的问题。我可以定义插槽并从MainWindow向MyServer发送信号,但不能反向。:(

编辑:好的,这里有一些代码可以理解我的问题:

主窗口.h

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

public slots:
    void slotUpdate();
...

主窗口.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()";
}

为了接收/发射信号:

  1. 您的类必须派生自QObject
  2. 类的声明中必须包含Q_OBJECT宏
  3. 此类的头文件必须使用moc处理(当您使用qmake生成项目文件时,会自动发生)

故障排除:

  1. 如果您的头最初没有带有signal/slots的类,而您添加了它们,则需要重新运行qmake并重新生成Makefile(或visualstudio项目文件)
  2. 将程序的调试版本构建为控制台应用程序(*.pro文件中的CONFIG += console),或者在运行程序时读取调试输出。如果您输入了一个拼写错误,qt无法连接到信号,它会将有关此问题的消息打印到调试输出窗口或stdout/stderr中。这是注意到未能建立连接的唯一方法——连接是在运行应用程序时(在运行时)建立的,而不是在编译时
  3. 如果您忘记将Q_OBJECT添加到类声明中,或者如果您没有通过moc运行头部(具有signals/slot的类),您将无法连接到signals/sslot

应该不需要为信号编写函数体。如果你必须编写函数体,那么你的代码就有问题了。

此外:
Qt有很棒的文档,所以您应该阅读它如果您安装了qt,文档应该可以通过"助理"程序获得,也可以在线获得。

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

解决方案:

@arne:

"您在源文件中提供了该函数的实现,即void MyServer::signalMessage(){qDebug()<<"getMessage()";}。这是不正确的。"

"连接语句已经正确。您的服务器接收到另一个信号表明QOBJECT宏在那里。只需删除函数实现,即我在上一条评论中引用的代码(来自cpp文件)"

所以我必须删除.cpp文件中singalMessage();的实现。之后的线路connect(&myServer,SIGNAL(singalMessage()),this,SLOT(slotUpdate()));作品

您不能像在myserver.cpp文件中那样自己实现signalMessage。这样,来自QObject的信号将被覆盖,而不会发出信号。

最新更新