1.界面+代碼?
//按鈕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”,然后立即點擊“按鈕其他”。按鈕沒變成禁用狀態,“按鈕其他”觸發。
pushButton1 clicked start
disableBtns
pushButton1 do sth start
pushButton1 do sth end
enableBtns
pushButton1 clicked end
pushButtonOther clicked
pushButtonOther clicked
2.2點擊 “按鈕2”,按鈕變成禁用狀態,然后點擊“按鈕其他”,“按鈕其他”仍觸發。
pushButton2 clicked start
disableBtns
pushButton2 clicked end
pushButton2 do sth start
pushButton2 do sth end
enableBtns
pushButtonOther clicked
pushButtonOther clicked
2.2點擊 “按鈕3”,按鈕變成禁用狀態,然后點擊“按鈕其他”,“按鈕其他”未觸發。
pushButton3 clicked start
disableBtns
pushButton3 clicked end
pushButton3 do sth start
pushButton3 do sth end
enableBtns
3.原因分析
????????Qt的界面刷新、按鈕或QTimer::singleShot的業務處理都是放在主線程處理的。
????????主線程處理按鈕業務時,不會處理其他業務,界面也不會刷新。此時如果有其他事件,會將其他事件放在義務處理完。
????????業務處理前禁用按鈕,業務處理中就不會刷新界面樣式;如果業務中點擊過按鈕,當業務處理完后有立即啟用按鈕,Qt框架會處理點擊事件,判斷按鈕已經可用了,就會再次調用點擊業務。
????????QTimer::singleShot 可以將業務延后處理,使界面樣式刷新,業務處理,點擊事件判斷 按預定順序處理。