我的代码如何在Qt Eventloop开始之前接收信号

How is my code Receiving Signals before the Qt Eventloop is Started

本文关键字:信号 开始 Eventloop 代码 Qt 我的      更新时间:2023-10-16

我试图理解为什么在以下Qt 4.8代码中放置a.exec()调用不需要在我的QProcess waitForFinished()和waitForStarted()调用可以工作之前发生。我理解a.exec()启动事件循环,在我看来,waitFor*槽需要接收一个信号(即'started()'或'finished()'),然后再继续执行。如果事件循环没有启动,怎么会发生这种情况呢?

waitForStarted()的文档:

Blocks until the process has started and the started() signal has been emitted, or until msecs milliseconds have passed.
代码:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    // Exec the i2c command to get the power button status
    QProcess i2cprocess;
    i2cprocess.start("/usr/bin/i2cget -f -y 1 0x4b 0x45");
    // Wait for it to start
    if(!i2cprocess.waitForStarted())
    {
        qDebug() << "Could not start QProcess to check power button status.";
        exit(-1);
    }
    // Wait for it to finish
    bool returnValue = i2cprocess.waitForFinished();
    if ( returnValue )
    {
        QByteArray status = i2cprocess.readAllStandardOutput().trimmed();
        bool ok;
        quint16 hexValue = status.toUInt(&ok, 16);
        qDebug() << "Power button status: " << status << hexValue << (hexValue & 0x01);
        // We want LSB
        exit(hexValue & 0x01);
    }
    else
    {
        qDebug() << "Error, process never completed to check power button status.";
        exit(-1);
    }
    return a.exec();
}

直接信号槽连接只是间接的函数调用,它们与事件循环没有任何关系。

但是,waitForXxxx方法所做的是旋转本地事件循环,直到信号触发。这个信号是由一些代码发出的,操作系统会通知这些代码进程状态发生了变化。该代码在功能上由事件循环"执行"。

记住,在Qt中你可以随心所欲地创建临时事件循环——这是一个不好的做法,你不应该编写使用waitFor方法的代码。它对代码提出了通常不存在的需求——从而引入了bug !

问题是:当等待进程改变状态时,事件循环有什么用?在内部,流程通知需要等待本地事件或回调,这些都从事件循环中得到处理。即使没有使用事件,事件循环也会执行一个可中断的睡眠,这是操作系统向应用程序发送回调所需的。

QProcess的Qt文档说明:-

QProcess提供了一组函数,通过挂起调用线程,直到发出某些信号,这些函数允许在没有事件循环的情况下使用它:

waitForStarted()阻塞,直到进程启动。

waitForReadyRead()阻塞,直到当前读通道上有新的数据可用。

waitForBytesWritten()阻塞,直到一个有效负载的数据被写入到进程。

waitForFinished()阻塞,直到进程完成。

从主线程(调用QApplication::exec()的线程)调用这些函数可能会导致用户界面冻结。