Qt同步处理业务并禁用按钮

1.界面+代码

cpp 复制代码
//按钮1
void Dialog::on_pushButton1_clicked()
{
    qDebug("pushButton1 clicked start");
    enableBtns(false);//禁用按钮
    qDebug("pushButton1 do sth start");
    QThread::sleep(5);//休眠,作为同步处理业务
    qDebug("pushButton1 do sth end");
    enableBtns(true);//启用按钮
    qDebug("pushButton1 clicked end");
}
//按钮2
void Dialog::on_pushButton2_clicked()
{
    qDebug("pushButton2 clicked start");
    enableBtns(false);
    //singleShot 延后处理业务。时间0ms不行
    QTimer::singleShot(1,this,[this](){
        qDebug("pushButton2 do sth start");
        QThread::sleep(5);
        qDebug("pushButton2 do sth end");
        enableBtns(true);
    });
    qDebug("pushButton2 clicked end");
}
//按钮3
void Dialog::on_pushButton3_clicked()
{
    qDebug("pushButton3 clicked start");
    enableBtns(false);
    //singleShot 延后处理业务。时间0ms不行
    QTimer::singleShot(1,this,[this](){
        qDebug("pushButton3 do sth start");
        QThread::sleep(5);
        qDebug("pushButton3 do sth end");
        //singleShot 延后启用按钮。时间 0或1不行,建议为5或10以上
        QTimer::singleShot(5,this,[this](){
            enableBtns(true);
        });
    });
    qDebug("pushButton3 clicked end");
}
//按钮其他
void Dialog::on_pushButtonOther_clicked()
{
    qDebug("pushButtonOther clicked");
}
//按钮禁用状态设置
void Dialog::enableBtns(bool enable)
{
    qDebug(enable?"enableBtns":"disableBtns");
    ui->pushButton1->setEnabled(enable);
    ui->pushButton2->setEnabled(enable);
    ui->pushButton3->setEnabled(enable);
    ui->pushButtonOther->setEnabled(enable);
}

2.测试

2.1点击 "按钮1",然后立即点击"按钮其他"。按钮没变成禁用状态,"按钮其他"触发。

bash 复制代码
pushButton1 clicked start
disableBtns
pushButton1 do sth start
pushButton1 do sth end
enableBtns
pushButton1 clicked end
pushButtonOther clicked
pushButtonOther clicked

2.2点击 "按钮2",按钮变成禁用状态,然后点击"按钮其他","按钮其他"仍触发。

bash 复制代码
pushButton2 clicked start
disableBtns
pushButton2 clicked end
pushButton2 do sth start
pushButton2 do sth end
enableBtns
pushButtonOther clicked
pushButtonOther clicked

2.2点击 "按钮3",按钮变成禁用状态,然后点击"按钮其他","按钮其他"未触发。

bash 复制代码
pushButton3 clicked start
disableBtns
pushButton3 clicked end
pushButton3 do sth start
pushButton3 do sth end
enableBtns

3.原因分析

Qt的界面刷新、按钮或QTimer::singleShot的业务处理都是放在主线程处理的。

主线程处理按钮业务时,不会处理其他业务,界面也不会刷新。此时如果有其他事件,会将其他事件放在义务处理完。

业务处理前禁用按钮,业务处理中就不会刷新界面样式;如果业务中点击过按钮,当业务处理完后有立即启用按钮,Qt框架会处理点击事件,判断按钮已经可用了,就会再次调用点击业务。

QTimer::singleShot 可以将业务延后处理,使界面样式刷新,业务处理,点击事件判断 按预定顺序处理。

相关推荐
小短腿的代码世界21 小时前
Qt Bluetooth源码深度解析:从HCI协议到跨平台API的完整架构
开发语言·qt·架构
小短腿的代码世界1 天前
Qt WebEngine多进程架构与IPC通信:从Chromium多进程到Qt信号槽融合
qt·架构·系统架构
尘中远1 天前
【Qwt 7.0 系列】快速入门与核心新特性概览 —— 更现代的 Qt 数据可视化库
qt·数据可视化·绘图·qwt·科学绘图
初阳7851 天前
【Qt】系统相关(3)——多线程
qt
初阳7851 天前
【Qt】系统相关(2)——文件
开发语言·qt
尘中远2 天前
【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内
qt·数据可视化·qcustomplot·qwt·工业软件·科学绘图
sycmancia2 天前
Qt——多线程间的互斥
开发语言·qt
尘中远2 天前
【Qwt 7.0 系列】常用图表类型实战 —— 柱状图、散点图、箱线图与直方图
qt·qwt·工业软件·科学绘图
尘中远2 天前
【Qwt 7.0 系列】交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取
qt·数据可视化·绘图·qcustomplot·qwt·科学绘图
sycmancia2 天前
Qt——进程与线程的概念
qt