【问题标题】:How to properly using infinite loop in Qt GUI?如何在 Qt GUI 中正确使用无限循环?
【发布时间】:2021-07-26 22:33:18
【问题描述】:

我是 Qt GUI 框架的新手并正在学习。

我有一个连接到 Raspberry Pi 的超声波传感器,用于测量水位。如果我使用 C 进行编码,我会使用 while(1) 循环来不断读取传感器输入。但是当我将while(1) 放入MainWindow.cpp 时,窗口无法显示。但是,使用qDebug() 我仍然可以打印出传感器值,这意味着我的while(1) 仍在运行但不会出现主窗口。我在this answer发现是因为while(1)

MainWindow ctor 永远不会返回,因此永远不会调用 w.show() 并且永远不会执行 a.exec()(主消息循环)。

为了解决这个问题,我使用QTimer 而不是循环:将timeout() SIGNAL 连接到一个 SLOT,这是一个一次性读取传感器值的函数:

waterLevelTimer = new QTimer(this);
connect(waterLevelTimer, SIGNAL(timeout()), this, SLOT(getWaterLevel()));
waterLevelTimer->start(100); // "loop" once every 100 millisecond

通过这种方法,我可以读取传感器值,最快的间隔是1毫秒,GUI仍然显示正常。

但是我应该使用QTimer 来模拟while(1) 循环吗?有没有更好的方法让无限循环读取 GPIO,同时仍然能够使用 GUI 进行其他工作?

【问题讨论】:

  • 您应该永远在事件驱动程序(基本上所有的 GUI 程序都是)中有无限循环。而构造函数实际上应该只初始化一个对象,而不是执行工作。
  • 你的问题的解决方案一个计时器,而不是一个无限循环。作为一种可能的辅助解决方案,您也许可以使用工作线程,但这可能会增加 GUI 和线程之间的同步和通信的其他复杂性。
  • 感谢 cmets!我应该把我的工作执行代码放在哪里?我遵循了几个 Qt 初学者示例,它们都在 MainWindow.cpp 中编写代码。
  • 如果您需要定期做某事,计时器 (QTimer) 是完美的选择,这就是它的用途。它比调用sleep 或类似名称的无限循环要好。
  • QTimer 可以处理一小时的长间隔吗?

标签: c++ qt raspberry-pi


【解决方案1】:

Qt 的 GUI 运行所在的主线程永远不应该被诸如无限 while 循环之类的长期操作阻塞,否则你会阻塞事件系统,任何事情都将不再起作用。

相反,您通常会创建一个并行工作线程(请参阅 QThread),您可以在该线程的 run 函数中执行循环。也许也可以按照您的建议使用此类计时器,如果执行的代码比计时器持续时间快,则该计时器有效。

QThread *thread = QThread::create([]{
    while(1)
        checkSomething();
});
thread->start();

【讨论】:

  • QThread 对我来说似乎很完美。但是你的最后一句话,如果工作时间超过计时器的间隔会发生什么?
  • 如果定时器触发的速度比执行代码的速度快,就会导致拥塞
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多