Qt 控制台应用程序:while 循环阻止事件循环
Posted
技术标签:
【中文标题】Qt 控制台应用程序:while 循环阻止事件循环【英文标题】:Qt Console Application: while loop blocks event loop 【发布时间】:2011-08-05 13:07:21 【问题描述】:我正在制作一个控制台应用程序,我在其中获取用户输入 使用 std::getline() (在 while 循环中)。我也在使用 QextSerialPort(继承 QIODevice)。因此 我需要一个事件循环,所以我使用 QCoreApplication 并调用 a.exec()。
问题是 getline() 阻塞了事件循环,当它被阻塞时,我无法从串口接收任何东西。我尝试使用
QCoreApplication::processEvents() 在 while(1)getline() 循环中,但发现这不是一个好的解决方案。然后,我尝试调用
QCoreApplication::processEvents() 在 QThread 但它没有 工作。
这是我使用的代码:
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
Base *base = new Base();
Commander *commander = new Commander(base);
QObject::connect(commander, SIGNAL(end()), &a, SLOT(quit()));
QTimer::singleShot(0, commander, SLOT(run()));
return a.exec();
void Commander::askToConnect()
if(base->connect() == false)
cout << "Failed to open port." << endl;
void Commander::run
string inputline;
askToConnect();
while(1)
QCoreApplication::processEvents(); // ???
cout << endl << "> ";
getline(cin, inputline);
// ...
如何在不阻塞事件循环的情况下使用 getline()(或类似方法)?
【问题讨论】:
【参考方案1】:是的,我对从主线程调用的 ProcessEvent() 方法有类似的体验。问题是它只是放在当前调用堆栈的顶部,并且可能会产生其他令人讨厌的副作用,例如无尽的调用深度或重入问题。
我只想在您的应用程序中添加几个线程来创建一个干净的解决方案。由于 getLine() 属于(控制台)用户界面,我会将它保留在主线程中并将网络代码移动到一个额外的线程中,但其他解决方案也是可能的(为各种交互生成线程并从主线程)。
【讨论】:
将通信代码移动到一个单独的线程是一个好主意。如果您让它仅通过信号/插槽连接与主线程通信,您将免费获得线程安全。 我忘了说:我使用来自 QextSerialPort 的 readyRead 信号异步接收数据。当我从串口接收数据时,我使用 qDebug() 在终端上打印它。但是,一旦事件循环被阻塞,它只会在我输入一些内容并按 enter (getline()) 后打印。那只是因为我在 while 循环中调用了 QCoreApplication::processEvents()。以上是关于Qt 控制台应用程序:while 循环阻止事件循环的主要内容,如果未能解决你的问题,请参考以下文章