2017-07-12 52 views
0

我想创建一个用于控制和监视QT工业机器的GUI。 GUI应该每300ms更新一次机器的测量结果。而且我应该能够同时控制机器。我在做什么(错误)是我正在尝试使用每隔300ms触发一次的定时器更新GUI中的测量值。但是,如果在定时器插槽执行的同时单击我的控制按钮,GUI不响应。我也尝试过使用信号和插槽技术。同样的结果。我无法在互联网上找到解决方案。如果有人能帮忙,我会很高兴。提前致谢。图形用户界面更新和控制同时在qt

+1

你能分享你的代码吗?您是否在代码中使用了Sleep命令? – aghilpro

+0

你能分享你的代码吗?在大多数情况下,计时器是正确的选择。如果点击未执行,那么可能是代码中的一些问题,也许是一些阻塞功能,您可能会重新排列信号/插槽或线程。 – Damien

+0

感谢您的回复。那么你是否说,即使我在触发计时器时点击按钮,它也不会造成任何问题?我会尽量明天发布代码..再次感谢 – user5160714

回答

0

我发现问题是什么。这不是我认为的。我正在请求我每隔30ms与之通信的机器状态。我增加到3000毫秒,现在它工作正常。即使在另一个插槽正在执行时单击,该按钮也不会造成任何问题。问这是一个愚蠢的事情。感谢大家的帮助。所有的答案都非常丰富。再次感谢。

1

这样做有三种主要方法,每种方法都有其优点和缺点。

简单,非可扩展解决方案


最简单的方法是手动调用QApplication::processEvents()你的“忙”的代码中。例如,要手动更新GUI每个循环,你可以这样做:

for (int i = 0; i < 5000; ++i) { 
    label->setText(tr("At Index %1...").arg(i)); 
    QApplication::processEvents(); 
} 

优点

  1. 很容易
  2. 没有并发问题

缺点

  1. 非常有限的功能
  2. 污染代码

线程

如果你想要一个简单的解决方案,但可扩展的一个,继承的QThread然后在运行非GUI任务单独的线程是一个很好的方法:

class MyThread: QThread 
{ 
    Q_OBJECT 

    void run() 
    { 
     for (size_t i = 0; i < 50000; ++i) { 
      std::cout << i << std::endl; 
     } 
    } 
}; 

auto *thread = new MyThread; 
thread->start(); 

当这个长时间的任务发生时,GUI将会更新,而Qt将负责垃圾收集。


优点

  1. 相当简单
  2. 鲁棒的,可扩展和信号/槽允许数据交换

缺点

  1. 不能更新从主线程以外的任何线程的GUI。
  2. 信号/插槽必须使用QueuedConnection。

事件循环

最后一种方法是Qt的原生解决方案:一个QEventLoop。

QTimer timer; 
QEventLoop loop; 

timer.setSingleShot(true); 
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); 

timer.start(5000); 
loop.exec(); 

这实际上不那么直观,但是在大多数情况下通过避免繁忙的等待而好得多。


优点

  1. 最小CPU使用率

缺点

  1. 不太直观。

您可以阅读更多here。我最初拥有一个拥有相同信息的现代资源,所以如果你在Qt5文档中找到类似的链接,请编辑这篇文章。

相关问题