C ++ - QT - SIGNAL和SLOT理解

时间:2013-07-01 12:43:50

标签: c++ qt

我不明白为什么这段代码不起作用,也许我还没有理解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();

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

我希望有人理解我的问题。我可以定义从MainWindow到MyServer的插槽和信号,但不能反向。 :(

编辑: Okey,这里有一些用于理解我的问题的代码:

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()";
}

4 个答案:

答案 0 :(得分:2)

为了接收/发出信号:

  1. 您的类必须从QObject派生。
  2. 您的类必须在其声明中包含Q_OBJECT宏。
  3. 此类的头文件必须使用moc处理(当您使用qmake生成项目文件时自动发生)。
  4. 故障排除:

    1. 如果您的标题最初没有带信号/插槽的类并且您添加了它们,则需要重新运行qmake并重新生成Makefile(或visual studio项目文件)。
    2. 将程序的调试版本构建为控制台应用程序(* .pro文件中为CONFIG += console)或在运行程序时读取调试输出。如果您输入错字并且qt无法连接到信号,它会将有关此问题的消息打印到调试输出窗口或stdout / stderr中。这是注意到您无法建立连接的唯一方法 - 在运行RUN应用程序时(在运行时)建立连接,而不是在编译时建立连接。
    3. 如果您忘记将Q_OBJECT添加到类声明中,或者如果您没有通过moc运行标头(具有信号/插槽的类),则无法连接到信号/插槽。
    4. 不需要为信号编写函数体。如果你必须编写函数体,那么你的代码就会出现问题。

      此外:
      Qt有很棒的文档,所以你应该阅读它 如果你安装了qt,那么应该通过“助手”程序提供文档,它也是available online

答案 1 :(得分:1)

如果必须定义signalMessage函数,则表示您未在Q_OBJECT类定义中使用MyServer宏。

答案 2 :(得分:1)

解决方案:

@arne:

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

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

所以我必须删除.cpp文件中singalMessage();的实现。在此之后 connect(&amp; myServer,SIGNAL(singalMessage()),this,SLOT(slotUpdate()));的工作原理。

答案 3 :(得分:0)

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