diff --git a/openpype/modules/default_modules/idle_manager/__init__.py b/openpype/modules/default_modules/idle_manager/__init__.py deleted file mode 100644 index 9d6e10bf39..0000000000 --- a/openpype/modules/default_modules/idle_manager/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .idle_module import ( - IdleManager -) - - -__all__ = ( - "IdleManager", -) diff --git a/openpype/modules/default_modules/idle_manager/idle_module.py b/openpype/modules/default_modules/idle_manager/idle_module.py deleted file mode 100644 index 1a6d71a961..0000000000 --- a/openpype/modules/default_modules/idle_manager/idle_module.py +++ /dev/null @@ -1,79 +0,0 @@ -import platform -import collections - -from openpype.modules import OpenPypeModule -from openpype_interfaces import ( - ITrayService, - IIdleManager -) - - -class IdleManager(OpenPypeModule, ITrayService): - """ Measure user's idle time in seconds. - Idle time resets on keyboard/mouse input. - Is able to emit signals at specific time idle. - """ - label = "Idle Service" - name = "idle_manager" - - def initialize(self, module_settings): - enabled = True - # Ignore on MacOs - # - pynput need root permissions and enabled access for application - if platform.system().lower() == "darwin": - enabled = False - self.enabled = enabled - - self.time_callbacks = collections.defaultdict(list) - self.idle_thread = None - - def tray_init(self): - return - - def tray_start(self): - if self.time_callbacks: - self.start_thread() - - def tray_exit(self): - self.stop_thread() - try: - self.time_callbacks = {} - except Exception: - pass - - def connect_with_modules(self, enabled_modules): - for module in enabled_modules: - if not isinstance(module, IIdleManager): - continue - - module.idle_manager = self - callbacks_items = module.callbacks_by_idle_time() or {} - for emit_time, callbacks in callbacks_items.items(): - if not isinstance(callbacks, (tuple, list, set)): - callbacks = [callbacks] - self.time_callbacks[emit_time].extend(callbacks) - - @property - def idle_time(self): - if self.idle_thread and self.idle_thread.is_running: - return self.idle_thread.idle_time - - def _create_thread(self): - from .idle_threads import IdleManagerThread - - return IdleManagerThread(self) - - def start_thread(self): - if self.idle_thread: - self.idle_thread.stop() - self.idle_thread.join() - self.idle_thread = self._create_thread() - self.idle_thread.start() - - def stop_thread(self): - if self.idle_thread: - self.idle_thread.stop() - self.idle_thread.join() - - def on_thread_stop(self): - self.set_service_failed_icon() diff --git a/openpype/modules/default_modules/idle_manager/idle_threads.py b/openpype/modules/default_modules/idle_manager/idle_threads.py deleted file mode 100644 index f19feddb77..0000000000 --- a/openpype/modules/default_modules/idle_manager/idle_threads.py +++ /dev/null @@ -1,97 +0,0 @@ -import time -import threading - -from pynput import mouse, keyboard - -from openpype.lib import PypeLogger - - -class MouseThread(mouse.Listener): - """Listens user's mouse movement.""" - - def __init__(self, callback): - super(MouseThread, self).__init__(on_move=self.on_move) - self.callback = callback - - def on_move(self, posx, posy): - self.callback() - - -class KeyboardThread(keyboard.Listener): - """Listens user's keyboard input.""" - - def __init__(self, callback): - super(KeyboardThread, self).__init__(on_press=self.on_press) - - self.callback = callback - - def on_press(self, key): - self.callback() - - -class IdleManagerThread(threading.Thread): - def __init__(self, module, *args, **kwargs): - super(IdleManagerThread, self).__init__(*args, **kwargs) - self.log = PypeLogger.get_logger(self.__class__.__name__) - self.module = module - self.threads = [] - self.is_running = False - self.idle_time = 0 - - def stop(self): - self.is_running = False - - def reset_time(self): - self.idle_time = 0 - - @property - def time_callbacks(self): - return self.module.time_callbacks - - def on_stop(self): - self.is_running = False - self.log.info("IdleManagerThread has stopped") - self.module.on_thread_stop() - - def run(self): - self.log.info("IdleManagerThread has started") - self.is_running = True - thread_mouse = MouseThread(self.reset_time) - thread_keyboard = KeyboardThread(self.reset_time) - thread_mouse.start() - thread_keyboard.start() - try: - while self.is_running: - if self.idle_time in self.time_callbacks: - for callback in self.time_callbacks[self.idle_time]: - thread = threading.Thread(target=callback) - thread.start() - self.threads.append(thread) - - for thread in tuple(self.threads): - if not thread.isAlive(): - thread.join() - self.threads.remove(thread) - - self.idle_time += 1 - time.sleep(1) - - except Exception: - self.log.warning( - 'Idle Manager service has failed', exc_info=True - ) - - # Threads don't have their attrs when Qt application already finished - try: - thread_mouse.stop() - thread_mouse.join() - except AttributeError: - pass - - try: - thread_keyboard.stop() - thread_keyboard.join() - except AttributeError: - pass - - self.on_stop() diff --git a/openpype/modules/default_modules/idle_manager/interfaces.py b/openpype/modules/default_modules/idle_manager/interfaces.py deleted file mode 100644 index 71cd17a64a..0000000000 --- a/openpype/modules/default_modules/idle_manager/interfaces.py +++ /dev/null @@ -1,26 +0,0 @@ -from abc import abstractmethod -from openpype.modules import OpenPypeInterface - - -class IIdleManager(OpenPypeInterface): - """Other modules interface to return callbacks by idle time in seconds. - - Expected output is dictionary with seconds as keys and callback/s - as value, value may be callback of list of callbacks. - EXAMPLE: - ``` - { - 60: self.on_minute_idle - } - ``` - """ - idle_manager = None - - @abstractmethod - def callbacks_by_idle_time(self): - pass - - @property - def idle_time(self): - if self.idle_manager: - return self.idle_manager.idle_time diff --git a/openpype/modules/default_modules/timers_manager/idle_threads.py b/openpype/modules/default_modules/timers_manager/idle_threads.py new file mode 100644 index 0000000000..9ec27e659b --- /dev/null +++ b/openpype/modules/default_modules/timers_manager/idle_threads.py @@ -0,0 +1,160 @@ +import time +from Qt import QtCore +from pynput import mouse, keyboard + +from openpype.lib import PypeLogger + + +class IdleItem: + """Python object holds information if state of idle changed. + + This item is used to be independent from Qt objects. + """ + def __init__(self): + self.changed = False + + def reset(self): + self.changed = False + + def set_changed(self, changed=True): + self.changed = changed + + +class IdleManager(QtCore.QThread): + """ Measure user's idle time in seconds. + Idle time resets on keyboard/mouse input. + Is able to emit signals at specific time idle. + """ + time_signals = {} + idle_time = 0 + signal_reset_timer = QtCore.Signal() + + def __init__(self): + super(IdleManager, self).__init__() + self.log = PypeLogger.get_logger(self.__class__.__name__) + self.signal_reset_timer.connect(self._reset_time) + + self.idle_item = IdleItem() + + self._is_running = False + self._mouse_thread = None + self._keyboard_thread = None + + def add_time_signal(self, emit_time, signal): + """ If any module want to use IdleManager, need to use add_time_signal + + Args: + emit_time(int): Time when signal will be emitted. + signal(QtCore.Signal): Signal that will be emitted + (without objects). + """ + if emit_time not in self.time_signals: + self.time_signals[emit_time] = [] + self.time_signals[emit_time].append(signal) + + @property + def is_running(self): + return self._is_running + + def _reset_time(self): + self.idle_time = 0 + + def stop(self): + self._is_running = False + + def _on_mouse_destroy(self): + self._mouse_thread = None + + def _on_keyboard_destroy(self): + self._keyboard_thread = None + + def run(self): + self.log.info('IdleManager has started') + self._is_running = True + + thread_mouse = MouseThread(self.idle_item) + thread_keyboard = KeyboardThread(self.idle_item) + + thread_mouse.destroyed.connect(self._on_mouse_destroy) + thread_keyboard.destroyed.connect(self._on_keyboard_destroy) + + self._mouse_thread = thread_mouse + self._keyboard_thread = thread_keyboard + + thread_mouse.start() + thread_keyboard.start() + + # Main loop here is each second checked if idle item changed state + while self._is_running: + if self.idle_item.changed: + self.idle_item.reset() + self.signal_reset_timer.emit() + else: + self.idle_time += 1 + + if self.idle_time in self.time_signals: + for signal in self.time_signals[self.idle_time]: + signal.emit() + time.sleep(1) + + self._post_run() + self.log.info('IdleManager has stopped') + + def _post_run(self): + # Stop threads if still exist + if self._mouse_thread is not None: + self._mouse_thread.signal_stop.emit() + self._mouse_thread.terminate() + self._mouse_thread.wait() + + if self._keyboard_thread is not None: + self._keyboard_thread.signal_stop.emit() + self._keyboard_thread.terminate() + self._keyboard_thread.wait() + + +class MouseThread(QtCore.QThread): + """Listens user's mouse movement.""" + signal_stop = QtCore.Signal() + + def __init__(self, idle_item): + super(MouseThread, self).__init__() + self.signal_stop.connect(self.stop) + self.m_listener = None + self.idle_item = idle_item + + def stop(self): + if self.m_listener is not None: + self.m_listener.stop() + + def on_move(self, *args, **kwargs): + self.idle_item.set_changed() + + def run(self): + self.m_listener = mouse.Listener(on_move=self.on_move) + self.m_listener.start() + + +class KeyboardThread(QtCore.QThread): + """Listens user's keyboard input + """ + signal_stop = QtCore.Signal() + + def __init__(self, idle_item): + super(KeyboardThread, self).__init__() + self.signal_stop.connect(self.stop) + self.k_listener = None + self.idle_item = idle_item + + def stop(self): + if self.k_listener is not None: + listener = self.k_listener + self.k_listener = None + listener.stop() + + def on_press(self, *args, **kwargs): + self.idle_item.set_changed() + + def run(self): + self.k_listener = keyboard.Listener(on_press=self.on_press) + self.k_listener.start() diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 47ba0b4059..6d08ad9dc5 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -1,10 +1,9 @@ import os -import collections +import platform from openpype.modules import OpenPypeModule from openpype_interfaces import ( ITimersManager, - ITrayService, - IIdleManager + ITrayService ) from avalon.api import AvalonMongoDB @@ -68,7 +67,7 @@ class ExampleTimersManagerConnector: self._timers_manager_module.timer_stopped(self._module.id) -class TimersManager(OpenPypeModule, ITrayService, IIdleManager): +class TimersManager(OpenPypeModule, ITrayService): """ Handles about Timers. Should be able to start/stop all timers at once. @@ -93,12 +92,16 @@ class TimersManager(OpenPypeModule, ITrayService, IIdleManager): self.enabled = timers_settings["enabled"] - auto_stop = timers_settings["auto_stop"] # When timer will stop if idle manager is running (minutes) full_time = int(timers_settings["full_time"] * 60) # How many minutes before the timer is stopped will popup the message message_time = int(timers_settings["message_time"] * 60) + auto_stop = timers_settings["auto_stop"] + # Turn of auto stop on MacOs because pynput requires root permissions + if platform.system().lower() == "darwin" or full_time <= 0: + auto_stop = False + self.auto_stop = auto_stop self.time_show_message = full_time - message_time self.time_stop_timer = full_time @@ -107,24 +110,46 @@ class TimersManager(OpenPypeModule, ITrayService, IIdleManager): self.last_task = None # Tray attributes - self.signal_handler = None - self.widget_user_idle = None - self.signal_handler = None + self._signal_handler = None + self._widget_user_idle = None + self._idle_manager = None self._connectors_by_module_id = {} self._modules_by_id = {} def tray_init(self): + if not self.auto_stop: + return + + from .idle_threads import IdleManager from .widget_user_idle import WidgetUserIdle, SignalHandler - self.widget_user_idle = WidgetUserIdle(self) - self.signal_handler = SignalHandler(self) + + signal_handler = SignalHandler(self) + idle_manager = IdleManager() + widget_user_idle = WidgetUserIdle(self) + widget_user_idle.set_countdown_start(self.time_show_message) + + idle_manager.signal_reset_timer.connect( + widget_user_idle.reset_countdown + ) + idle_manager.add_time_signal( + self.time_show_message, signal_handler.signal_show_message + ) + idle_manager.add_time_signal( + self.time_stop_timer, signal_handler.signal_stop_timers + ) + + self._signal_handler = signal_handler + self._widget_user_idle = widget_user_idle + self._idle_manager = idle_manager def tray_start(self, *_a, **_kw): - return + if self._idle_manager: + self._idle_manager.start() def tray_exit(self): - """Nothing special for TimersManager.""" - return + if self._idle_manager: + self._idle_manager.stop() def start_timer(self, project_name, asset_name, task_name, hierarchy): """ @@ -205,8 +230,8 @@ class TimersManager(OpenPypeModule, ITrayService, IIdleManager): if self.is_running is False: return - self.widget_user_idle.bool_not_stopped = False - self.widget_user_idle.refresh_context() + if self._widget_user_idle is not None: + self._widget_user_idle.set_timer_stopped() self.is_running = False self.timer_stopped(None) @@ -244,70 +269,12 @@ class TimersManager(OpenPypeModule, ITrayService, IIdleManager): " for connector of module \"{}\"." ).format(module.name)) - def callbacks_by_idle_time(self): - """Implementation of IIdleManager interface.""" - # Time when message is shown - if not self.auto_stop: - return {} - - callbacks = collections.defaultdict(list) - callbacks[self.time_show_message].append(lambda: self.time_callback(0)) - - # Times when idle is between show widget and stop timers - show_to_stop_range = range( - self.time_show_message - 1, self.time_stop_timer - ) - for num in show_to_stop_range: - callbacks[num].append(lambda: self.time_callback(1)) - - # Times when widget is already shown and user restart idle - shown_and_moved_range = range( - self.time_stop_timer - self.time_show_message - ) - for num in shown_and_moved_range: - callbacks[num].append(lambda: self.time_callback(1)) - - # Time when timers are stopped - callbacks[self.time_stop_timer].append(lambda: self.time_callback(2)) - - return callbacks - - def time_callback(self, int_def): - if not self.signal_handler: - return - - if int_def == 0: - self.signal_handler.signal_show_message.emit() - elif int_def == 1: - self.signal_handler.signal_change_label.emit() - elif int_def == 2: - self.signal_handler.signal_stop_timers.emit() - - def change_label(self): - if self.is_running is False: - return - - if ( - not self.idle_manager - or self.widget_user_idle.bool_is_showed is False - ): - return - - if self.idle_manager.idle_time > self.time_show_message: - value = self.time_stop_timer - self.idle_manager.idle_time - else: - value = 1 + ( - self.time_stop_timer - - self.time_show_message - - self.idle_manager.idle_time - ) - self.widget_user_idle.change_count_widget(value) - def show_message(self): if self.is_running is False: return - if self.widget_user_idle.bool_is_showed is False: - self.widget_user_idle.show() + if not self._widget_user_idle.is_showed(): + self._widget_user_idle.reset_countdown() + self._widget_user_idle.show() # Webserver module implementation def webserver_initialization(self, server_manager): diff --git a/openpype/modules/default_modules/timers_manager/widget_user_idle.py b/openpype/modules/default_modules/timers_manager/widget_user_idle.py index cefa6bb4fb..1ecea74440 100644 --- a/openpype/modules/default_modules/timers_manager/widget_user_idle.py +++ b/openpype/modules/default_modules/timers_manager/widget_user_idle.py @@ -3,168 +3,193 @@ from openpype import resources, style class WidgetUserIdle(QtWidgets.QWidget): - SIZE_W = 300 SIZE_H = 160 def __init__(self, module): - super(WidgetUserIdle, self).__init__() - self.bool_is_showed = False - self.bool_not_stopped = True - - self.module = module + self.setWindowTitle("OpenPype - Stop timers") icon = QtGui.QIcon(resources.get_openpype_icon_filepath()) self.setWindowIcon(icon) + self.setWindowFlags( QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinimizeButtonHint ) - self._translate = QtCore.QCoreApplication.translate + self._is_showed = False + self._timer_stopped = False + self._countdown = 0 + self._countdown_start = 0 - self.font = QtGui.QFont() - self.font.setFamily("DejaVu Sans Condensed") - self.font.setPointSize(9) - self.font.setBold(True) - self.font.setWeight(50) - self.font.setKerning(True) + self.module = module + + msg_info = "You didn't work for a long time." + msg_question = "Would you like to stop Timers?" + msg_stopped = ( + "Your Timers were stopped. Do you want to start them again?" + ) + + lbl_info = QtWidgets.QLabel(msg_info, self) + lbl_info.setTextFormat(QtCore.Qt.RichText) + lbl_info.setWordWrap(True) + + lbl_question = QtWidgets.QLabel(msg_question, self) + lbl_question.setTextFormat(QtCore.Qt.RichText) + lbl_question.setWordWrap(True) + + lbl_stopped = QtWidgets.QLabel(msg_stopped, self) + lbl_stopped.setTextFormat(QtCore.Qt.RichText) + lbl_stopped.setWordWrap(True) + + lbl_rest_time = QtWidgets.QLabel(self) + lbl_rest_time.setTextFormat(QtCore.Qt.RichText) + lbl_rest_time.setWordWrap(True) + lbl_rest_time.setAlignment(QtCore.Qt.AlignCenter) + + form = QtWidgets.QFormLayout() + form.setContentsMargins(10, 15, 10, 5) + + form.addRow(lbl_info) + form.addRow(lbl_question) + form.addRow(lbl_stopped) + form.addRow(lbl_rest_time) + + btn_stop = QtWidgets.QPushButton("Stop timer", self) + btn_stop.setToolTip("Stop's All timers") + + btn_continue = QtWidgets.QPushButton("Continue", self) + btn_continue.setToolTip("Timer won't stop") + + btn_close = QtWidgets.QPushButton("Close", self) + btn_close.setToolTip("Close window") + + btn_restart = QtWidgets.QPushButton("Start timers", self) + btn_restart.setToolTip("Timer will be started again") + + group_layout = QtWidgets.QHBoxLayout() + group_layout.addStretch(1) + group_layout.addWidget(btn_continue) + group_layout.addWidget(btn_stop) + group_layout.addWidget(btn_restart) + group_layout.addWidget(btn_close) + + layout = QtWidgets.QVBoxLayout(self) + layout.addLayout(form) + layout.addLayout(group_layout) + + count_timer = QtCore.QTimer() + count_timer.setInterval(1000) + + btn_stop.clicked.connect(self._on_stop_clicked) + btn_continue.clicked.connect(self._on_continue_clicked) + btn_close.clicked.connect(self._close_widget) + btn_restart.clicked.connect(self._on_restart_clicked) + count_timer.timeout.connect(self._on_count_timeout) + + self.lbl_info = lbl_info + self.lbl_question = lbl_question + self.lbl_stopped = lbl_stopped + self.lbl_rest_time = lbl_rest_time + + self.btn_stop = btn_stop + self.btn_continue = btn_continue + self.btn_close = btn_close + self.btn_restart = btn_restart + + self._count_timer = count_timer self.resize(self.SIZE_W, self.SIZE_H) self.setMinimumSize(QtCore.QSize(self.SIZE_W, self.SIZE_H)) self.setMaximumSize(QtCore.QSize(self.SIZE_W+100, self.SIZE_H+100)) self.setStyleSheet(style.load_stylesheet()) - self.setLayout(self._main()) - self.refresh_context() - self.setWindowTitle('Pype - Stop timers') + def set_countdown_start(self, countdown): + self._countdown_start = countdown + if not self.is_showed(): + self.reset_countdown() - def _main(self): - self.main = QtWidgets.QVBoxLayout() - self.main.setObjectName('main') + def reset_countdown(self): + self._countdown = self._countdown_start + self._update_countdown_label() - self.form = QtWidgets.QFormLayout() - self.form.setContentsMargins(10, 15, 10, 5) - self.form.setObjectName('form') + def is_showed(self): + return self._is_showed - msg_info = 'You didn\'t work for a long time.' - msg_question = 'Would you like to stop Timers?' - msg_stopped = ( - 'Your Timers were stopped. Do you want to start them again?' - ) + def set_timer_stopped(self): + self._timer_stopped = True + self._refresh_context() - self.lbl_info = QtWidgets.QLabel(msg_info) - self.lbl_info.setFont(self.font) - self.lbl_info.setTextFormat(QtCore.Qt.RichText) - self.lbl_info.setObjectName("lbl_info") - self.lbl_info.setWordWrap(True) + def _update_countdown_label(self): + self.lbl_rest_time.setText(str(self._countdown)) - self.lbl_question = QtWidgets.QLabel(msg_question) - self.lbl_question.setFont(self.font) - self.lbl_question.setTextFormat(QtCore.Qt.RichText) - self.lbl_question.setObjectName("lbl_question") - self.lbl_question.setWordWrap(True) + def _on_count_timeout(self): + if self._timer_stopped or not self._is_showed: + self._count_timer.stop() + return - self.lbl_stopped = QtWidgets.QLabel(msg_stopped) - self.lbl_stopped.setFont(self.font) - self.lbl_stopped.setTextFormat(QtCore.Qt.RichText) - self.lbl_stopped.setObjectName("lbl_stopped") - self.lbl_stopped.setWordWrap(True) - - self.lbl_rest_time = QtWidgets.QLabel("") - self.lbl_rest_time.setFont(self.font) - self.lbl_rest_time.setTextFormat(QtCore.Qt.RichText) - self.lbl_rest_time.setObjectName("lbl_rest_time") - self.lbl_rest_time.setWordWrap(True) - self.lbl_rest_time.setAlignment(QtCore.Qt.AlignCenter) - - self.form.addRow(self.lbl_info) - self.form.addRow(self.lbl_question) - self.form.addRow(self.lbl_stopped) - self.form.addRow(self.lbl_rest_time) - - self.group_btn = QtWidgets.QHBoxLayout() - self.group_btn.addStretch(1) - self.group_btn.setObjectName("group_btn") - - self.btn_stop = QtWidgets.QPushButton("Stop timer") - self.btn_stop.setToolTip('Stop\'s All timers') - self.btn_stop.clicked.connect(self.stop_timer) - - self.btn_continue = QtWidgets.QPushButton("Continue") - self.btn_continue.setToolTip('Timer won\'t stop') - self.btn_continue.clicked.connect(self.continue_timer) - - self.btn_close = QtWidgets.QPushButton("Close") - self.btn_close.setToolTip('Close window') - self.btn_close.clicked.connect(self.close_widget) - - self.btn_restart = QtWidgets.QPushButton("Start timers") - self.btn_restart.setToolTip('Timer will be started again') - self.btn_restart.clicked.connect(self.restart_timer) - - self.group_btn.addWidget(self.btn_continue) - self.group_btn.addWidget(self.btn_stop) - self.group_btn.addWidget(self.btn_restart) - self.group_btn.addWidget(self.btn_close) - - self.main.addLayout(self.form) - self.main.addLayout(self.group_btn) - - return self.main - - def refresh_context(self): - self.lbl_question.setVisible(self.bool_not_stopped) - self.lbl_rest_time.setVisible(self.bool_not_stopped) - self.lbl_stopped.setVisible(not self.bool_not_stopped) - - self.btn_continue.setVisible(self.bool_not_stopped) - self.btn_stop.setVisible(self.bool_not_stopped) - self.btn_restart.setVisible(not self.bool_not_stopped) - self.btn_close.setVisible(not self.bool_not_stopped) - - def change_count_widget(self, time): - str_time = str(time) - self.lbl_rest_time.setText(str_time) - - def stop_timer(self): - self.module.stop_timers() - self.close_widget() - - def restart_timer(self): - self.module.restart_timers() - self.close_widget() - - def continue_timer(self): - self.close_widget() - - def closeEvent(self, event): - event.ignore() - if self.bool_not_stopped is True: - self.continue_timer() + if self._countdown <= 0: + self._stop_timers() + self.set_timer_stopped() else: - self.close_widget() + self._countdown -= 1 + self._update_countdown_label() - def close_widget(self): - self.bool_is_showed = False - self.bool_not_stopped = True - self.refresh_context() + def _refresh_context(self): + self.lbl_question.setVisible(not self._timer_stopped) + self.lbl_rest_time.setVisible(not self._timer_stopped) + self.lbl_stopped.setVisible(self._timer_stopped) + + self.btn_continue.setVisible(not self._timer_stopped) + self.btn_stop.setVisible(not self._timer_stopped) + self.btn_restart.setVisible(self._timer_stopped) + self.btn_close.setVisible(self._timer_stopped) + + def _stop_timers(self): + self.module.stop_timers() + + def _on_stop_clicked(self): + self._stop_timers() + self._close_widget() + + def _on_restart_clicked(self): + self.module.restart_timers() + self._close_widget() + + def _on_continue_clicked(self): + self._close_widget() + + def _close_widget(self): + self._is_showed = False + self._timer_stopped = False + self._refresh_context() self.hide() def showEvent(self, event): - self.bool_is_showed = True + if not self._is_showed: + self._is_showed = True + self._refresh_context() + + if not self._count_timer.isActive(): + self._count_timer.start() + super(WidgetUserIdle, self).showEvent(event) + + def closeEvent(self, event): + event.ignore() + if self._timer_stopped: + self._close_widget() + else: + self._on_continue_clicked() class SignalHandler(QtCore.QObject): signal_show_message = QtCore.Signal() - signal_change_label = QtCore.Signal() signal_stop_timers = QtCore.Signal() def __init__(self, module): super(SignalHandler, self).__init__() self.module = module self.signal_show_message.connect(module.show_message) - self.signal_change_label.connect(module.change_label) self.signal_stop_timers.connect(module.stop_timers)