C++ QProgresdialog:函数执行时,忙等待栏未移动

C++ QProgresdialog:函数执行时,忙等待栏未移动,c++,qt,thread-safety,progress-bar,C++,Qt,Thread Safety,Progress Bar,我试图在一个函数执行时显示一个繁忙的等待条,我的问题是一旦函数启动它就会停止移动 MyProgressDialog *progBar= new MyProgressDialog(); QProgressBar* bar = new QProgressBar(progBar); bar->setRange(0, 0); bar->setValue(0); progBar->setBar(bar); QString labeltext=QS

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

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;

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

  • 使用线程进行计算并将更新事件发送到UI
  • 更简单的方法:在每次调用
    setValue
    show
    调用
    QApplication::processEvents()之后静态方法。调用
    QApplication::processEvents()
    将分派当前在事件循环上排队的事件。这些事件包括所有与ui相关的事件
  • 下面是gcc/mingwgcc的代码示例

    #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;
    }
    
    #包括
    #包括
    int main(int argc,char*argv[])
    {
    QApplication应用程序(argc、argv);
    QProgressBar条;
    设置范围(0,100);
    bar.show();
    app.processEvents();
    美国LEEP(250000);
    对于(int i=1;i setRange(01100);//注意,在显示之后,您正在更改值,因此不会显示“忙”状态
    条->设置值(0);
    progBar->立根杆(杆);
    QString labeltext=QString(“%1
    %2
    %3
    %4
    %5”) .arg(程序条->标签文本) .arg(“文件位于:”) .arg(文件i) .arg(“文件输出:”) .arg(FileO); 程序条->标签->设置文本(标签文本); progBar->setValue(10); progBar->show(); QApplication::processEvents();//此处 progBar->setValue(20); QApplication::processEvents();//此处 睡眠(500); 程序条->设置值(50); QApplication::processEvents();//此处 睡眠(500); MyFunction(文件I、文件O、模式、键); 睡眠(500); 程序条->设置值(80); QApplication::processEvents();//此处 睡眠(500); 程序条->设置值(100); progBar->close(); QApplication::processEvents();//此处 删除条; 删除程序条;
    谢谢@Kamil,与
    QApplication::processEvents()的结果相同
    ,我将尝试第一种方法并查看。如果与QApplication::processEvents的结果相同,则说明您做错了。您将“processEvents”调用放在哪里了?我将范围设置为0,0以使其处于忙碌状态,我调用了
    QApplication::processEvents()
    在调用MyFunction之前,这是否足够,还是应该调用
    myapp.processEvents();
    那么如何获取QApplication的当前实例!!!您不需要QApplication的实例。processEvents是静态方法。您必须更改范围以使进度条显示正确的值。正如我前面所说的,您必须在每次调用之后调用processEventssetValue@oumaya向我们展示
    MyProgressDialog
    implementation。也许你很好如果有错误,你能告诉我们什么是fileN,我的函数实现也很有用。它是类的方法还是独立函数?FileI和FileO是qstring(文件的绝对路径),MyFunction是用c语言编写的独立函数。我说的是
    file.absolutePath()+“/OUT_“+fileN
    在此上下文中,它是我的文件的基本名称。
    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;
    
    };
    
    #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;
    }
    
    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;