#c #qt
Вопрос:
У меня есть следующий код.
Метод compress (), в котором я выполняю задачу сжатия всего каталога, я вызываю этот метод из своей кнопки с помощью QtConcurrent, как вы можете видеть. пока все хорошо.
Мой вопрос в том, как я могу отобразить сообщение во время выполнения сжатия папки.
Я использую QuaZIP для процесса сжатия.
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_5_clicked();
private:
Ui::Widget *ui;
void compress();
public:
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>
#include <JlCompress.h>
#include <QtConcurrent/QtConcurrent>
#include <QFuture>
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_5_clicked()
{
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
QFuture<void> future=QtConcurrent::run(this,amp;Widget::compress);
future.waitForFinished();
QGuiApplication::restoreOverrideCursor();
QMessageBox::information(this,qApp->applicationName(),"The folder was compressed successfully.");
}
void Widget::compress()
{
if(!JlCompress::compressDir("C:/Users/Mypc/Desktop/iconos.zip", "D:/images/iconos")){
QMessageBox::warning(this,qApp->applicationName(),"Error compressing folder.");
return;
}
}
Я сделал это, но теперь, когда резервное копирование завершено, все приложение закрывается.
void Widget::on_pushButton_5_clicked()
{
QMessageBox box;
// box->setWindowFlags(Qt::Dialog | Qt::SplashScreen);
box.setStandardButtons(QMessageBox::NoButton);
box.setText("Realizando una tarea!");
box.setWindowTitle(qApp->applicationName());
box.setIcon(QMessageBox::Information);
box.setAttribute(Qt::WA_DeleteOnClose);
QFutureWatcher<void> watcher;
QFuture<void> future=QtConcurrent::run(this,amp;Widget::compress);
watcher.setFuture(future);
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
QObject::connect(amp;watcher,amp;QFutureWatcher<void>::finished,[amp;](){
box.close();
box.deleteLater();
QGuiApplication::restoreOverrideCursor();
});
box.exec();
QMessageBox::information(this,qApp->applicationName(), "The folder was compressed successfully.");
}
Также попробуйте ProgressDialog и QFutureWatcher следующим образом, но он не компилируется, я получаю эту ошибку.
void Widget::on_pushButton_5_clicked()
{
QStringList files;
QDir dir("D:/images/iconos/uigenericicon");
files=dir.entryList(QStringList() << "*.jpg" << "*.JPG"<<"*.PNG",QDir::Files);
qInfo()<<files;
QProgressDialog pDialog;
pDialog.setLabelText("Porecessing!!");
QFutureWatcher<void> watcher;
QObject::connect(amp;pDialog,SIGNAL(canceled()),amp;watcher,SLOT(cancel()));
QObject::connect(amp;watcher,SIGNAL(finished()),amp;pDialog,SLOT(reset()));
QObject::connect(amp;watcher,SIGNAL(progressRangeChanged(int,int)),amp;pDialog,SLOT(setRange(int,int)));
QObject::connect(amp;watcher,SIGNAL(progressValueChanged(int)),amp;pDialog,SLOT(setValue(int)));
watcher.setFuture(QtConcurrent::map(files,amp;Widget::compress));
pDialog.exec();
if(watcher.isCanceled()){
QMessageBox::information(this,qApp->applicationName(),"You canceled.");
}else{
QMessageBox::information(this,qApp->applicationName(),"All done.");
}
}
void Widget::compress(QStringList amp;files)
{
if(!JlCompress::compressFiles("C:/Users/Lincoln/Desktop/iconos.zip",files)){
QMessageBox::warning(this,qApp->applicationName(),"Error al comprimir la carpeta.");
return;
}
}
Комментарии:
1. Вы ищете неблокирующий QMessageBox?
2. Выполните фактическое сжатие в рабочем потоке, оставив поток пользовательского интерфейса разблокированным для отображения сообщения, которое вы можете закрыть, как только поток будет завершен.
3. Вам нужно избавиться от
future.waitForFinished();
этого, чтобы графический интерфейс не обновлялся до тех пор, пока выполняется параллельное задание. Помните, что графический интерфейс не будет обновляться до тех пор, пока он не выйдет из вашей функции и не вернется в цикл событий. Ваш QMessageBox также может быть проблематичным в том, что вы должны отображать это в потоке графического интерфейса, а не в рабочем.4. Если вы хотите использовать QtConcurrent, вам может потребоваться: https://doc.qt.io/qt-5/qfuturewatcher.html
5.
if(watcher.isCanceled()){
Деталь должна быть в функции reset ().