繁体   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