qt事件循环与connect

本文探讨了Qt开发中界面操作卡顿的问题,分析了事件循环的阻塞机制,并提供了非阻塞界面延时响应的解决方案。通过合理利用QApplication::processEvents()和QEventLoop,可以有效避免UI线程的阻塞,确保应用程序的流畅运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结一下工作中遇到的问题:
界面操作卡滞问题与connect
转载,便于自己查阅

//qt开发过程中的常用功能
https://www.cnblogs.com/linuxAndMcu/p/10137264.html
//使用QApplication::processEvent()实现非阻塞界面的延时响应
https://blog.youkuaiyun.com/Chirive/article/details/95106300
//Qt 如何处理密集型耗时的事情(频繁调用QApplication::processEvents)
//写文件的进度问题(QProcess::event刷新)
https://blog.youkuaiyun.com/u012260238/article/details/60149435
//这里介绍了一个bug
https://www.cnblogs.com/senior-engineer/p/5598133.html

//qt事件循环阻塞机制分析
https://blog.youkuaiyun.com/u010810750/article/details/105912178

//QT中使用QEventLoop来实现事件循环
https://blog.youkuaiyun.com/qiufenpeng/article/details/81583768


自己写的测试程序
#include “mainwindow.h”
#include “ui_mainwindow.h”
#include
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
d = new Dialog(this);
d->show();
thread = new Mythread(0);
//验证ok
// connect(thread,SIGNAL(threadsignal1(int)),this,SLOT(test1(int)),Qt::BlockingQueuedConnection);
//当接收线程获取事件循环时再执行?
connect(thread,SIGNAL(threadsignal1(int)),this,SLOT(test1(int)),Qt::QueuedConnection);
connect(thread,SIGNAL(threadsignal2(int)),this,SLOT(test2(int)));
connect(this,SIGNAL(here()),this,SLOT(thisslot()));
}
void MainWindow::thisslot(){
qDebug()<<QString::fromLocal8Bit(“马上执行”);
}

MainWindow::~MainWindow()
{
delete(d);
delete ui;
}

void MainWindow::test1(int input)
{
ui->label->setText(QString::number(input));
// qApp->processEvents(QEventLoop::AllEvents, 100);//与后面的效果是一样的
// QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
//QApplication::processEvents(QEventLoop::AllEvents,100);
QElapsedTimer t;
t.start();
#if 0
// emit threadsignal1(3);
for(int num = 0; num<20000; num++)
{
QString e = “111”;
QFile file(“e.txt”);
file.open(QIODevice::WriteOnly | QIODevice::Text);
file.write(e.toUtf8());
file.close();
}
#endif
qDebug()<<t.elapsed();
}

void MainWindow::test2(int input)
{
qDebug()<<QString::fromLocal8Bit(“延迟才对”)<<input;
}

void MainWindow::on_pushButton_clicked()
{
thread->start();
emit here();
#if 1
// emit threadsignal1(3);
for(int num = 0; num<20000; num++)
{
QString e = “111”;
QFile file(“e.txt”);
file.open(QIODevice::WriteOnly | QIODevice::Text);
file.write(e.toUtf8());
file.close();
}
#endif
}

#include “mythread.h”
#include “QElapsedTimer”
#include “QDebug”
#include “QFile”
#include “QTimer”
Mythread::Mythread(QObject *parent) :
QThread(parent)
{

Mystring.clear();
}

void Mythread::run(){
//QElapsedTimer t;
// t.start();
emit threadsignal1(3);
#if 0
for(int num = 0; num<8000; num++)
{
QString e = “111”;
QFile file(“e.txt”);
file.open(QIODevice::WriteOnly | QIODevice::Text);
file.write(e.toUtf8());
file.close();
}
qDebug()<<t.elapsed();
#endif
emit threadsignal2(6);
return;
QElapsedTimer t;
t.start();
while(t.elapsed()<300);
//等待3s
return;
}

自己总结的一些经验
0)弄明白什么是事件循环
1)exec模态接手父事件循环(子对象阻塞一次父对象事件(eg:键盘事件))之后接手事件循环,但是while(1)会阻塞整个线程,可不是阻塞父事件的循环!这种阻塞呢,导致界面不刷新,事件循环阻塞界面。
2)解决ui线程的阻塞问题;
3)看看connect的第五个参数!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值