在 Qt Eventloop 启动之前,我的代码如何接收信号
How is my code Receiving Signals before the Qt Eventloop is Started
我试图理解为什么在我的 QProcess waitForFinished() 和 waitForStarted() 调用可以工作之前不需要在以下 Qt 4.8 代码中调用 a.exec() 。我知道 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();
}
QProcess 的 Qt 文档指出:-
QProcess provides a set of functions which allow it to be used without an event loop, by suspending the calling thread until certain signals are emitted:
waitForStarted() blocks until the process has started.
waitForReadyRead() blocks until new data is available for reading on the current read channel.
waitForBytesWritten() blocks until one payload of data has been written to the process.
waitForFinished() blocks until the process has finished.
Calling these functions from the main thread (the thread that calls QApplication::exec()) may cause your user interface to freeze.
直接信号槽连接只是间接函数调用,它们与事件循环没有任何关系。
不过,waitForXxxx
方法的作用是旋转一个本地事件循环,直到信号触发。该信号是从一些代码中触发的,这些代码被 OS 通知进程状态已更改。该代码在功能上执行,"by" 事件循环。
请记住,在 Qt 中,您可以随心所欲地创建临时事件循环 - 这是一种不好的做法,您永远不应该编写使用 waitFor
方法的代码。它对您的代码提出了通常不存在的要求 - 从而引入了错误!
那么问题来了:在等待进程改变状态时,事件循环有什么用?在内部,流程通知需要等待本机事件或回调,而这些都从事件循环中得到处理。即使不使用任何事件,事件循环也会执行 OS 向应用程序传递回调所需的可中断睡眠。
我试图理解为什么在我的 QProcess waitForFinished() 和 waitForStarted() 调用可以工作之前不需要在以下 Qt 4.8 代码中调用 a.exec() 。我知道 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();
}
QProcess 的 Qt 文档指出:-
QProcess provides a set of functions which allow it to be used without an event loop, by suspending the calling thread until certain signals are emitted:
waitForStarted() blocks until the process has started.
waitForReadyRead() blocks until new data is available for reading on the current read channel.
waitForBytesWritten() blocks until one payload of data has been written to the process.
waitForFinished() blocks until the process has finished.
Calling these functions from the main thread (the thread that calls QApplication::exec()) may cause your user interface to freeze.
直接信号槽连接只是间接函数调用,它们与事件循环没有任何关系。
不过,waitForXxxx
方法的作用是旋转一个本地事件循环,直到信号触发。该信号是从一些代码中触发的,这些代码被 OS 通知进程状态已更改。该代码在功能上执行,"by" 事件循环。
请记住,在 Qt 中,您可以随心所欲地创建临时事件循环 - 这是一种不好的做法,您永远不应该编写使用 waitFor
方法的代码。它对您的代码提出了通常不存在的要求 - 从而引入了错误!
那么问题来了:在等待进程改变状态时,事件循环有什么用?在内部,流程通知需要等待本机事件或回调,而这些都从事件循环中得到处理。即使不使用任何事件,事件循环也会执行 OS 向应用程序传递回调所需的可中断睡眠。