mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge pull request #333 from pypeclub/feature/idle_manager_without_qt
Feature/idle manager without qt
This commit is contained in:
commit
fe6ea0e1ad
3 changed files with 94 additions and 101 deletions
|
|
@ -1,26 +1,25 @@
|
|||
import time
|
||||
import collections
|
||||
from Qt import QtCore
|
||||
import threading
|
||||
from pynput import mouse, keyboard
|
||||
from pype.api import Logger
|
||||
|
||||
|
||||
class IdleManager(QtCore.QThread):
|
||||
class IdleManager(threading.Thread):
|
||||
""" 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 = collections.defaultdict(list)
|
||||
time_callbacks = collections.defaultdict(list)
|
||||
idle_time = 0
|
||||
signal_reset_timer = QtCore.Signal()
|
||||
|
||||
def __init__(self):
|
||||
super(IdleManager, self).__init__()
|
||||
self.log = Logger().get_logger(self.__class__.__name__)
|
||||
self.signal_reset_timer.connect(self._reset_time)
|
||||
self.qaction = None
|
||||
self.failed_icon = None
|
||||
self._is_running = False
|
||||
self.threads = []
|
||||
|
||||
def set_qaction(self, qaction, failed_icon):
|
||||
self.qaction = qaction
|
||||
|
|
@ -32,18 +31,18 @@ class IdleManager(QtCore.QThread):
|
|||
def tray_exit(self):
|
||||
self.stop()
|
||||
try:
|
||||
self.time_signals = {}
|
||||
self.time_callbacks = {}
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def add_time_signal(self, emit_time, signal):
|
||||
""" If any module want to use IdleManager, need to use add_time_signal
|
||||
:param emit_time: time when signal will be emitted
|
||||
:type emit_time: int
|
||||
:param signal: signal that will be emitted (without objects)
|
||||
:type signal: QtCore.Signal
|
||||
def add_time_callback(self, emit_time, callback):
|
||||
"""If any module want to use IdleManager, need to use this method.
|
||||
|
||||
Args:
|
||||
emit_time(int): Time when callback will be triggered.
|
||||
callback(func): Callback that will be triggered.
|
||||
"""
|
||||
self.time_signals[emit_time].append(signal)
|
||||
self.time_callbacks[emit_time].append(callback)
|
||||
|
||||
@property
|
||||
def is_running(self):
|
||||
|
|
@ -58,17 +57,26 @@ class IdleManager(QtCore.QThread):
|
|||
def run(self):
|
||||
self.log.info('IdleManager has started')
|
||||
self._is_running = True
|
||||
thread_mouse = MouseThread(self.signal_reset_timer)
|
||||
thread_mouse = MouseThread(self._reset_time)
|
||||
thread_mouse.start()
|
||||
thread_keyboard = KeyboardThread(self.signal_reset_timer)
|
||||
thread_keyboard = KeyboardThread(self._reset_time)
|
||||
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
|
||||
if self.idle_time in self.time_signals:
|
||||
for signal in self.time_signals[self.idle_time]:
|
||||
signal.emit()
|
||||
time.sleep(1)
|
||||
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
'Idle Manager service has failed', exc_info=True
|
||||
|
|
@ -79,16 +87,14 @@ class IdleManager(QtCore.QThread):
|
|||
|
||||
# Threads don't have their attrs when Qt application already finished
|
||||
try:
|
||||
thread_mouse.signal_stop.emit()
|
||||
thread_mouse.terminate()
|
||||
thread_mouse.wait()
|
||||
thread_mouse.stop()
|
||||
thread_mouse.join()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
thread_keyboard.signal_stop.emit()
|
||||
thread_keyboard.terminate()
|
||||
thread_keyboard.wait()
|
||||
thread_keyboard.stop()
|
||||
thread_keyboard.join()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
|
@ -96,49 +102,24 @@ class IdleManager(QtCore.QThread):
|
|||
self.log.info('IdleManager has stopped')
|
||||
|
||||
|
||||
class MouseThread(QtCore.QThread):
|
||||
"""Listens user's mouse movement
|
||||
"""
|
||||
signal_stop = QtCore.Signal()
|
||||
class MouseThread(mouse.Listener):
|
||||
"""Listens user's mouse movement."""
|
||||
|
||||
def __init__(self, signal):
|
||||
super(MouseThread, self).__init__()
|
||||
self.signal_stop.connect(self.stop)
|
||||
self.m_listener = None
|
||||
|
||||
self.signal_reset_timer = signal
|
||||
|
||||
def stop(self):
|
||||
if self.m_listener is not None:
|
||||
self.m_listener.stop()
|
||||
def __init__(self, callback):
|
||||
super(MouseThread, self).__init__(on_move=self.on_move)
|
||||
self.callback = callback
|
||||
|
||||
def on_move(self, posx, posy):
|
||||
self.signal_reset_timer.emit()
|
||||
|
||||
def run(self):
|
||||
self.m_listener = mouse.Listener(on_move=self.on_move)
|
||||
self.m_listener.start()
|
||||
self.callback()
|
||||
|
||||
|
||||
class KeyboardThread(QtCore.QThread):
|
||||
"""Listens user's keyboard input
|
||||
"""
|
||||
signal_stop = QtCore.Signal()
|
||||
class KeyboardThread(keyboard.Listener):
|
||||
"""Listens user's keyboard input."""
|
||||
|
||||
def __init__(self, signal):
|
||||
super(KeyboardThread, self).__init__()
|
||||
self.signal_stop.connect(self.stop)
|
||||
self.k_listener = None
|
||||
def __init__(self, callback):
|
||||
super(KeyboardThread, self).__init__(on_press=self.on_press)
|
||||
|
||||
self.signal_reset_timer = signal
|
||||
|
||||
def stop(self):
|
||||
if self.k_listener is not None:
|
||||
self.k_listener.stop()
|
||||
self.callback = callback
|
||||
|
||||
def on_press(self, key):
|
||||
self.signal_reset_timer.emit()
|
||||
|
||||
def run(self):
|
||||
self.k_listener = keyboard.Listener(on_press=self.on_press)
|
||||
self.k_listener.start()
|
||||
self.callback()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
from Qt import QtCore
|
||||
from .widget_user_idle import WidgetUserIdle
|
||||
from .widget_user_idle import WidgetUserIdle, SignalHandler
|
||||
from pype.api import Logger, config
|
||||
|
||||
|
||||
|
|
@ -31,7 +30,10 @@ class TimersManager(metaclass=Singleton):
|
|||
self.log = Logger().get_logger(self.__class__.__name__)
|
||||
self.tray_widget = tray_widget
|
||||
self.main_widget = main_widget
|
||||
self.widget_user_idle = WidgetUserIdle(self)
|
||||
|
||||
self.idle_man = None
|
||||
self.signal_handler = None
|
||||
self.widget_user_idle = WidgetUserIdle(self, tray_widget)
|
||||
|
||||
def set_signal_times(self):
|
||||
try:
|
||||
|
|
@ -114,49 +116,59 @@ class TimersManager(metaclass=Singleton):
|
|||
:param modules: All imported modules from TrayManager
|
||||
:type modules: dict
|
||||
"""
|
||||
self.s_handler = SignalHandler(self)
|
||||
|
||||
if 'IdleManager' in modules:
|
||||
self.signal_handler = SignalHandler(self)
|
||||
if self.set_signal_times() is True:
|
||||
self.register_to_idle_manager(modules['IdleManager'])
|
||||
|
||||
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 register_to_idle_manager(self, man_obj):
|
||||
self.idle_man = man_obj
|
||||
|
||||
# Time when message is shown
|
||||
self.idle_man.add_time_callback(
|
||||
self.time_show_message,
|
||||
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
|
||||
self.time_show_message - 1, self.time_stop_timer
|
||||
)
|
||||
for num in show_to_stop_range:
|
||||
self.idle_man.add_time_signal(
|
||||
num,
|
||||
self.s_handler.signal_change_label
|
||||
self.idle_man.add_time_callback(
|
||||
num, 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:
|
||||
self.idle_man.add_time_signal(
|
||||
num,
|
||||
self.s_handler.signal_change_label
|
||||
self.idle_man.add_time_callback(
|
||||
num, lambda: self.time_callback(1)
|
||||
)
|
||||
# Time when message is shown
|
||||
self.idle_man.add_time_signal(
|
||||
self.time_show_message,
|
||||
self.s_handler.signal_show_message
|
||||
)
|
||||
|
||||
# Time when timers are stopped
|
||||
self.idle_man.add_time_signal(
|
||||
self.idle_man.add_time_callback(
|
||||
self.time_stop_timer,
|
||||
self.s_handler.signal_stop_timers
|
||||
lambda: self.time_callback(2)
|
||||
)
|
||||
|
||||
def change_label(self):
|
||||
if self.is_running is False:
|
||||
return
|
||||
if self.widget_user_idle.bool_is_showed is False:
|
||||
return
|
||||
if not hasattr(self, 'idle_man'):
|
||||
if not self.idle_man or self.widget_user_idle.bool_is_showed is False:
|
||||
return
|
||||
|
||||
if self.idle_man.idle_time > self.time_show_message:
|
||||
|
|
@ -174,14 +186,3 @@ class TimersManager(metaclass=Singleton):
|
|||
return
|
||||
if self.widget_user_idle.bool_is_showed is False:
|
||||
self.widget_user_idle.show()
|
||||
|
||||
|
||||
class SignalHandler(QtCore.QObject):
|
||||
signal_show_message = QtCore.Signal()
|
||||
signal_change_label = QtCore.Signal()
|
||||
signal_stop_timers = QtCore.Signal()
|
||||
def __init__(self, cls):
|
||||
super().__init__()
|
||||
self.signal_show_message.connect(cls.show_message)
|
||||
self.signal_change_label.connect(cls.change_label)
|
||||
self.signal_stop_timers.connect(cls.stop_timers)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from pype.api import Logger
|
||||
from avalon import style
|
||||
from Qt import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
|
@ -8,18 +7,18 @@ class WidgetUserIdle(QtWidgets.QWidget):
|
|||
SIZE_W = 300
|
||||
SIZE_H = 160
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self, module, tray_widget):
|
||||
|
||||
super(WidgetUserIdle, self).__init__()
|
||||
|
||||
self.bool_is_showed = False
|
||||
self.bool_not_stopped = True
|
||||
|
||||
self.parent_widget = parent
|
||||
self.setWindowIcon(parent.tray_widget.icon)
|
||||
self.module = module
|
||||
self.setWindowIcon(tray_widget.icon)
|
||||
self.setWindowFlags(
|
||||
QtCore.Qt.WindowCloseButtonHint |
|
||||
QtCore.Qt.WindowMinimizeButtonHint
|
||||
QtCore.Qt.WindowCloseButtonHint
|
||||
| QtCore.Qt.WindowMinimizeButtonHint
|
||||
)
|
||||
|
||||
self._translate = QtCore.QCoreApplication.translate
|
||||
|
|
@ -129,11 +128,11 @@ class WidgetUserIdle(QtWidgets.QWidget):
|
|||
self.lbl_rest_time.setText(str_time)
|
||||
|
||||
def stop_timer(self):
|
||||
self.parent_widget.stop_timers()
|
||||
self.module.stop_timers()
|
||||
self.close_widget()
|
||||
|
||||
def restart_timer(self):
|
||||
self.parent_widget.restart_timers()
|
||||
self.module.restart_timers()
|
||||
self.close_widget()
|
||||
|
||||
def continue_timer(self):
|
||||
|
|
@ -154,3 +153,15 @@ class WidgetUserIdle(QtWidgets.QWidget):
|
|||
|
||||
def showEvent(self, event):
|
||||
self.bool_is_showed = True
|
||||
|
||||
|
||||
class SignalHandler(QtCore.QObject):
|
||||
signal_show_message = QtCore.Signal()
|
||||
signal_change_label = QtCore.Signal()
|
||||
signal_stop_timers = QtCore.Signal()
|
||||
|
||||
def __init__(self, cls):
|
||||
super().__init__()
|
||||
self.signal_show_message.connect(cls.show_message)
|
||||
self.signal_change_label.connect(cls.change_label)
|
||||
self.signal_stop_timers.connect(cls.stop_timers)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue