【问题标题】:Qt signals and slots, threads, app.exec(), and related queriesQt 信号和槽、线程、app.exec() 和相关查询
【发布时间】:2009-09-24 14:36:02
【问题描述】:

[与this question相关]

我编写这段代码是为了了解 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:还有谁有这种嵌套括号综合症?像“(.. :))”还是“(.. (..))”?

【问题讨论】:

    标签: c++ qt signals-slots


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 还有一件事:如果主事件循环正忙于从系统获取事件,谁在生成它们?如果主循环正忙于在此循环中等待,newConnection() 信号是如何发出的?
    • @harshath.jr - 我以前没有使用过 QTcpServer,但从文档看来它要求操作系统将 Tcp 事件传递给您的程序。当您的程序处理该 tcp 事件时,QTcpServer 会执行所需的操作,然后发出 newConnection()。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-15
        • 2015-07-18
        相关资源
        最近更新 更多