Я пытаюсь понять, почему не нужно выполнять вызов a.exec () в следующем коде Qt 4.8, прежде чем мои вызовы QProcess waitForFinished () и waitForStarted () могут работать. Я понимаю, что a.exec () запускает цикл обработки событий, и, на мой взгляд, слоты waitFor * должны получить сигнал (т. Е. ‘Start ()’ или ‘finish ()’) перед тем, как продолжить выполнение. Как это может произойти, если цикл обработки событий не был запущен?
Документация для 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();
}
Документация Qt для QProcess состояния: —
QProcess предоставляет набор функций, которые позволяют использовать его без цикла событий, приостанавливая вызывающий поток до тех пор, пока не будут отправлены определенные сигналы:
waitForStarted () блокирует, пока процесс не запустится.
waitForReadyRead () блокирует, пока новые данные не будут доступны для чтения на текущем канале чтения.
waitForBytesWritten () блокирует до тех пор, пока одна полезная нагрузка данных не будет записана в процесс.
waitForFinished () блокирует, пока процесс не завершится.
Вызов этих функций из основного потока (потока, который вызывает QApplication :: exec ()) может привести к зависанию вашего пользовательского интерфейса.
Соединения с прямым сигнальным интервалом — это просто косвенные вызовы функций, они не имеют ничего общего с циклами событий.
Что за waitForXxxx
методы делают, однако, это вращать локальный цикл событий, пока не сработает сигнал. Сигнал запускается из некоторого кода, который получает уведомление от ОС об изменении состояния процесса. Функционально этот код выполняется «с помощью» цикла обработки событий.
Помните, что в Qt вы можете создавать временные циклы событий по прихоти — это плохая практика, и вы никогда не должны писать код, который использует waitFor
методы. Это ставит требования к вашему коду, которые обычно не присутствуют — и, следовательно, вносит ошибки!
Тогда возникает вопрос: какова польза от цикла обработки событий, когда процессы ожидают изменения состояния? Внутренне, уведомления процесса требуют ожидания собственных событий или обратных вызовов, и все они обрабатываются из цикла событий. Даже если никакие события не используются, цикл обработки событий выполняет прерывистый спящий режим, который необходим ОС для доставки обратных вызовов приложению.