簡體   English   中英

如何實現QProgressDialog?

[英]How to implement QProgressDialog?

我嘗試使用QProgressDialog向用戶提供有關長任務進度的一些信息,同時允許他取消此任務。

基本上,我有一個帶有按鈕ComputeQDialog 通過單擊它,在我的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM