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

现在,运行此程序会将其发送到无限循环中,以寻找新的连接。

Observation:如果我不调用app.exec(),程序会立即返回(应该如此)。
Question:为什么?

Question:如果我已将插槽连接为排队连接,那么何时执行插槽调用?
Question:如果app.exec()是某种无限循环,newConnection()信号是如何发出的?

Big Question:他们这里有没有“第二条线索”?(我期待一个不,一个非常优雅的解释:))

谢谢,
jr

PS:还有谁有这种嵌套括号综合症?像“(.. :))”或“(..(..))”?

4

3 回答 3

12

如果你不调用 app.exec() 那么程序会到达你的 main() 的末尾并结束。(为什么?没有更多的代码可以执行!)

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

do
{
  get event from system
  handle event
}
while (true);

如果您使用排队连接,则该事件将添加到您的事件队列中,并将在未来的某个时间点在 app.exec() 循环期间执行。

您的程序中没有第二个线程。事件由操作系统异步传递,这就是为什么看起来还有其他事情发生的原因。有,但不在您的程序中。

于 2009-09-24T15:52:03.200 回答
0

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

更新:
主事件循环和 qmake 生成的胶水代码负责将事件消息QTcpServerConnectionHandler.

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

于 2009-09-24T14:49:55.017 回答
0

当您说它进入无限循环时,您的意思是它使程序崩溃?

因为 listen() 将按照您设置的方式成为主应用程序事件循环的一部分,该循环一直运行到您退出程序。我不确定问题是什么。每当遇到信号时,在主应用程序事件循环 (exec()) 中发出信号应该没有问题。

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

于 2009-09-24T15:05:46.350 回答