运行方法时更新 qt gui

Posted

技术标签:

【中文标题】运行方法时更新 qt gui【英文标题】:updating qt gui when running a method 【发布时间】:2014-07-02 23:34:47 【问题描述】:

我知道如何使用 qt 线程,但是可以使用线程来更新 gui 而无需子类化 qthread 或 qobject? 例如:

class Foo 
    public void heavyWork();


Foo::heavyWork() 
    doSomething();

并使用线程(只是一个选项)

void ThreadSubClass::run() 
    myFoo.heavyWork();
    updateGui(); //i know, heavyWork will run before updateGui()

我不想继承 qobject 或 qthread 来实现我的“foo”类,因为这个类可以(或应该)独立于 gui 库(甚至在控制台中)使用,我正在使用 Qt,但我打算尝试其他方法

【问题讨论】:

请注意,Qt 不是一个 gui 库,它是一个应用程序开发框架。这是一个相当重要的区别。也就是说,Qt 应用程序,即使使用 gui 和小部件模块,也可以无头运行——无需使用任何屏幕,甚至根本无需任何人工交互。 Qt 的核心和网络模块适用于很多非gui、服务器式的开发。哎呀,许多常见的 Unix 实用程序在 Qt 中重新实现时看起来非常微不足道,即使它们的 C 实现是可怕的。 【参考方案1】:

所以,我假设Foo 的方法在工作线程中执行,并且您希望提供一种机制将一些数据从Foo 传递到GUI 线程。

执行此操作的典型方法是提供一种在Foo 的线程中执行回调的机制 - 然后回调的实现特定于正在使用的特定 GUI 工具包。

回调可以是一个简单的函数指针,也可以是一个接口(观察者模式)。例如:

class FooObserver 
  friend class Foo;
protected:
  virtual void update(Foo *) = 0;
;

class Foo 
  int m_data;
  std::list<std::shared_ptr<FooObserver>> m_observers;
public:
  void heavyWork();
  int data() const;
  void addObserver(std::shared_ptr<FooObserver> observer);


void Foo::addObserver(std::shared_ptr<FooObserver> observer)

  m_observers.push_back(observer);


void Foo::heavyWork()

  ...
  for (auto observer: m_observers) observer->update(this);

那么,对于 Qt,您可以:

class QtFooObserver : public FooObserver 
  Q_OBJECT
  void update(Foo * foo) override  emit newData(foo->data()); 
public:
  QtFooObserver() 
  Q_SIGNAL void newData(int);
;

这是完全线程安全的,因为信号线程的确定发生在信号发射时。 QtFooObserver 对象可以驻留在任何线程中,包括与Foo 的线程不同的线程。因此,如果Foo 在线程A 中,并且连接到QtFooObserver 的槽在线程B 中的对象上,Qt 将自动使用线程安全的跨线程信号传递方法。

如需更多灵感,请参阅this answer 和Leap Motion C++ SDK。

【讨论】:

以上是关于运行方法时更新 qt gui的主要内容,如果未能解决你的问题,请参考以下文章

如何并行运行 Qt GUI 和 Linux 消息队列接收线程?

非GUI-Qt程序运行后显示Console(简单好用)

Qt 4.8 杀死并重新启动 GUI

Qt 保持GUI响应的几种方法

在已经运行的 c++ 控制台应用程序上实现 Qt Gui

即使我在单独的线程中运行,QT GUI 也会冻结