我写了这段代码来理解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();
}
现在,运行此程序会将其发送到无限循环中,以寻找新的连接。
Observation:
如果我不致电app.exec()
,程序会立即返回(应该如此)。
Question:
为什么?
Question:
如果我将插槽连接为排队连接,何时执行插槽调用?
Question:
如果app.exec()
是一个无限循环的排序,那么newConnection()
信号是如何发出的?
Big Question:
他们的任何“第二线程”是否涉及到这里? (我期待一个不,一个非常优雅的解释:))
谢谢,
JRH
PS:还有谁有这种嵌套的括号综合症?喜欢“(.. :))”或“(..(..))”?
答案 0 :(得分:12)
如果你没有调用app.exec(),程序将命中main()的结尾并结束。 (为什么?没有更多的代码可以执行!)
app.exec()是以下样式的无限循环:
do
{
get event from system
handle event
}
while (true);
如果使用排队连接,则事件将添加到事件队列中,并且将在app.exec()循环期间的某个时间点执行。
您的程序中没有第二个帖子。事件由操作系统异步传递,这就是看起来还有其他事情发生的原因。有,但不在您的计划中。
答案 1 :(得分:0)
app.exec()
进入主事件循环并等待exit()
被调用。
<强>更新强>
qmake生成的主事件循环和粘合代码负责将事件消息从QTcpServer
转移到您的ConnectionHandler
。
如果您使用排队连接,则QTcpServers
插槽的实际连接将被延迟,直到主事件循环传递连接请求。
答案 2 :(得分:0)
当你说它进入无限循环时,你的意思是它会使程序崩溃吗?
因为listen()将成为主应用程序事件循环的一部分,就像你设置它一样,直到退出程序为止。我不确定问题是什么。遇到问题时,主应用程序事件循环(exec())中的信号应该没有问题。
如果您愿意,除了主应用程序循环之外,您可以让ConnectionHandler类扩展QThread并在其自己的线程中运行listen()。