DeepFaceLive/xlib/qt/widgets/QXMainApplication.py
2021-12-09 16:49:55 +04:00

170 lines
5.6 KiB
Python

from pathlib import Path
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from ..core.QXTimer import QXTimer
from ...db import KeyValueDB
from .forward_declarations import forward_declarations
class QXMainApplication(QApplication):
inst : 'QXMainApplication' = None
@staticmethod
def get_singleton() -> 'QXMainApplication':
if QXMainApplication.inst is None:
raise Exception('QXMainApplication must be instantiated')
return QXMainApplication.inst
def __init__(self, app_name=None, settings_dirpath : Path = None):
"""
base class for MainApplication
QXMainApplication.inst - singleton instance
settings_dirpath(None) where the data will be saved
"""
super().__init__([])
if QXMainApplication.inst is not None:
raise Exception('Only one singleton QXMainApplication is allowed')
QXMainApplication.inst = self
self._settings_dirpath = settings_dirpath
if settings_dirpath is not None:
self._app_data_path = settings_dirpath / 'app.dat'
else:
self._app_data_path = None
self._hierarchy_name_count = {}
self._app_db = KeyValueDB(self._app_data_path)
if app_name is not None:
self.setApplicationName(app_name)
self.setStyle('Fusion')
text_color = QColor(200,200,200)
self.setStyleSheet(f"""
QRadioButton::disabled {{
color: gray;
}}
""")
pal = QPalette()
pal.setColor(QPalette.ColorRole.Window, QColor(56, 56, 56))
pal.setColor(QPalette.ColorRole.Base, QColor(25, 25, 25))
pal.setColor(QPalette.ColorRole.AlternateBase, QColor(56, 56, 56))
pal.setColor(QPalette.ColorRole.ToolTipBase, text_color )
pal.setColor(QPalette.ColorRole.ToolTipText, text_color )
pal.setColor(QPalette.ColorRole.Text, text_color )
pal.setColor(QPalette.ColorRole.Button, QColor(56, 56, 56))
pal.setColor(QPalette.ColorRole.ButtonText, Qt.GlobalColor.white)
pal.setColor(QPalette.ColorRole.PlaceholderText, Qt.GlobalColor.darkGray)
pal.setColor(QPalette.ColorGroup.Active, QPalette.ColorRole.ButtonText, text_color)
pal.setColor(QPalette.ColorGroup.Inactive, QPalette.ColorRole.ButtonText, text_color)
pal.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, Qt.GlobalColor.gray)
pal.setColor(QPalette.ColorRole.WindowText, text_color )
pal.setColor(QPalette.ColorGroup.Active, QPalette.ColorRole.WindowText, text_color)
pal.setColor(QPalette.ColorGroup.Inactive, QPalette.ColorRole.WindowText, text_color)
pal.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.WindowText, Qt.GlobalColor.gray)
pal.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Text, Qt.GlobalColor.gray)
pal.setColor(QPalette.ColorRole.BrightText, Qt.GlobalColor.red)
pal.setColor(QPalette.ColorRole.Link, QColor(42, 130, 218))
pal.setColor(QPalette.ColorRole.Highlight, QColor(42, 130, 218))
pal.setColor(QPalette.ColorRole.HighlightedText, Qt.GlobalColor.black)
self.setPalette(pal)
self._reinitialize = False
self._timer = QXTimer(interval=10, timeout=self._on_10ms_timer, start=True)
def _on_10ms_timer(self):
self._app_db.process_messages()
if self._reinitialize:
self._reinitialize = False
self.on_reinitialize()
def register_QXWidget(self, widget) -> str:
"""
registers QXWidget, checks validity, returns an unique name
"""
hierarchy = []
iter_widget = widget
while True:
hierarchy.insert(0, iter_widget.__class__.__name__)
iter_parent_widget = iter_widget.parentWidget()
if iter_parent_widget is None:
break
iter_widget = iter_parent_widget
if not isinstance(iter_widget, forward_declarations.QXWindow):
raise Exception('Top widget must be a class of QXWindow')
if len(hierarchy) == 1:
# top level widgets(Windows) has no numerification
return hierarchy[0]
else:
hierarchy_name = '.'.join(hierarchy)
num = self._hierarchy_name_count.get(hierarchy_name, -1)
num = self._hierarchy_name_count[hierarchy_name] = num + 1
return f'{hierarchy_name}:{num}'
def clear_app_data(self):
"""
clear app data and reinitialize()
"""
self._app_db.clear()
self.reinitialize()
def get_app_data(self, key, default_value=None):
"""
returns picklable data by picklable key stored in app db
returns default_value if no data
"""
return self._app_db.get_value(key, default_value=default_value)
def set_app_data(self, key, value):
"""
set picklable data by picklable key stored to app db
"""
self._app_db.set_value(key, value )
def run(self):
"""
run the app
"""
self.exec()
self._app_db.finish_pending_jobs()
def reinitialize(self):
"""
start reinitialization of app.
"""
self._reinitialize = True
def on_reinitialize(self):
raise NotImplementedError()
def get_language(self) -> str:
return self.get_app_data('__app_language', 'en-US')
def set_language(self, lang : str) -> str:
"""
lang xx-YY
example: en-US ru-RU
"""
return self.set_app_data('__app_language', lang)