我有一个后台线程,线程调用一些更新UI的方法(为了显示进度条并在文本区域显示其他信息).
如果我修改了一些UI窗口小部件值,则会引发"无法将事件发送到由不同线程拥有的对象"断言错误.
看看论坛,我读到我可以使用QMetaObject :: invokeMethod方法,但是如果我传递Qt :: DirectConnection标志,它实际上会引发上面显示的相同错误,它就可以正常工作.
如果我使用Qt :: QueuedConnection或Qt :: AutoConnection,则invokeMethod返回false.
我的代码看起来类似于:
.H:
class A : public QMainWindow
{
Q_OBJECT
QProgressBar* pb;
public slots:
bool m(bool, int);
};
class B
{
A* a;
public:
void handleEvent();
};
.cpp:
bool A::m(bool x, int y)
{
pb->setValue(y);
return x;
}
void B::handleEvent()
{
//a->m(true, 12); //raises an assertion error
bool r;
//bool ret = QMetaObject::invokeMethod(a, "m", Qt::DirectConnection, Q_RETURN_ARG(bool, r), Q_ARG(bool, true), Q_ARG(int, 12)); //raises the same assertion error error
bool ret = QMetaObject::invokeMethod(a, "m", Qt::AutoConnection, Q_RETURN_ARG(bool, r), Q_ARG(bool, true), Q_ARG(int, 12)); //is ignored and ret contains false.
}
Run Code Online (Sandbox Code Playgroud)
你知道发生了什么事或我做错了什么吗?或者,有人可以建议我另一种处理我的新手问题的方法吗?
提前致谢,
埃内斯托
Jas*_*n B 10
我没有用过invokeMethod()自己,但为了做到这一点,我通常只使用信号和插槽.例如,您可以创建一个信号作为class B连接到插槽的成员,以class A更新进度:
class B : public QObject
{
Q_OBJECT
A* a;
signals:
void update_signal(bool, int);
public:
void handleEvent();
};
B::B()
{
//assuming a already points to the correct place...
connect(this, SIGNAL(update_signal(bool,int),
a, SLOT(m(bool,int)), Qt::QueuedConnection);
}
void B::handleEvent()
{
emit update_signal(true, 12);
}
Run Code Online (Sandbox Code Playgroud)
A::m()将不得不在这种情况下返回void但由于使用排队连接时,你不能得到一个返回值反正这不是一个问题,因为调用是异步的(emit update_signal(true,12)可能会返回被称为插槽功能之前,根本不可能有返回值准备).
实际上,你只要能在任何地方,你有一个指针执行此连接类型的对象A和类型的对象B.这使得信号和槽非常灵活,因为你可以完全脱钩A从B,但仍然允许他们通过信号和槽沟通.例如:
class B : public QObject
{
Q_OBJECT
signals:
void update_signal(bool, int);
public:
void handleEvent();
};
void B::handleEvent()
{
emit update_signal(true, 12);
}
class A : public QMainWindow
{
Q_OBJECT
QProgressBar* pb;
public slots:
void m(bool, int);
};
void A::m(bool x, int y)
{
pb->setValue(y);
}
int main()
{
A* a = new A();
B* b = new B();
QObject::connect(b, SIGNAL(update_signal(bool, int)),
a, SLOT(m(bool, int)), Qt::QueuedConnection);
//...
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,b不必存储指针或知道任何有关a它们可以通过精心定义的精简通道进行通信的信息.
| 归档时间: |
|
| 查看次数: |
9089 次 |
| 最近记录: |