Advance the progress bar in the foreground when a long running task

in the background (e.g. git clone).
This commit is contained in:
Gerhard Hoffmann 2023-08-06 20:44:26 +02:00
parent 1fd2269753
commit 4ff3b0efdf
6 changed files with 98 additions and 22 deletions

View File

@ -12,7 +12,9 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
, m_worker(worker) , m_worker(worker)
, m_width(70) { , m_width(70)
, m_progressRunning(false)
, m_progressValue(0) {
ui->setupUi(this); ui->setupUi(this);
ui->updateProgress->setRange(0, 100); ui->updateProgress->setRange(0, 100);
@ -71,11 +73,51 @@ MainWindow::~MainWindow() {
void MainWindow::customEvent(QEvent *event) { void MainWindow::customEvent(QEvent *event) {
if (event->type() == ProgressEvent::type()) { if (event->type() == ProgressEvent::type()) {
int progress = ((ProgressEvent *)(event))->progressPercent(); ProgressEvent *pevent = (ProgressEvent *)event;
if (progress > 0) { int const progress = pevent->progressPercent();
ui->updateProgress->setValue(progress); QObject const *sender = pevent->sender();
} else { if (sender == this) {
switch(progress) {
case 0: {
ui->updateProgress->reset(); ui->updateProgress->reset();
} break;
case START_PROGRESS_LOOP: {
m_progressRunning = true;
ui->updateProgress->reset();
m_progressValue = 10;
QApplication::postEvent(this, new ProgressEvent(this, m_progressValue));
} break;
case STOP_PROGRESS_LOOP: {
m_progressRunning = false;
m_progressValue -= 10;
m_worker->setProgress(m_progressValue/10);
} break;
default: {
if (m_progressRunning) {
m_progressValue = progress;
ui->updateProgress->setValue(progress/10);
QApplication::postEvent(this, new ProgressEvent(this, progress+10));
QThread::msleep(100);
}
}
}
} else
if (sender == m_worker) {
switch(progress) {
case 0: {
ui->updateProgress->reset();
} break;
case START_PROGRESS_LOOP: {
QApplication::postEvent(this, new ProgressEvent(this, START_PROGRESS_LOOP));
} break;
case STOP_PROGRESS_LOOP: {
QApplication::postEvent(this, new ProgressEvent(this, STOP_PROGRESS_LOOP));
} break;
default:{
ui->updateProgress->setValue(progress);
}}
} else {
qCritical() << "!!! UNKNOWN SENDER !!!";
} }
} }
} }

View File

@ -20,6 +20,11 @@ public:
MainWindow(Worker *worker, QWidget *parent = nullptr); MainWindow(Worker *worker, QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
static const int START_PROGRESS_LOOP = -1;
static const int STOP_PROGRESS_LOOP = -2;
int progressValue() const { return m_progressValue; }
public slots: public slots:
void onAppendText(QString, QString suffix = ""); void onAppendText(QString, QString suffix = "");
void onReplaceLast(QString, QString); void onReplaceLast(QString, QString);
@ -38,5 +43,7 @@ private:
int m_width; int m_width;
QTimer *m_startTimer; QTimer *m_startTimer;
QTimer *m_exitTimer; QTimer *m_exitTimer;
bool m_progressRunning;
int m_progressValue;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -2,8 +2,9 @@
QEvent::Type ProgressEvent::customEventType = QEvent::None; QEvent::Type ProgressEvent::customEventType = QEvent::None;
ProgressEvent::ProgressEvent(int progressPercent) ProgressEvent::ProgressEvent(QObject const *sender, int progressPercent)
: QEvent(ProgressEvent::type()) : QEvent(ProgressEvent::type())
, m_sender(sender)
, m_progressPercent(progressPercent) { , m_progressPercent(progressPercent) {
} }

View File

@ -5,12 +5,16 @@
class ProgressEvent : public QEvent { class ProgressEvent : public QEvent {
QObject const *m_sender;
int m_progressPercent; int m_progressPercent;
public: public:
explicit ProgressEvent(int progressPercent); explicit ProgressEvent(QObject const *sender, int progressPercent);
virtual ~ProgressEvent(); virtual ~ProgressEvent();
static QEvent::Type type(); static QEvent::Type type();
QObject const *sender() { return m_sender; }
QObject const *sender() const { return m_sender; }
void setProgress(int progressPercent) { m_progressPercent = progressPercent; } void setProgress(int progressPercent) { m_progressPercent = progressPercent; }
int progressPercent() { return m_progressPercent; } int progressPercent() { return m_progressPercent; }
int progressPercent() const { return m_progressPercent; } int progressPercent() const { return m_progressPercent; }

View File

@ -68,7 +68,8 @@ Worker::Worker(hwinf *hw,
, m_waitForNewUpdates(this) , m_waitForNewUpdates(this)
, m_filesToUpdate() , m_filesToUpdate()
, m_updateProcessRunning(false) , m_updateProcessRunning(false)
, m_returnCode(0) { , m_returnCode(0)
, m_progressValue{0} {
QDir::setCurrent(m_workingDirectory); QDir::setCurrent(m_workingDirectory);
@ -116,10 +117,19 @@ Worker::~Worker() {
void Worker::setProgress(int progress) { void Worker::setProgress(int progress) {
if (m_mainWindow) { if (m_mainWindow) {
QApplication::postEvent(m_mainWindow, new ProgressEvent(progress)); m_progressValue = progress;
QApplication::postEvent(m_mainWindow, new ProgressEvent(this, progress));
} }
} }
void Worker::startProgressLoop() {
QApplication::postEvent(m_mainWindow, new ProgressEvent(this, MainWindow::START_PROGRESS_LOOP));
}
void Worker::stopProgressLoop() {
QApplication::postEvent(m_mainWindow, new ProgressEvent(this, MainWindow::STOP_PROGRESS_LOOP));
}
static std::once_flag once; static std::once_flag once;
void Worker::update() { void Worker::update() {
// user should not start the update process several times // user should not start the update process several times
@ -130,17 +140,27 @@ void Worker::privateUpdate() {
QPushButton *start = qobject_cast<QPushButton *>(QObject::sender()); QPushButton *start = qobject_cast<QPushButton *>(QObject::sender());
start->setEnabled(false); start->setEnabled(false);
//emit appendText("\nConnecting backend ..."); #if 0
// emit appendText("\nConnecting backend ...");
//for (int i=0;i <= 100; ++i) {
// setProgress(i); for (int i=0;i <= 100; ++i) {
// QThread::msleep(100); setProgress(i);
//} QThread::msleep(100);
//emit replaceLast("Connecting backend ...", UPDATE_STEP_OK); }
//emit appendText(QString("UPDATE "), UPDATE_STEP_SUCCESS); emit replaceLast("Connecting backend ...", UPDATE_STEP_OK);
//emit appendText(QString("UPDATE "), UPDATE_STEP_FAIL); emit appendText(QString("UPDATE "), UPDATE_STEP_SUCCESS);
// setProgress(0); emit appendText(QString("UPDATE "), UPDATE_STEP_FAIL);
// return; setProgress(0);
startProgressLoop();
QThread::sleep(5); // long running process
stopProgressLoop();
for (int i=m_mainWindow->progressValue()/10; i <= 100; ++i) {
setProgress(i);
QThread::msleep(100);
}
return;
#endif
emit stopStartTimer(); emit stopStartTimer();
emit disableExit(); emit disableExit();

View File

@ -126,6 +126,7 @@ class Worker : public QObject {
int m_returnCode; int m_returnCode;
MainWindow *m_mainWindow; MainWindow *m_mainWindow;
int m_progressValue;
bool executeOpkgCommand(QString opkgCommand); bool executeOpkgCommand(QString opkgCommand);
QString getOsVersion() const; QString getOsVersion() const;
@ -138,8 +139,6 @@ class Worker : public QObject {
qint64 getFileSize(QString const &fileName) const; qint64 getFileSize(QString const &fileName) const;
void setProgress(int progress);
public: public:
static const QString UPDATE_STEP_OK; static const QString UPDATE_STEP_OK;
static const QString UPDATE_STEP_DONE; static const QString UPDATE_STEP_DONE;
@ -159,6 +158,7 @@ public:
~Worker(); ~Worker();
void setMainWindow(MainWindow *mainWindow) { m_mainWindow = mainWindow; } void setMainWindow(MainWindow *mainWindow) { m_mainWindow = mainWindow; }
void setProgress(int progress);
IsmasClient &getIsmasClient() { return m_ismasClient; } IsmasClient &getIsmasClient() { return m_ismasClient; }
IsmasClient const &getIsmasClient() const { return m_ismasClient; } IsmasClient const &getIsmasClient() const { return m_ismasClient; }
@ -205,6 +205,8 @@ private:
PSAInstalled getPSAInstalled(); PSAInstalled getPSAInstalled();
QString sendCmdSendVersionToIsmas(); QString sendCmdSendVersionToIsmas();
void privateUpdate(); void privateUpdate();
void startProgressLoop();
void stopProgressLoop();
}; };
#endif // WORKER_H_INCLUDED #endif // WORKER_H_INCLUDED