[英]How to implement QProgressDialog?
我嘗試使用QProgressDialog
向用戶提供有關長任務進度的一些信息,同時允許他取消此任務。
基本上,我有一個帶有按鈕Compute
的QDialog
。 通過單擊它,在我的QDialog
的父級成員上調用了一個耗時的方法。 此方法執行回調以告知調用方工作進度。
問題在於進度對話框在顯示之前需要花費一些時間,並且沒有立即單擊其“ Cancel
按鈕Cancel
其考慮在內。
顯然,我的代碼中有一個小故障,但是我不習慣Qt,我嘗試了很多事情。 我可能需要一個單獨的線程。
我的代碼摘錄:
void MyDialog::callbackFunction(int value, void * objPtr) {
((QProgressDialog *)(objPtr))->setValue(value);
QCoreApplication::processEvents();
}
void MyDialog::on_mComputeBtn_clicked()
{
Compute();
}
void MyDialog::Compute()
{
QProgressDialog progressDialog("Optimization in progress...", "Cancel", 0, 100, this);
progressDialog.setMinimumDuration(500); // 500 ms
progressDialog.setWindowModality(Qt::WindowModal);
progressDialog.setValue(0);
connect(&progressDialog, SIGNAL(canceled()), this, SLOT(Cancel()));
QCoreApplication::processEvents();
parentMember->LongComputation(callbackFunction);
// probably useless
progressDialog.reset();
progressDialog.hide();
QCoreApplication::processEvents();
}
由於您將最小持續時間設置為500ms,因此不會立即顯示該對話框。 將其設置為0可使對話框在進度更改時立即顯示,或手動調用其show函數。
為了使“取消”按鈕起作用,請將您的長時間計算移至另一個線程(例如,使用QThread或std :: async),並讓您的主事件循環繼續執行。
實際上,您的代碼存在很多問題,但是這兩點應該為您指明正確的方向。 以我的經驗,每次手動調用processEvents都會產生很大的代碼異味。
您要做的是嘗試使用QProgressdialog的模式范例,而不是讓主事件泵觸發,還設置了0.5 s的超時時間,最短的持續時間將確保暫停。 也許無模式的變體更適合您的情況。
如果過程有離散的步驟,則無需單獨的線程即可
class MyTask : public QObject
{
Q_OBJECT
public:
explicit MyTask(QObject *parent = 0);
signals:
public slots:
void perform();
void cancel();
private:
int steps;
QProgressDialog *pd;
QTimer *t;
};
...
void MyDialog::on_mComputeBtn_clicked()
{
myTask = new MyTask;
}
...
MyTask::MyTask(QObject *parent) :
QObject(parent), steps(0)
{
pd = new QProgressDialog("Task in progress.", "Cancel", 0, 100000);
connect(pd, SIGNAL(canceled()), this, SLOT(cancel()));
t = new QTimer(this);
connect(t, SIGNAL(timeout()), this, SLOT(perform()));
t->start(0);
}
void MyTask::perform()
{
pd->setValue(steps);
//... perform one percent of the operation
steps++;
if (steps > pd->maximum())
t->stop();
}
void MyTask::cancel()
{
t->stop();
//... cleanup
}
這里存在QThread示例: Qt 5:在QThread工作期間通過信號更新QProgressBar
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.