C++ 运行方法时更新QtGUI

C++ 运行方法时更新QtGUI,c++,multithreading,qt,user-interface,worker,C++,Multithreading,Qt,User Interface,Worker,我知道如何使用qt线程,但是可以使用线程来更新gui,而无需子类化qthread或qobject? 例如: class Foo { public void heavyWork(); } Foo::heavyWork() { doSomething(); } class FooObserver { friend class Foo; protected: virtual void update(Foo *) = 0; }; class Foo { int m_da

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

class Foo {
    public void heavyWork();
}

Foo::heavyWork() {
    doSomething();
}
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);
}
使用线程只是一种选择

void ThreadSubClass::run() {
    myFoo.heavyWork();
    updateGui(); //i know, heavyWork will run before updateGui()
}
我不想子类qobject或qthread来实现我的foo类,因为这个类可以或应该独立于gui库使用,甚至在控制台中使用,我正在使用Qt,但我计划尝试其他方法,所以我假设foo的方法在工作线程中执行,您希望提供一种机制,将一些数据从Foo传递到GUI线程

这样做的典型方式是提供一种在Foo线程中执行回调的机制——然后回调的实现特定于正在使用的特定GUI工具包

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

class Foo {
    public void heavyWork();
}

Foo::heavyWork() {
    doSomething();
}
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);
}
这是完全线程安全的,因为信号的线程是在信号发出时确定的。QtFooObserver对象可以驻留在任何线程中,包括与Foo的线程不同的线程。因此,如果Foo位于线程A中,并且连接到QtFooObserver的插槽位于线程B中的对象上,那么Qt将自动使用线程安全的跨线程信号传递方法


有关更多信息,请参阅和。

注意,Qt不是gui库,而是一个应用程序开发框架。这是一个相当重要的区别。也就是说,即使使用gui和widgets模块,Qt应用程序也可以无头运行——不使用任何屏幕,甚至根本不需要任何人机交互。Qt的核心和网络模块适用于许多非gui、服务器式的开发。见鬼,许多常见的Unix实用程序在Qt中重新实现时看起来微不足道,尽管它们的C实现非常庞大。