Skip to content

Commit 633e562

Browse files
committed
reg: put database update progress dialog into its own thread and improve it
1 parent e8a44d5 commit 633e562

1 file changed

Lines changed: 69 additions & 25 deletions

File tree

dcoraid/gui/main.py

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939

4040

4141
class DCORAid(QtWidgets.QMainWindow):
42+
progress_update_event = QtCore.pyqtSignal()
43+
4244
def __init__(self, *args, **kwargs):
4345
"""Initialize DCOR-Aid
4446
@@ -71,6 +73,11 @@ def __init__(self, *args, **kwargs):
7173
QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 300)
7274
sys.exit(0)
7375

76+
# Progressbar for database updates
77+
self._prog_update_db = None
78+
self._dbup_thread = None
79+
self._dbup_worker = None
80+
7481
#: DCOR-Aid settings
7582
self.settings = QtCore.QSettings()
7683
ref_ui = resources.files("dcoraid.gui") / "main.ui"
@@ -201,40 +208,35 @@ def check_update_database(self, reset=False, force=False):
201208
QtWidgets.QMessageBox.StandardButton.Yes)
202209
doit = button_reply == QtWidgets.QMessageBox.StandardButton.Yes
203210
if doit:
204-
abort_event = threading.Event()
205-
prog = QtWidgets.QProgressDialog(
206-
"Performing database update, please wait..." + " "*20,
211+
self._prog_update_db = QtWidgets.QProgressDialog(
212+
"Performing database update, please wait...\n" + " " * 200,
207213
"Abort",
208214
0,
209215
0,
210216
self
211217
)
212-
prog.canceled.connect(abort_event.set)
213-
prog.setMinimumDuration(0)
214-
prog.setModal(True)
215-
prog.show()
216-
217-
def prog_update_callback(data):
218-
cdict = data["circle_current"]
219-
new_ds = data["datasets_new"]
220-
title = cdict.get("title")
221-
if not title:
222-
title = cdict.get("name")
223-
if len(title) > 50:
224-
title = title[:50] + "..."
225-
prog.setLabelText(f"Fetching '{title}'\n"
226-
f"Imported {new_ds} datasets so far.")
227-
228-
thr = threading.Thread(target=self.database.update,
229-
args=(reset, abort_event,
230-
prog_update_callback))
231-
thr.start()
232-
233-
while thr.is_alive():
218+
self._prog_update_db.setMinimumDuration(0)
219+
self._prog_update_db.show()
220+
221+
# This is hell of a lot of boilerplate for just one progress bar.
222+
self._dbup_thread = QtCore.QThread()
223+
self._dbup_worker = UpdateDatabaseWorker(
224+
update=self.database.update, reset=reset)
225+
self._dbup_worker.moveToThread(self._dbup_thread)
226+
self._dbup_thread.started.connect(self._dbup_worker.run)
227+
self._dbup_worker.finished.connect(self._dbup_thread.quit)
228+
self._dbup_worker.finished.connect(self._dbup_worker.deleteLater)
229+
self._dbup_worker.progress.connect(self.on_progress_db_update)
230+
self._prog_update_db.canceled.connect(self._dbup_worker.cancelled)
231+
self._dbup_thread.start()
232+
233+
while self._dbup_thread.isRunning():
234234
QtWidgets.QApplication.processEvents(
235235
QtCore.QEventLoop.ProcessEventsFlag.AllEvents, 300)
236236
QtTest.QTest.qWait(500)
237237

238+
self._prog_update_db.deleteLater()
239+
238240
self._last_asked_about_update = time.time()
239241

240242
@QtCore.pyqtSlot(QtCore.QEvent)
@@ -338,12 +340,54 @@ def on_action_software(self):
338340
def on_dataset_changed(self, ds_dict):
339341
self.database.update_dataset(ds_dict)
340342

343+
@QtCore.pyqtSlot(dict)
344+
def on_progress_db_update(self, data):
345+
cdict = data["circle_current"]
346+
new_ds = data["datasets_new"]
347+
title = cdict.get("title")
348+
if not title:
349+
title = cdict.get("name")
350+
if len(title) > 50:
351+
title = title[:50] + "..."
352+
if self._prog_update_db is not None:
353+
self._prog_update_db.setLabelText(
354+
f"Fetching '{title}'\n"
355+
f"Imported {new_ds} datasets so far.")
356+
circle_ids = [c["id"] for c in data["circles"]]
357+
cur_index = circle_ids.index(cdict["id"])
358+
self._prog_update_db.setMaximum(len(circle_ids))
359+
self._prog_update_db.setValue(cur_index + 1)
360+
else:
361+
self.logger.error("Progress dialog not defined")
362+
341363
@QtCore.pyqtSlot()
342364
def on_wizard(self):
343365
self.wizard = SetupWizard(self)
344366
self.wizard.exec()
345367

346368

369+
class UpdateDatabaseWorker(QtCore.QObject):
370+
finished = QtCore.pyqtSignal()
371+
progress = QtCore.pyqtSignal(dict)
372+
373+
def __init__(self, update, reset, *args, **kwargs):
374+
self.update = update
375+
self.reset = reset
376+
self.abort_event = threading.Event()
377+
super(UpdateDatabaseWorker, self).__init__(*args, **kwargs)
378+
379+
@QtCore.pyqtSlot()
380+
def cancelled(self):
381+
self.abort_event.set()
382+
383+
def run(self):
384+
"""Long-running task."""
385+
self.update(reset=self.reset,
386+
abort_event=self.abort_event,
387+
callback=self.progress.emit)
388+
self.finished.emit()
389+
390+
347391
def excepthook(etype, value, trace):
348392
"""
349393
Handler for all unhandled exceptions.

0 commit comments

Comments
 (0)