使用QtConcurrent多线程刷新主界面的方法

前言:做项目时,遇到这样一个问题,在QtConcurrent线程中对QStandardItem*对象使用setText()函数,相应的ListView控件没有刷新,需要在界面点击一下控件,才能刷新。刚接手这个问题时给我的第一感觉是控件失焦。

QtConcurrent

因为第一感觉是失焦,所以在程序线程函数中对控件调用了setFocus(),结果程序直接报异常,问题大致是不能在其它线程对控件进行操作,也就是说创建控件的线程是主线程,而QtConcurrent新开了一个线程。因为对QtConcurrent第一次接触,索性在网上查了一下QtConcurrent的特性。

https://blog.csdn.net/Amnes1a/article/details/66470751
https://blog.csdn.net/fghler/article/details/109444779

主要参考了以上几篇文章,说的是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);
bool demo::event(QEvent * e)
{
	if (e->type() == QEvent::User) {
		//更新控件
		ui.pushButton->setText(QString::number(m_num));
	}
	return QWidget::event(e);
}
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Qt中,可以通过信号与槽机制实现多线刷新界面。具体步骤如下: 1. 在线程中创建一个QObject对象,并将其与需要更新的UI元素绑定。 2. 在另一个线程中创建一个QThread对象,并将QObject对象移动到该线程中。 3. 在QThread类中定义一个更新UI的槽函数,并将其与QObject对象的信号连接起来。 4. 在需要更新UI的地方,调用QObject对象的信号即可触发QThread对象中的槽函数,从而更新UI。 下面是一个简单的示例代码: ```cpp //在线程中创建QObject对象,并将其与需要更新的UI元素绑定 QObject* pObject = new QObject(this); connect(pObject, SIGNAL(updateUI()), ui->label, SLOT(update())); //在另一个线程中创建一个QThread对象,并将QObject对象移动到该线程中 QThread* pThread = new QThread(); pObject->moveToThread(pThread); //在QThread类中定义一个更新UI的槽函数,并将其与QObject对象的信号连接起来 class Worker : public QObject { Q_OBJECT public slots: void onUpdateUI() { emit updateUI(); } }; Worker* pWorker = new Worker(); connect(pObject, SIGNAL(updateUI()), pWorker, SLOT(onUpdateUI())); //启动线程 pThread->start(); //在需要更新UI的地方,调用QObject对象的信号即可触发QThread对象中的槽函数,从而更新UI emit pObject->updateUI(); ``` 需要注意的是,更新UI的操作必须在线程中执行,因此在槽函数中需要使用Qt的线程安全函数来更新UI,例如QMetaObject::invokeMethod()函数。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值