Added Worker to GUI process for time-consuming tasks (e.g. printing) to make GUI more responsive
This commit is contained in:
@@ -316,22 +316,22 @@ class CountdownMessage(QtWidgets.QFrame):
|
||||
|
||||
class PostprocessMessage(Widgets.TransparentOverlay):
|
||||
|
||||
def __init__(self, parent, tasks, idle_handle, timeout=None,
|
||||
timeout_handle=None):
|
||||
def __init__(self, parent, tasks, worker, idle_handle,
|
||||
timeout=None, timeout_handle=None):
|
||||
|
||||
if timeout_handle is None:
|
||||
timeout_handle = idle_handle
|
||||
|
||||
super().__init__(parent, timeout, timeout_handle)
|
||||
self.setObjectName('PostprocessMessage')
|
||||
self.initFrame(tasks, idle_handle)
|
||||
self.initFrame(tasks, idle_handle, worker)
|
||||
|
||||
def initFrame(self, tasks, idle_handle):
|
||||
def initFrame(self, tasks, idle_handle, worker):
|
||||
|
||||
def disableAndCall(button, handle):
|
||||
button.setEnabled(False)
|
||||
button.update()
|
||||
handle()
|
||||
worker.put(handle)
|
||||
|
||||
def createButton(task):
|
||||
button = QtWidgets.QPushButton(task.label)
|
||||
|
||||
@@ -36,6 +36,7 @@ from ..GuiPostprocessor import GuiPostprocessor
|
||||
from . import styles
|
||||
from . import Frames
|
||||
from . import Receiver
|
||||
from . import Worker
|
||||
|
||||
|
||||
class PyQt5Gui(GuiSkeleton):
|
||||
@@ -49,6 +50,7 @@ class PyQt5Gui(GuiSkeleton):
|
||||
is_start, unparsed_args = self._parseArgs()
|
||||
self._initUI(argv[:1] + unparsed_args)
|
||||
self._initReceiver()
|
||||
self._initWorker()
|
||||
|
||||
self._picture = None
|
||||
self._postprocess = GuiPostprocessor(self._cfg)
|
||||
@@ -101,6 +103,12 @@ class PyQt5Gui(GuiSkeleton):
|
||||
self._receiver.notify.connect(self.handleState)
|
||||
self._receiver.start()
|
||||
|
||||
def _initWorker(self):
|
||||
|
||||
# Create worker thread for time consuming tasks to keep gui responsive
|
||||
self._worker = Worker.Worker(self._comm)
|
||||
self._worker.start()
|
||||
|
||||
def _enableEscape(self):
|
||||
|
||||
self._is_escape = True
|
||||
@@ -131,6 +139,7 @@ class PyQt5Gui(GuiSkeleton):
|
||||
if state.target == TeardownEvent.WELCOME:
|
||||
self._comm.send(Workers.MASTER, GuiEvent('welcome'))
|
||||
elif state.target in (TeardownEvent.EXIT, TeardownEvent.RESTART):
|
||||
self._worker.put(None)
|
||||
self._app.exit(0)
|
||||
|
||||
def showError(self, state):
|
||||
@@ -229,7 +238,7 @@ class PyQt5Gui(GuiSkeleton):
|
||||
postproc_t = self._cfg.getInt('Photobooth', 'postprocess_time')
|
||||
|
||||
Frames.PostprocessMessage(
|
||||
self._gui.centralWidget(), tasks,
|
||||
self._gui.centralWidget(), tasks, self._worker,
|
||||
lambda: self._comm.send(Workers.MASTER, GuiEvent('idle')),
|
||||
postproc_t * 1000)
|
||||
|
||||
|
||||
52
photobooth/gui/Qt5Gui/Worker.py
Normal file
52
photobooth/gui/Qt5Gui/Worker.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Photobooth - a flexible photo booth software
|
||||
# Copyright (C) 2018 Balthasar Reuter <photobooth at re - web dot eu>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import queue
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
|
||||
class Worker(QtCore.QThread):
|
||||
|
||||
def __init__(self, comm):
|
||||
|
||||
super().__init__()
|
||||
self._comm = comm
|
||||
self._queue = queue.Queue()
|
||||
|
||||
def put(self, task):
|
||||
|
||||
self._queue.put(task)
|
||||
|
||||
def get(self):
|
||||
|
||||
return self._queue.get()
|
||||
|
||||
def done(self):
|
||||
|
||||
self._queue.task_done()
|
||||
|
||||
def run(self):
|
||||
|
||||
while True:
|
||||
task = self.get()
|
||||
if task is None:
|
||||
break
|
||||
task()
|
||||
self.done()
|
||||
Reference in New Issue
Block a user