我知道如何使用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,但是我打算尝试其他任何事情
答案 0 :(得分:0)
因此,我假设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。