QProcess 冻结图形用户界面
Posted
技术标签:
【中文标题】QProcess 冻结图形用户界面【英文标题】:QProcess freeze GUI 【发布时间】:2017-09-14 06:53:10 【问题描述】:这是 QNX 目标的代码 sn-p。当我在系统上运行它并且当我执行下一个点火循环/重新启动我的系统时,它工作正常,GUI 冻结/挂起。
如果可能,请告诉我这段代码有什么问题。
我尝试使用readAllStandardOutput
并完成并启动信号也有同样的问题。它没有帮助。
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<__PRETTY_FUNCTION__<<!usbProcess;
usbProcess = new QProcess();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<usbProcess->pid();
usbProcess->start("usb");
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<usbProcess->pid();;
usbProcess->waitForReadyRead();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__;
usbProcess->waitForFinished();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__;
text = usbProcess->readAll();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<!usbProcess<<text;
usbProcess->closeReadChannel(QProcess::ProcessChannel::StandardOutput);
usbProcess->closeReadChannel(QProcess::ProcessChannel::StandardError);
usbProcess->closeWriteChannel();
usbProcess->close();
delete usbProcess;
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<!usbProcess;
【问题讨论】:
我不确定我是否完全理解了这个问题,但是...如果您检查 QProcess documentation,waitForReadyRead
和 waitForFinished
都会出现警告“从主函数调用此函数 ( GUI)线程可能会导致您的用户界面冻结”。改用信号/槽。
我试过了。请看...
usbProcess = new QProcess(this); QObject::connect(usbProcess, &QProcess::readyReadStandardOutput, [this]() text = usbProcess->readAllStandardOutput(); text.replace(",", ",\n"); text.replace(":", "\n:"); qDebug()start("usb");
要么使用专用线程,要么使用带有信号或槽的非阻塞 API。你的代码也不做。
我试试 std:system("usb")。它有效,但不适用于 QProcess。我无法弄清楚我的代码有什么问题。
【参考方案1】:
您正在 GUI 线程上运行阻塞进程。这就是您的 GUI 挂起的原因。
我通常创建两种方法。一种是阻塞,一种是非阻塞。 阻塞 方法由非阻塞 方法调用using the Qt Concurrent framework。完成后会发出信号并返回任何数据。
// Runs the usb process without blocking
void MyClass::runUsbProcess()
QtConcurrent::run(this, &MyClass::runUsbProcessBlocking);
// Runs the usb process while blocking
void MyClass::runUsbProcessBlocking()
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<__PRETTY_FUNCTION__<<!usbProcess;
usbProcess = new QProcess();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<usbProcess->pid();
usbProcess->start("usb");
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<usbProcess->pid();;
usbProcess->waitForReadyRead();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__;
usbProcess->waitForFinished();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__;
text = usbProcess->readAll();
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<!usbProcess<<text;
usbProcess->closeReadChannel(QProcess::ProcessChannel::StandardOutput);
usbProcess->closeReadChannel(QProcess::ProcessChannel::StandardError);
usbProcess->closeWriteChannel();
usbProcess->close();
delete usbProcess;
qCDebug(SYSTEM)<<"--RDQA--"<<__LINE__<<!usbProcess;
emit usbProcessFinished(text);
【讨论】:
以上是关于QProcess 冻结图形用户界面的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 QProcess 避免 waitForStarted 以阻止 GUI 冻结?
《Java并发编程实战》第九章 图形用户界面应用程序界面 读书笔记