Qt信号和槽、线程、app.exec()以及相关查询

8

[与这个问题相关]

我写了这段代码来理解qt信号和槽的工作原理。我需要有人解释行为,并告诉我我的结论是否正确。

我的程序:

connectionhandler.h

#ifndef CONNECTIONHANDLER_H
#define CONNECTIONHANDLER_H

#include <QTcpServer>
class ConnectionHandler : public QObject
{
    Q_OBJECT
public:
    ConnectionHandler();
public slots:
    void newConn();
private:
    QTcpServer *server;
};

#endif // CONNECTIONHANDLER_H

connectionhandler.cpp

#include "connectionhandler.h"
#include <QTextStream>

ConnectionHandler::ConnectionHandler() {
    server = new QTcpServer;
    server->listen(QHostAddress::LocalHost, 8080);
    QObject::connect(server, SIGNAL(newConnection()),this, SLOT(newConn()));
}
void ConnectionHandler::newConn() {
    QTextStream out(stdout);
    out << "new kanneksan!\n";
    out.flush();
}

main.cpp

#include <QCoreApplication>
#include "connectionhandler.h"

int main(int argc, char* argv[]) {
    QCoreApplication app(argc,argv);
    ConnectionHandler handler;
    return app.exec();
}

现在运行这个程序会使它陷入一个无限循环,寻找新的连接。
观察:如果我不调用app.exec(),程序会立即返回(应该是这样)。问题:为什么?
问题:如果我将槽连接为排队连接,那么槽调用将在何时执行?问题:如果app.exec()是一种无限循环,那么newConnection()信号如何被发出?
重要问题:这里是否涉及任何"第二个线程"?(我期望得到否定答案和一个优雅的解释:))
谢谢, jrh
附言:还有谁有这种嵌套括号综合症吗?像"(.. :))"或"(.. (..))"?
3个回答

13

如果你不调用app.exec(),那么程序会执行完main()函数后就结束了。(为什么?因为没有更多的代码需要执行了!)

app.exec()是以下样式的无限循环:

do
{
  get event from system
  handle event
}
while (true);
如果您使用排队的连接,那么事件将被添加到事件队列中,在app.exec() 循环期间的某个时间执行。您的程序中没有第二个线程。事件是由操作系统异步传递的,这就是为什么看起来好像发生了其他事情的原因。确实有其他事情发生,但不在您的程序中。

仍有一件事情需要解决:如果主事件循环正在忙于从系统获取事件,那么是谁在生成这些事件呢?如果主循环在等待中,那么newConnection()信号又是如何被发射的呢? - jrharshath
@harshath.jr - 我以前没有使用过QTcpServer,但从文档中看来,它似乎会要求操作系统将Tcp事件传递给您的程序。当您的程序处理该tcp事件时,QTcpServer会执行其所需的操作,然后发出newConnection()信号。 - Bill

0

app.exec() 进入主事件循环并等待直到 exit() 被调用。

更新:
主事件循环和 qmake 生成的粘合代码负责将事件消息从 QTcpServer 传输到您的 ConnectionHandler

如果您使用排队连接,则实际连接到 QTcpServers 插槽的连接将延迟,直到主事件循环传递 连接请求


0

当你说它进入了无限循环时,你是指它使程序崩溃吗?

因为按照你的设置,listen()将成为主应用程序事件循环的一部分,该循环在退出程序之前一直运行。我不确定问题出在哪里。无论何时遇到信号被发射到主应用程序事件循环(exec())中,都不应该有问题。

如果你愿意,你可以让你的ConnectionHandler类扩展QThread,并在它自己的线程中运行listen(),与主应用程序循环分离开来。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接