我正在尝试在执行一个函数时显示忙碌的等待条,我的问题是它在函数启动后停止移动。
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;
};
答案 0 :(得分:1)
Qt中的UI是事件驱动的。因此,在与ui相同的线程中执行代码将阻止每个ui事件,直到您的函数完成。有两种方法可以显示进展。
setValue
和show
调用后调用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,05s步骤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;