【问题标题】:How is my code Receiving Signals before the Qt Eventloop is Started我的代码在 Qt 事件循环启动之前如何接收信号
【发布时间】:2015-05-28 12:44:17
【问题描述】:

我试图了解为什么不需要在我的 QProcess waitForFinished() 和 waitForStarted() 调用可以工作之前将 a.exec() 调用放入以下 ​​Qt 4.8 代码中。我知道 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();

}

【问题讨论】:

    标签: c++ linux qt qt4 qeventloop


    【解决方案1】:

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

    不过,waitForXxxx 方法的作用是旋转本地事件循环,直到信号触发。该信号是从一些代码中触发的,这些代码由操作系统通知进程状态已更改。该代码在功能上由事件循环“执行”。

    请记住,在 Qt 中,您可以随心所欲地创建临时事件循环 - 这是一种不好的做法,并且您永远不应该编写使用 waitFor 方法的代码。它对您的代码提出了通常不存在的要求 - 从而引入了错误!

    那么问题来了:当等待进程改变状态时,事件循环有什么用?在内部,流程通知需要等待本地事件或回调,并且这些都从事件循环中得到处理。即使没有使用任何事件,事件循环也会执行操作系统所需的可中断睡眠,以便将回调传递给应用程序。

    【讨论】:

      【解决方案2】:

      QProcess 的 Qt 文档指出:-

      QProcess 提供了一组函数,允许在没有事件循环的情况下使用它,方法是暂停调用线程直到发出某些信号:

      waitForStarted() 阻塞,直到进程开始。

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

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

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

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

      【讨论】:

      • 谢谢 - 这些特定信号如何在没有事件循环的情况下到达?
      • 你没有使用信号,只是使用函数。等效信号是here 如果将槽连接到信号,则需要一个事件循环
      • @PhilBot 只是一些附加信息:使用直接连接时不需要事件循环。这些行为就像直接的函数调用。
      • 这并不能真正回答问题,引用文档只是在搅浑水。在内部,这些函数旋转一个内部事件循环(或等效的)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 2018-02-20
      • 2012-01-10
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多