QT易踩坑之在子线程中操作UI,造成应用程序卡死!
QtConcurrent::run([=]() {
int res = SDKGetMemberInfo(memberNum.toStdString().c_str());
if (res == 0)
{
MainHandler::GetInstance()->TipMessageBox(QString(tr("Examples of briquette elves")));
}
});
这里调用SDKGetMemberInfo()接口可能是个耗时操作,因此我们使用QtConcurrent启动一个线程来执行该函数,若返回值为0,则主界面弹出提示语"Examples of briquette elves"(如何弹出提示语就是另一个故事了,这里我们不过多关注,但重要的是!弹出提示语是一个UI操作!)。然后我们会发现,应用程序直接卡死!嘤嘤嘤~怎么肥四……
咳咳,从复杂度、安全性、性能等多方便考虑,QT限制更新、创建UI必须在主线程里完成。怎么解决这个问题呢?
一个好用的解决办法就是把对UI的操作再发送到主线程去,如下:文章来源:https://www.toymoban.com/news/detail-464552.html
QtConcurrent::run([=]() {
int res = SDKChangeConfChairman(meetNum.toStdString().c_str());
QMetaObject::invokeMethod(qApp, [this, res]
{
if (res == 0)
{
MainHandler::GetInstance()->TipMessageBox(QString(tr("Transfer host succeeded")));
}
});
});
这样应用程序就能丝滑地运行起来啦~
简单介绍一下原理:
QMetaObject的invokeMethod()方法用来调用一个对象的信号、槽、可调用的方法。此功能是线程安全的!第一个参数qAPP是被调用对象的指针,位于主线程;第二个参数是方法的名字,这里用一个简单的lambda表达式表示。这样弹出提示的语句(UI操作)就被从子线程发送到主线程了~文章来源地址https://www.toymoban.com/news/detail-464552.html
到了这里,关于QT踩坑之子线程不能操作UI,否则应用程序卡死的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!