简体   繁体   English

在Qt中同时进行GUI更新和控制

[英]GUI update and control at the same time in qt

I am trying to create a GUI for controlling and monitoring an industrial machine in QT. 我正在尝试创建一个用于在QT中控制和监视工业机器的GUI。 The GUI should update every 300ms with the measurements from the machine. GUI应该每300毫秒更新一次机器的测量结果。 And I should be able to control the machine at the same time. 而且我应该能够同时控制机器。 What I was doing (wrong) is I was trying to update the measurements in GUI using a timer which triggers every 300ms. 我正在做的(错误的)是我试图使用每300毫秒触发一次的计时器来更新GUI中的测量。 But if I click my control buttons at the same time as the timer slot getting executed, the GUI is not responding. 但是,如果我在执行计时器插槽的同时单击我的控制按钮,则GUI没有响应。 I tried using signals and slot technique too. 我也尝试使用信号和插槽技术。 Same result. 结果相同。 I wasn't able to find a solution in internet. 我无法在互联网上找到解决方案。 I would be happy if someone could help. 如果有人可以帮助我,我会很高兴。 Thanks in advance. 提前致谢。

There are three main approaches to doing this, each which has their advantages and disadvantages. 共有三种主要方法,每种方法各有优缺点。

Easy, Non-Scalable Solution 简单,不可扩展的解决方案


The easiest way is to call QApplication::processEvents() inside your "busy" code manually. 最简单的方法是在“忙”代码中手动调用QApplication::processEvents() For example, to manually update the GUI each loop you could do this: 例如,要手动更新每个循环的GUI,可以执行以下操作:

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

Pros 优点

  1. Very easy 很容易
  2. No concurrency issues 没有并发问题

Cons 缺点

  1. Very limited functionality 功能非常有限
  2. Pollutes code 污染代码

Threads 线程数

If you want an easy solution, but scalable one, subclassing QThread and then running non-GUI tasks in a separate thread is a great approach: 如果您想要一个简单但可扩展的解决方案,可以将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();

While that long task occurs, the GUI will update, and Qt will take care of the garbage collection. 当执行此任务时,GUI将更新,而Qt将负责垃圾收集。


Pros 优点

  1. Fairly simple 相当简单
  2. Robust, scalable, and signals/slots allow data exchange 坚固,可扩展且信号/插槽允许数据交换

Cons 缺点

  1. You cannot update the GUI from any thread other than the main thread. 不能从主线程以外的任何线程更新GUI。
  2. Signals/slots must use QueuedConnection. 信号/插槽必须使用QueuedConnection。

Event Loops 事件循环

The last approach is Qt's native solution: a QEventLoop. 最后一种方法是Qt的本机解决方案:QEventLoop。

QTimer timer;
QEventLoop loop;

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

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

This is substantially less intuitive, but happens to be much better in most cases by avoiding busy waiting. 这实际上不那么直观,但是在大多数情况下,通过避免繁忙的等待,它会变得更好。


Pros 优点

  1. Minimal CPU usage 最小的CPU使用率

Cons 缺点

  1. Less intuitive. 不太直观。

You can read more here . 您可以在这里阅读更多内容。 I originally had a modern resource with the same information, so if you find a similar link on the Qt5 documentation, please edit this post. 我最初有一个具有相同信息的现代资源,因此,如果您在Qt5文档上找到类似的链接,请编辑此帖子。

I found out what the problem was. 我发现了问题所在。 It was not what I thought it was. 那不是我想的那样。 I was requesting for the status of the machine with which I was communicating every 30ms. 我要求每30毫秒与之通信的计算机的状态。 I increased it to 3000ms now it works fine. 我将其增加到3000ms,现在可以正常工作了。 The button will not cause any problem even if clicked when another slot is being executed. 即使在执行另一个插槽时单击该按钮也不会引起任何问题。 It was a foolish thing to ask. 问这是愚蠢的事。 Thanks for the help everyone. 感谢大家的帮助。 All the answers were very informative. 所有的答案都非常有用。 Thanks again. 再次感谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM