0

我试图在一个函数执行时显示一个繁忙的等待栏,我的问题是一旦函数启动它就停止移动。

MyProgressDialog *progBar= new MyProgressDialog();
    QProgressBar* bar = new QProgressBar(progBar);
    bar->setRange(0, 0);
    bar->setValue(0);

    progBar->setBar(bar);
    QString labeltext=QString("<qt> <center><big><b>%1</b></big></center> <br><b>%2</b><br> %3 <br><b>%4</b><br> %5</qt>")
                         .arg(progBar->labeltext)
                         .arg("File in :")
                         .arg(FileI)
                         .arg("File out :")
                         .arg(FileO);
    progBar->label->setText(labeltext);    
    progBar->setValue(10);
    progBar->show();
    progBar->setValue(20);
    Sleep(500);
    progBar->setValue(50);
    Sleep(500);
    MyFunction(FileI,FileO,mode,key);
    Sleep(500);
    progBar->setValue(80);
    Sleep(500);
    progBar->setValue(100);
    progBar->close();
    delete bar;
    delete progBar;

我用睡眠扭曲了我的函数并设置了值以让它移动但徒劳无功,当我删除它们时 MyProgressdialog 没有显示它的内容,我需要在单独的线程中午餐我的函数吗?我尝试使用 QFutureWatcher:

 QFutureWatcher<void> futureWatcher;
                       QFuture<void> f1 = run(
                                              MyFunction,
                                              filePath,
                                              file.absolutePath()+"/OUT_"+fileN,
                                              1,
                                              key
                                              );
                       QObject::connect(&futureWatcher, SIGNAL(finished()), progBar, SLOT(reset()));
                       QObject::connect(progBar, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
                       QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), progBar, SLOT(setRange(int,int)));
                       QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), progBar, SLOT(setValue(int)));

                       // Start the computation.
                       futureWatcher.setFuture(f1);
                       // Display the dialog and start the event loop.
                       progBar->exec();
                       futureWatcher.waitForFinished();
                       delete progBar;

它工作正常,当我只调用一次 MyFunction (对于一个文件)时,我的栏正在移动,但是当我多次调用 MyFunction 时出现问题(对于许多文件连续):它可以工作,但我得到所有文件的相同 OUT_file处理,我认为这是多线程问题。

编辑: class MyProgressDialog

class MyProgressDialog: public QProgressDialog
{
  Q_OBJECT

  public:

    MyProgressDialog()
      {

      qDebug()<<"MyProgressDialog constructor";

      label=new QLabel(this);

      QPalette* palette = new QPalette();
      palette->setColor(QPalette::Window,"#F8F8FF");
      setPalette(*palette);

      QFont* font = new QFont("Courier New");
          font->setItalic(true);
          font->setPixelSize(15);
      setFont(*font);
      adjustSize();

     setWindowIcon(QIcon(QApplication::applicationDirPath()+"/icons/icon1.png"));
     setWindowFlags(Qt::WindowStaysOnTopHint);
     setMinimumWidth(500);
     setMinimumHeight(200);
     labeltext=QString("Please wait until Encryption/Decryption was done");
     label->setText(labeltext);
     label->adjustSize();
     label->setWordWrap (true);
     setLabel(label);

     setRange(0,100);
     setWindowTitle("MyFunction progress");        
     setModal(true);    

    }
    ~MyProgressDialog()
    {
        qDebug()<<"MyProgressDialog destructor";
        delete label;
    }



public:

  int value;     
  QString labeltext;
  QLabel* label;

};
4

1 回答 1

1

Qt 中的 UI 是事件驱动的。因此,在与 ui 相同的线程中执行您的代码将阻塞每个 ui 事件,直到您的函数完成。有两种方法可以显示进步。

  1. 使用线程进行计算并将更新事件发送到 UI
  2. 更简单的方法:在每次调用setValueshow调用QApplication::processEvents();静态方法。调用QApplication::processEvents()将调度当前在事件循环中排队的事件。这些事件包括所有与 ui 相关的事件

这是 gcc/mingw gcc 的代码示例

#include <QApplication>
#include <QProgressBar>

int main(int argc, char * argv[])
{
    QApplication app(argc, argv);

    QProgressBar bar;
    bar.setRange(0, 100);
    bar.show();
    app.processEvents();
    usleep(250000);

    for(int i = 1; i <= 10; ++i)
    {
            bar.setValue(i * 10);
            app.processEvents();
            usleep(250000);
    }

    return 0;
}

它显示进度条并每 0.25 秒步进 10

您的代码应如下所示:

MyProgressDialog *progBar= new MyProgressDialog();
QProgressBar* bar = new QProgressBar(progBar);
bar->setRange(0, 100); // note your "busy state won't be shown as you're changing value right after show
bar->setValue(0);

progBar->setBar(bar);
QString labeltext=QString("<qt> <center><big><b>%1</b></big></center> <br><b>%2</b><br> %3 <br><b>%4</b><br> %5</qt>")
                     .arg(progBar->labeltext)
                     .arg("File in :")
                     .arg(FileI)
                     .arg("File out :")
                     .arg(FileO);
progBar->label->setText(labeltext);    
progBar->setValue(10);
progBar->show();
QApplication::processEvents(); // HERE
progBar->setValue(20);
QApplication::processEvents(); // HERE
Sleep(500);
progBar->setValue(50);
QApplication::processEvents(); // HERE
Sleep(500);
MyFunction(FileI,FileO,mode,key);
Sleep(500);
progBar->setValue(80);
QApplication::processEvents(); // HERE
Sleep(500);
progBar->setValue(100);
progBar->close();
QApplication::processEvents(); // HERE
delete bar;
delete progBar;
于 2012-11-05T10:23:30.643 回答