使⽤QtConcurrent多线程刷新主界⾯的⽅法
前⾔:做项⽬时,遇到这样⼀个问题,在QtConcurrent线程中对QStandardItem*对象使⽤setText()函数,相应的ListView控件没有刷新,需要在界⾯点击⼀下控件,才能刷新。刚接⼿这个问题时给我的第⼀感觉是控件失焦。
QtConcurrent
因为第⼀感觉是失焦,所以在程序线程函数中对控件调⽤了setFocus(),结果程序直接报异常,问题⼤致是不能在其它线程对控件进⾏操作,也就是说创建控件的线程是主线程,⽽QtConcurrent新开了⼀个线程。因为对QtConcurrent第⼀次接触,索性在⽹上查了⼀下QtConcurrent的特性。
主要参考了以上⼏篇⽂章,说的是QtConcurrent编写多线程程序的⾼级API,使⽤这个API可以使我们在不使⽤低级的线程元素…感觉就很⾼⼤上的样⼦。在使⽤上,相⽐于使⽤QThread的⽅法开线程,需要写⼀个类继承QThread的⽅式,QtConcurrent的⽅法简直是简单⾄极,甚⾄只要⼀⾏代码就⾏:QFuture future = QtConcurrent::run(func); 知道此事的我,对于之前苦逼的写着QThread⼦类的事情感到⼼⼒憔悴。不过,QtConcurrent也存在不⾜,据⼤佬说⽆法使⽤signal/slot的槽函数。因此,QtConcurrent的应⽤场景应该是不需要额外交互,计算耗时,只需要关注计算结果的场合。当然,QFutureWatcher也提供了多种signal/slot的槽函数,但对于把QtConcurrent 写成轮询线程,需要处理多
种数据的⽅式可能不适⽤。因此需要另外⼀种⽅式与主线程进⾏交互。好了,不说废话了。上代码。
postEvent
在QtConcurrent线程函数中调⽤postEvent,注意QEvent* e⼀定要⽤new,因为QT会⾃动delete这个指针,所以不⽤new的话,会报异常。
QEvent *e =new QEvent(QEvent::User);
QCoreApplication::postEvent(this, e);
event(QEvent * e)
在主线程中添加这个函数,应该是重写。
protected:
bool event(QEvent * e);qt listview
bool demo::event(QEvent * e)
{
if(e->type()== QEvent::User){
//更新控件
ui.pushButton->setText(QString::number(m_num));
}
return QWidget::event(e);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论