1

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

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

signals:
    void signalMessage();

通常在类中调用后,应该调用singalMessage()类中的MyServer函数。但 only被称为而不是。slotUpdate()MainWindowsignalMessage()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()";
}
...

我的服务器.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();

我的服务器.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

4 回答 4

2

为了接收/发射信号:

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

故障排除:

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

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

另外:
Qt 有很好的文档,所以你应该阅读它 如果你安装了 qt,文档应该可以通过“助手”程序获得,也可以在线获得

于 2013-07-01T13:52:25.247 回答
1

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

于 2013-07-01T13:27:59.880 回答
1

解决方案:

@arne:

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

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

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

于 2013-07-01T14:02:24.083 回答
0

您不能像在文件中那样实现signalMessage自己。myserver.cpp这样,一个 fromQObject将被覆盖,而不是发出信号。

于 2013-07-01T13:25:59.890 回答