qt refactoring

This commit is contained in:
iperov 2021-12-07 17:51:23 +04:00
commit 9ef7be4f3a
59 changed files with 632 additions and 890 deletions

View file

@ -2,13 +2,10 @@ from pathlib import Path
from typing import List
from localization import L, Localization
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from resources.gfx import QXImageDB
from xlib import os as lib_os
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.qt.widgets.QXLabel import QXLabel
from . import backend
@ -27,7 +24,7 @@ from .ui.widgets.QBCMergedFrameViewer import QBCMergedFrameViewer
from .ui.widgets.QBCFrameViewer import QBCFrameViewer
class QLiveSwap(lib_qt.QXWidget):
class QLiveSwap(qtx.QXWidget):
def __init__(self, userdata_path : Path,
settings_dirpath : Path):
super().__init__()
@ -39,7 +36,6 @@ class QLiveSwap(lib_qt.QXWidget):
output_sequence_path.mkdir(parents=True, exist_ok=True)
# Construct backend config
backend_db = self.backend_db = backend.BackendDB( settings_dirpath / 'states.dat' )
backed_weak_heap = self.backed_weak_heap = backend.BackendWeakHeap(size_mb=1024)
reemit_frame_signal = self.reemit_frame_signal = backend.BackendSignal()
@ -79,32 +75,24 @@ class QLiveSwap(lib_qt.QXWidget):
self.q_ds_fc_viewer = QBCFaceSwapViewer(backed_weak_heap, face_swapper_bc_out, preview_width=256)
self.q_ds_merged_frame_viewer = QBCMergedFrameViewer(backed_weak_heap, face_merger_bc_out)
q_nodes = lib_qt.QXWidget(size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed),
layout=lib_qt.QXHBoxLayout([
lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_file_source, self.q_camera_source], spacing=5), fixed_width=256 ),
lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_face_detector, self.q_face_aligner,], spacing=5), fixed_width=256),
lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_face_marker, self.q_face_swapper], spacing=5), fixed_width=256),
lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_frame_adjuster, self.q_face_merger, self.q_stream_output, ], spacing=5), fixed_width=256),
], spacing=5))
q_nodes = qtx.QXWidgetHBox([ qtx.QXWidgetVBox([self.q_file_source, self.q_camera_source], spacing=5, fixed_width=256),
qtx.QXWidgetVBox([self.q_face_detector, self.q_face_aligner,], spacing=5, fixed_width=256),
qtx.QXWidgetVBox([self.q_face_marker, self.q_face_swapper], spacing=5, fixed_width=256),
qtx.QXWidgetVBox([self.q_frame_adjuster, self.q_face_merger, self.q_stream_output], spacing=5, fixed_width=256),
], spacing=5, size_policy=('fixed', 'fixed') )
q_view_nodes = lib_qt.QXWidget(size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed),
layout=lib_qt.QXHBoxLayout([
(lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_ds_frame_viewer]), fixed_width=256 ), Qt.AlignmentFlag.AlignTop),
(lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_ds_fa_viewer]), fixed_width=256 ), Qt.AlignmentFlag.AlignTop),
(lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_ds_fc_viewer]), fixed_width=256 ), Qt.AlignmentFlag.AlignTop),
(lib_qt.QXWidget(layout=lib_qt.QXVBoxLayout([self.q_ds_merged_frame_viewer]), fixed_width=256 ), Qt.AlignmentFlag.AlignTop),
], spacing=5))
q_view_nodes = qtx.QXWidgetHBox([ (qtx.QXWidgetVBox([self.q_ds_frame_viewer], fixed_width=256), qtx.AlignTop),
(qtx.QXWidgetVBox([self.q_ds_fa_viewer], fixed_width=256), qtx.AlignTop),
(qtx.QXWidgetVBox([self.q_ds_fc_viewer], fixed_width=256), qtx.AlignTop),
(qtx.QXWidgetVBox([self.q_ds_merged_frame_viewer], fixed_width=256), qtx.AlignTop),
], spacing=5, size_policy=('fixed', 'fixed') )
self.setLayout(lib_qt.QXVBoxLayout(
[ (lib_qt.QXWidget( layout=lib_qt.QXVBoxLayout([
(q_nodes, Qt.AlignmentFlag.AlignTop),
(q_view_nodes, Qt.AlignmentFlag.AlignHCenter),
], spacing=5)),
Qt.AlignmentFlag.AlignCenter),
self.setLayout(qtx.QXVBoxLayout(
[ (qtx.QXWidgetVBox([(q_nodes, qtx.AlignTop),
(q_view_nodes, qtx.AlignHCenter), ], spacing=5), qtx.AlignCenter),
]))
self._timer = lib_qt.QXTimer(interval=5, timeout=self._on_timer_5ms, start=True)
self._timer = qtx.QXTimer(interval=5, timeout=self._on_timer_5ms, start=True)
def _process_messages(self):
self.backend_db.process_messages()
@ -138,64 +126,58 @@ class QLiveSwap(lib_qt.QXWidget):
self.q_ds_frame_viewer.clear()
self.q_ds_fa_viewer.clear()
class QDFLAppWindow(lib_qt.QXWindow):
class QDFLAppWindow(qtx.QXWindow):
def __init__(self, userdata_path, settings_dirpath):
super().__init__(save_load_state=True, size_policy=(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum) )
super().__init__(save_load_state=True, size_policy=('minimum', 'minimum') )
self._userdata_path = userdata_path
self._settings_dirpath = settings_dirpath
menu_bar = lib_qt.QXMenuBar( font=QXFontDB.get_default_font(size=10), size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.MinimumExpanding) )
menu_bar = qtx.QXMenuBar( font=QXFontDB.get_default_font(size=10), size_policy=('fixed', 'minimumexpanding') )
menu_file = menu_bar.addMenu( L('@QDFLAppWindow.file') )
menu_language = menu_bar.addMenu( L('@QDFLAppWindow.language') )
menu_file_action_reinitialize = menu_file.addAction( L('@QDFLAppWindow.reinitialize') )
menu_file_action_reinitialize.triggered.connect(lambda: lib_qt.QXMainApplication.get_singleton().reinitialize() )
menu_file_action_reinitialize.triggered.connect(lambda: qtx.QXMainApplication.get_singleton().reinitialize() )
menu_file_action_reset_settings = menu_file.addAction( L('@QDFLAppWindow.reset_modules_settings') )
menu_file_action_reset_settings.triggered.connect(self._on_reset_modules_settings)
menu_file_action_quit = menu_file.addAction( L('@QDFLAppWindow.quit') )
menu_file_action_quit.triggered.connect(lambda: lib_qt.QXMainApplication.quit() )
menu_file_action_quit.triggered.connect(lambda: qtx.QXMainApplication.quit() )
menu_language_action_english = menu_language.addAction('English' )
menu_language_action_english.triggered.connect(lambda: (lib_qt.QXMainApplication.get_singleton().set_language('en-US'), lib_qt.QXMainApplication.get_singleton().reinitialize()) )
menu_language_action_english.triggered.connect(lambda: (qtx.QXMainApplication.get_singleton().set_language('en-US'), qtx.QXMainApplication.get_singleton().reinitialize()) )
menu_language_action_russian = menu_language.addAction('Русский')
menu_language_action_russian.triggered.connect(lambda: (lib_qt.QXMainApplication.get_singleton().set_language('ru-RU'), lib_qt.QXMainApplication.get_singleton().reinitialize()) )
menu_language_action_russian.triggered.connect(lambda: (qtx.QXMainApplication.get_singleton().set_language('ru-RU'), qtx.QXMainApplication.get_singleton().reinitialize()) )
menu_language_action_chinesse = menu_language.addAction('汉语')
menu_language_action_chinesse.triggered.connect(lambda: (lib_qt.QXMainApplication.get_singleton().set_language('zh-CN'), lib_qt.QXMainApplication.get_singleton().reinitialize()) )
menu_language_action_chinesse.triggered.connect(lambda: (qtx.QXMainApplication.get_singleton().set_language('zh-CN'), qtx.QXMainApplication.get_singleton().reinitialize()) )
menu_help = menu_bar.addMenu( L('@QDFLAppWindow.help') )
menu_help_action_github = menu_help.addAction( L('@QDFLAppWindow.visit_github_page') )
menu_help_action_github.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://github.com/iperov/DeepFaceLive' )))
menu_help_action_github.triggered.connect(lambda: qtx.QDesktopServices.openUrl(QUrl('https://github.com/iperov/DeepFaceLive' )))
self.q_live_swap = None
self.q_live_swap_container = lib_qt.QXWidget()
self.q_live_swap_container = qtx.QXWidget()
self.content_l = lib_qt.QXVBoxLayout()
self.content_l = qtx.QXVBoxLayout()
cb_process_priority = self._cb_process_priority = lib_qt.QXSaveableComboBox(
cb_process_priority = self._cb_process_priority = qtx.QXSaveableComboBox(
db_key = '_QDFLAppWindow_process_priority',
choices=[lib_os.ProcessPriority.NORMAL, lib_os.ProcessPriority.IDLE],
default_choice=lib_os.ProcessPriority.NORMAL,
choices_names=[ L('@QDFLAppWindow.process_priority.normal'), L('@QDFLAppWindow.process_priority.lowest') ],
on_choice_selected=self._on_cb_process_priority_choice)
menu_bar_tail = lib_qt.QXFrame(layout=lib_qt.QXHBoxLayout([
10,
QXLabel(text=L('@QDFLAppWindow.process_priority')),
4,
cb_process_priority,
]),
size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
menu_bar_tail = qtx.QXFrameHBox([10, QXLabel(text=L('@QDFLAppWindow.process_priority')), 4, cb_process_priority], size_policy=('fixed', 'fixed'))
self.setLayout( lib_qt.QXVBoxLayout([ lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([menu_bar, menu_bar_tail, lib_qt.QXFrame() ]), size_policy=(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Fixed)),
5,
lib_qt.QXWidget(layout=self.content_l)
] ))
self.setLayout( qtx.QXVBoxLayout([ qtx.QXWidgetHBox([menu_bar, menu_bar_tail, qtx.QXFrame() ], size_policy=('minimumexpanding', 'fixed')),
5,
qtx.QXWidget(layout=self.content_l)
]))
self.call_on_closeEvent(self._on_closeEvent)
@ -206,13 +188,13 @@ class QDFLAppWindow(lib_qt.QXWindow):
def _on_reset_modules_settings(self):
if self.q_live_swap is not None:
self.q_live_swap.clear_backend_db()
lib_qt.QXMainApplication.get_singleton().reinitialize()
qtx.QXMainApplication.get_singleton().reinitialize()
def _on_cb_process_priority_choice(self, prio : lib_os.ProcessPriority, _):
lib_os.set_process_priority(prio)
if self.q_live_swap is not None:
lib_qt.QXMainApplication.get_singleton().reinitialize()
qtx.QXMainApplication.get_singleton().reinitialize()
def finalize(self):
self.q_live_swap.finalize()
@ -220,17 +202,12 @@ class QDFLAppWindow(lib_qt.QXWindow):
def _on_closeEvent(self):
self.finalize()
class QSplashWindow(lib_qt.QXWindow):
def __init__(self, next_window=None):
super().__init__()
self.setWindowFlags(Qt.WindowType.SplashScreen)
class QDeepFaceLiveSplashWindow(qtx.QXSplashWindow):
def __init__(self):
super().__init__(layout=qtx.QXVBoxLayout([ (qtx.QXLabel(image=QXImageDB.splash_deepfacelive()), qtx.AlignCenter)
], contents_margins=20))
logo_deepfacelive = lib_qt.QXLabel(image=QXImageDB.splash_deepfacelive())
self.setLayout( lib_qt.QXVBoxLayout([
( lib_qt.QXHBoxLayout([logo_deepfacelive]), Qt.AlignmentFlag.AlignCenter),
], spacing=0, contents_margins=20))
class DeepFaceLiveApp(lib_qt.QXMainApplication):
class DeepFaceLiveApp(qtx.QXMainApplication):
def __init__(self, userdata_path):
self.userdata_path = userdata_path
settings_dirpath = self.settings_dirpath = userdata_path / 'settings'
@ -241,13 +218,13 @@ class DeepFaceLiveApp(lib_qt.QXMainApplication):
self.setFont( QXFontDB.get_default_font() )
self.setWindowIcon( QXImageDB.app_icon().as_QIcon() )
splash_wnd = self.splash_wnd = QSplashWindow()
splash_wnd = self.splash_wnd = QDeepFaceLiveSplashWindow()
splash_wnd.show()
splash_wnd.center_on_screen()
self._dfl_wnd = None
self.initialize()
self._t = lib_qt.QXTimer(interval=1666, timeout=self._on_splash_wnd_expired, single_shot=True, start=True)
self._t = qtx.QXTimer(interval=1666, timeout=self._on_splash_wnd_expired, single_shot=True, start=True)
def on_reinitialize(self):
self.finalize()
@ -278,32 +255,3 @@ class DeepFaceLiveApp(lib_qt.QXMainApplication):
self.splash_wnd.hide()
self.splash_wnd.deleteLater()
self.splash_wnd = None
#import gc
#gc.collect()
#gc.collect()
# def _reinitialize(self, init_new=True):
# if self.q_live_swap is not None:
# self.content_l.removeWidget(self.q_live_swap)
# self.q_live_swap.finalize()
# self.q_live_swap.deleteLater()
# self.q_live_swap = None
# import gc
# gc.collect()
# gc.collect()
# LStrings.initialize()
# if init_new:
# self.q_live_swap = QLiveSwap(userdata_path=self._userdata_path, settings_dirpath=self._settings_dirpath)
# self.q_live_swap.initialize()
# self.content_l.addWidget(self.q_live_swap)
#self._reinitialize(init_new=False)

View file

@ -1,8 +1,5 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from ..backend import CameraSource
from .widgets.QBackendPanel import QBackendPanel
@ -42,38 +39,33 @@ class QCameraSource(QBackendPanel):
q_load_settings = QXPushButtonCSWSignal(cs.load_settings, text=L('@QCameraSource.load_settings'), reflect_state_widgets=[q_camera_settings_group_label])
q_save_settings = QXPushButtonCSWSignal(cs.save_settings, text=L('@QCameraSource.save_settings'))
grid_l = lib_qt.QXGridLayout(spacing=5)
grid_l = qtx.QXGridLayout(spacing=5)
row = 0
grid_l.addWidget(q_device_idx_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_device_idx, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_device_idx_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_device_idx, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_driver_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_driver, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_driver_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_driver, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_resolution_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_resolution, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_resolution_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_resolution, row, 1, alignment=qtx.AlignLeft )
row += 1
btn_height = 24
grid_l.addWidget(q_camera_settings_group_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget( lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([
lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([q_open_settings]), ),
lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([q_load_settings]), ),
lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([q_save_settings]), ),
], contents_margins=(1,0,1,0), spacing=1), fixed_height=btn_height), row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_camera_settings_group_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget( qtx.QXWidgetHBox([q_open_settings, q_load_settings, q_save_settings],
contents_margins=(1,0,1,0), spacing=1, fixed_height=btn_height), row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_fps_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_fps, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_fps_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_fps, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_rotation_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_rotation, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_rotation_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_rotation, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_flip_horizontal_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_flip_horizontal, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_flip_horizontal_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_flip_horizontal, row, 1, alignment=qtx.AlignLeft )
row += 1
super().__init__(backend, L('@QCameraSource.module_title'),
layout=lib_qt.QXVBoxLayout([grid_l], spacing=5),
layout=qtx.QXVBoxLayout([grid_l], spacing=5),
content_align_top=True)

View file

@ -1,8 +1,5 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from ..backend import FaceAligner
from .widgets.QBackendPanel import QBackendPanel
@ -33,24 +30,24 @@ class QFaceAligner(QBackendPanel):
q_y_offset_label = QLabelPopupInfo(label=L('@QFaceAligner.y_offset'))
q_y_offset = QSpinBoxCSWNumber(cs.y_offset, reflect_state_widgets=[q_y_offset_label])
grid_l = lib_qt.QXGridLayout(spacing=5)
grid_l = qtx.QXGridLayout(spacing=5)
row = 0
grid_l.addWidget(q_face_coverage_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_face_coverage, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_face_coverage_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_face_coverage, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_resolution_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_resolution, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_resolution_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_resolution, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_exclude_moving_parts_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_exclude_moving_parts, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_exclude_moving_parts_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_exclude_moving_parts, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_head_mode_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_head_mode, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_head_mode_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_head_mode, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addLayout( lib_qt.QXVBoxLayout([q_x_offset_label, q_y_offset_label]), row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( lib_qt.QXHBoxLayout([q_x_offset, q_y_offset]), row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addLayout( qtx.QXVBoxLayout([q_x_offset_label, q_y_offset_label]), row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addLayout( qtx.QXHBoxLayout([q_x_offset, q_y_offset]), row, 1, alignment=qtx.AlignLeft )
row += 1
super().__init__(backend, L('@QFaceAligner.module_title'),
layout=lib_qt.QXVBoxLayout([grid_l]))
layout=qtx.QXVBoxLayout([grid_l]))

View file

@ -1,10 +1,7 @@
import numpy as np
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from ..backend import FaceDetector
from .widgets.QBackendPanel import QBackendPanel
@ -23,11 +20,11 @@ class QFaceDetector(QBackendPanel):
self._bc_out = backend.get_bc_out()
self._weak_heap = backend.get_weak_heap()
self._bcd_id = None
self._timer = lib_qt.QXTimer(interval=10, timeout=self._on_timer_10ms, start=True)
self._timer = qtx.QXTimer(interval=10, timeout=self._on_timer_10ms, start=True)
face_coords_label = self._q_face_coords_label = lib_qt.QXLabel(font=QXFontDB.get_fixedwidth_font(size=7), word_wrap=False)
q_detected_faces = self._q_detected_faces = lib_qt.QXCollapsibleSection(title=L('@QFaceDetector.detected_faces'),
content_layout=lib_qt.QXVBoxLayout([face_coords_label]), is_opened=True)
face_coords_label = self._q_face_coords_label = qtx.QXLabel(font=QXFontDB.get_fixedwidth_font(size=7), word_wrap=False)
q_detected_faces = self._q_detected_faces = qtx.QXCollapsibleSection(title=L('@QFaceDetector.detected_faces'),
content_layout=qtx.QXVBoxLayout([face_coords_label]), is_opened=True)
cs = backend.get_control_sheet()
@ -52,28 +49,28 @@ class QFaceDetector(QBackendPanel):
q_temporal_smoothing_label = QLabelPopupInfo(label=L('@QFaceDetector.temporal_smoothing'), popup_info_text=L('@QFaceDetector.help.temporal_smoothing') )
q_temporal_smoothing = QSpinBoxCSWNumber(cs.temporal_smoothing, reflect_state_widgets=[q_temporal_smoothing_label])
grid_l = lib_qt.QXGridLayout(vertical_spacing=5, horizontal_spacing=5, )
grid_l = qtx.QXGridLayout(vertical_spacing=5, horizontal_spacing=5)
row = 0
grid_l.addWidget(q_detector_type_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_detector_type, row, 1, 1, 3, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_detector_type_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_detector_type, row, 1, 1, 3)
row += 1
grid_l.addWidget(q_device_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_device, row, 1, 1, 3, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_device_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_device, row, 1, 1, 3)
row += 1
grid_l.addWidget(q_fixed_window_size_label, row, 0, 1, 2, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_fixed_window_size, row, 2, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_fixed_window_size_label, row, 0, 1, 2, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_fixed_window_size, row, 2, 1, 2, alignment=qtx.AlignLeft)
row += 1
grid_l.addWidget(q_threshold_label, row, 0, 1, 2, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_threshold, row, 2, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_threshold_label, row, 0, 1, 2, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_threshold, row, 2, 1, 2, alignment=qtx.AlignLeft )
row += 1
grid_l.addLayout( lib_qt.QXHBoxLayout([q_max_faces_label, 5, q_max_faces]), row, 0, 1, 2, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( lib_qt.QXHBoxLayout([q_sort_by_label, 5,q_sort_by]), row, 2, 1,2,alignment=Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( qtx.QXHBoxLayout([q_max_faces_label, 5, q_max_faces]), row, 0, 1, 2, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addLayout( qtx.QXHBoxLayout([q_sort_by_label, 5,q_sort_by]), row, 2, 1,2, alignment=qtx.AlignLeft | qtx.AlignVCenter)
row += 1
grid_l.addLayout( lib_qt.QXHBoxLayout([q_temporal_smoothing_label, 5, q_temporal_smoothing]), row, 0, 1, 4, alignment=Qt.AlignmentFlag.AlignCenter )
grid_l.addLayout( qtx.QXHBoxLayout([q_temporal_smoothing_label, 5, q_temporal_smoothing]), row, 0, 1, 4, alignment=qtx.AlignCenter)
row += 1
grid_l.addWidget(q_detected_faces, row, 0, 1, 4)
row += 1
super().__init__(backend, L('@QFaceDetector.module_title'), layout=lib_qt.QXVBoxLayout([grid_l]))
super().__init__(backend, L('@QFaceDetector.module_title'), layout=qtx.QXVBoxLayout([grid_l]))
def _on_backend_state_change(self, backend, started, starting, stopping, stopped, busy):
super()._on_backend_state_change (backend, started, starting, stopping, stopped, busy)
@ -101,7 +98,7 @@ class QFaceDetector(QBackendPanel):
info = []
for face_id, fsi in enumerate(bcd.get_face_swap_info_list()):
info_str = f'{face_id}: '
if fsi.face_urect is not None:
l,t,r,b = fsi.face_urect.as_ltrb_bbox(frame_image_w_h).astype(np.int)
info_str += f'[{l},{t},{r},{b}]'

View file

@ -1,8 +1,5 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from .widgets.QBackendPanel import QBackendPanel
from .widgets.QComboBoxCSWDynamicSingleSwitch import \
@ -27,30 +24,29 @@ class QFaceMarker(QBackendPanel):
q_temporal_smoothing_label = QLabelPopupInfo(label=L('@QFaceMarker.temporal_smoothing'), popup_info_text=L('@QFaceMarker.help.temporal_smoothing') )
q_temporal_smoothing = QSpinBoxCSWNumber(cs.temporal_smoothing, reflect_state_widgets=[q_temporal_smoothing_label])
grid_l = lib_qt.QXGridLayout(spacing=5)
grid_l = qtx.QXGridLayout(spacing=5)
row = 0
grid_l.addWidget(q_marker_type_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_marker_type, row, 1, 1, 3, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_marker_type_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_marker_type, row, 1, 1, 3 )
row += 1
grid_l.addWidget(q_device_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_device, row, 1, 1, 3, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_device_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_device, row, 1, 1, 3 )
row += 1
sub_row = 0
sub_grid_l = lib_qt.QXGridLayout(spacing=5)
sub_grid_l.addWidget(q_marker_coverage_label, sub_row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
sub_grid_l.addWidget(q_marker_coverage, sub_row, 1, 1, 1, alignment=Qt.AlignmentFlag.AlignLeft )
sub_grid_l = qtx.QXGridLayout(spacing=5)
sub_grid_l.addWidget(q_marker_coverage_label, sub_row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
sub_grid_l.addWidget(q_marker_coverage, sub_row, 1, 1, 1, alignment=qtx.AlignLeft )
sub_row += 1
sub_grid_l.addWidget(q_temporal_smoothing_label, sub_row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
sub_grid_l.addWidget(q_temporal_smoothing, sub_row, 1, 1, 1, alignment=Qt.AlignmentFlag.AlignLeft )
sub_grid_l.addWidget(q_temporal_smoothing_label, sub_row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
sub_grid_l.addWidget(q_temporal_smoothing, sub_row, 1, 1, 1, alignment=qtx.AlignLeft )
sub_row += 1
grid_l.addLayout(sub_grid_l, row, 0, 1, 4, alignment=Qt.AlignmentFlag.AlignCenter )
grid_l.addLayout(sub_grid_l, row, 0, 1, 4, alignment=qtx.AlignCenter )
row += 1
super().__init__(backend, L('@QFaceMarker.module_title'),
layout=lib_qt.QXVBoxLayout([grid_l]) )
layout=qtx.QXVBoxLayout([grid_l]) )

View file

@ -1,8 +1,5 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from .widgets.QBackendPanel import QBackendPanel
from .widgets.QCheckBoxCSWFlag import QCheckBoxCSWFlag
@ -48,45 +45,45 @@ class QFaceMerger(QBackendPanel):
q_interpolation_label = QLabelPopupInfo(label=L('@QFaceMerger.interpolation') )
q_interpolation = QComboBoxCSWDynamicSingleSwitch(cs.interpolation, reflect_state_widgets=[q_interpolation_label])
q_color_compression_label = QLabelPopupInfo(label=L('@QFaceMerger.color_compression') )
q_color_compression = QSliderCSWNumber(cs.color_compression, reflect_state_widgets=[q_color_compression_label])
q_face_opacity_label = QLabelPopupInfo(label=L('@QFaceMerger.face_opacity') )
q_face_opacity = QSliderCSWNumber(cs.face_opacity, reflect_state_widgets=[q_face_opacity_label])
grid_l = lib_qt.QXGridLayout(spacing=5)
grid_l = qtx.QXGridLayout(spacing=5)
row = 0
grid_l.addWidget(q_device_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_device, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_device_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_device, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addLayout( lib_qt.QXVBoxLayout([q_face_x_offset_label, q_face_y_offset_label]), row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( lib_qt.QXHBoxLayout([q_face_x_offset, q_face_y_offset]), row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addLayout( qtx.QXVBoxLayout([q_face_x_offset_label, q_face_y_offset_label]), row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addLayout( qtx.QXHBoxLayout([q_face_x_offset, q_face_y_offset]), row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_face_scale_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_face_scale, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_face_scale_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_face_scale, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget( q_face_mask_type_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( lib_qt.QXHBoxLayout([q_face_mask_source, q_face_mask_source_label, 5,
q_face_mask_celeb, q_face_mask_celeb_label, 5,
q_face_mask_lmrks, q_face_mask_lmrks_label]), row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget( q_face_mask_type_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addLayout( qtx.QXHBoxLayout([q_face_mask_source, q_face_mask_source_label, 5,
q_face_mask_celeb, q_face_mask_celeb_label, 5,
q_face_mask_lmrks, q_face_mask_lmrks_label]), row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addLayout(lib_qt.QXVBoxLayout([q_face_mask_erode_label,q_face_mask_blur_label]), row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout(lib_qt.QXHBoxLayout([q_face_mask_erode,q_face_mask_blur], spacing=3), row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addLayout(qtx.QXVBoxLayout([q_face_mask_erode_label,q_face_mask_blur_label]), row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addLayout(qtx.QXHBoxLayout([q_face_mask_erode,q_face_mask_blur], spacing=3), row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_color_transfer_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_color_transfer, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_color_transfer_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_color_transfer, row, 1 )
row += 1
grid_l.addWidget(q_interpolation_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_interpolation, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_interpolation_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_interpolation, row, 1)
row += 1
grid_l.addWidget(q_color_compression_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_color_compression_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_color_compression, row, 1)
row += 1
grid_l.addWidget(q_face_opacity_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_face_opacity_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter)
grid_l.addWidget(q_face_opacity, row, 1)
row += 1
super().__init__(backend, L('@QFaceMerger.module_title'),
layout=lib_qt.QXVBoxLayout([grid_l]) )
layout=qtx.QXVBoxLayout([grid_l]) )

View file

@ -1,11 +1,8 @@
from pathlib import Path
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.gfx import QXImageDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from ..backend import FaceSwapper
from .widgets.QBackendPanel import QBackendPanel
@ -26,7 +23,7 @@ class QFaceSwapper(QBackendPanel):
cs = backend.get_control_sheet()
btn_open_folder = self.btn_open_folder = lib_qt.QXPushButton(image = QXImageDB.eye_outline('light gray'), tooltip_text='Reveal in Explorer', released=self._btn_open_folder_released, fixed_size=(24,22) )
btn_open_folder = self.btn_open_folder = qtx.QXPushButton(image = QXImageDB.eye_outline('light gray'), tooltip_text='Reveal in Explorer', released=self._btn_open_folder_released, fixed_size=(24,22) )
q_model_label = QLabelPopupInfo(label=L('@QFaceSwapper.model'), popup_info_text=L('@QFaceSwapper.help.model') )
q_model = QComboBoxCSWDynamicSingleSwitch(cs.model, reflect_state_widgets=[q_model_label, btn_open_folder])
@ -60,39 +57,37 @@ class QFaceSwapper(QBackendPanel):
q_two_pass_label = QLabelPopupInfo(label=L('@QFaceSwapper.two_pass'), popup_info_text=L('@QFaceSwapper.help.two_pass') )
q_two_pass = QCheckBoxCSWFlag(cs.two_pass, reflect_state_widgets=[q_two_pass_label])
grid_l = lib_qt.QXGridLayout( spacing=5)
grid_l = qtx.QXGridLayout( spacing=5)
row = 0
grid_l.addWidget(q_model_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout(lib_qt.QXHBoxLayout([q_model, 2, btn_open_folder, 2, q_model_info_label]), row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_model_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addLayout(qtx.QXHBoxLayout([q_model, 2, btn_open_folder, 2, q_model_info_label]), row, 1 )
row += 1
grid_l.addWidget(q_model_dl_progress, row, 0, 1, 2 )
row += 1
grid_l.addWidget(q_model_dl_error, row, 0, 1, 2 )
row += 1
grid_l.addWidget(q_device_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_device, row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_device_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_device, row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget( q_swap_all_faces_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( lib_qt.QXHBoxLayout([q_swap_all_faces, 4, q_face_id_label, 4, q_face_id ]), row, 1, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget( q_swap_all_faces_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addLayout( qtx.QXHBoxLayout([q_swap_all_faces, 4, q_face_id_label, 4, q_face_id ]), row, 1, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(q_morph_factor_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_morph_factor_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_morph_factor, row, 1)
row += 1
grid_l.addWidget(q_sharpen_amount_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_sharpen_amount_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_sharpen_amount, row, 1)
row += 1
grid_l.addWidget( q_pre_gamma_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( lib_qt.QXHBoxLayout([q_pre_gamma_red, q_pre_gamma_green, q_pre_gamma_blue ]), row, 1)
grid_l.addWidget( q_pre_gamma_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addLayout( qtx.QXHBoxLayout([q_pre_gamma_red, q_pre_gamma_green, q_pre_gamma_blue ]), row, 1)
row += 1
grid_l.addWidget(q_two_pass_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_two_pass_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_two_pass, row, 1)
row += 1
super().__init__(backend, L('@QFaceSwapper.module_title'),
layout=lib_qt.QXVBoxLayout([grid_l]) )
layout=qtx.QXVBoxLayout([grid_l]) )
def _btn_open_folder_released(self):
QDesktopServices.openUrl(QUrl.fromLocalFile( str(self._dfm_models_path) ))
qtx.QDesktopServices.openUrl(qtx.QUrl.fromLocalFile( str(self._dfm_models_path) ))

View file

@ -1,9 +1,6 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.gfx import QXImageDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from ..backend import FileSource
from .widgets.QBackendPanel import QBackendPanel
@ -38,39 +35,38 @@ class QFileSource(QBackendPanel):
q_is_autorewind_label = QLabelPopupInfo(label=L('@QFileSource.is_autorewind'))
q_is_autorewind = QCheckBoxCSWFlag(cs.is_autorewind, reflect_state_widgets=[q_is_autorewind_label])
btn_size=(32,32)
btn_color= '#E01010'
btn_size = (32,32)
btn_color = '#E01010'
btn_seek_begin = QXPushButtonCSWSignal(cs.seek_begin, image=QXImageDB.play_skip_back_circle_outline(btn_color), button_size=btn_size )
btn_seek_backward = QXPushButtonCSWSignal(cs.seek_backward, image=QXImageDB.play_back_circle_outline(btn_color), button_size=btn_size )
btn_play = QXPushButtonCSWSignal(cs.play, image=QXImageDB.play_circle_outline(btn_color), button_size=btn_size )
btn_pause = QXPushButtonCSWSignal(cs.pause, image=QXImageDB.pause_circle_outline(btn_color), button_size=btn_size )
btn_seek_backward = QXPushButtonCSWSignal(cs.seek_backward, image=QXImageDB.play_back_circle_outline(btn_color), button_size=btn_size )
btn_seek_forward = QXPushButtonCSWSignal(cs.seek_forward, image=QXImageDB.play_forward_circle_outline(btn_color), button_size=btn_size )
btn_seek_begin = QXPushButtonCSWSignal(cs.seek_begin, image=QXImageDB.play_skip_back_circle_outline(btn_color), button_size=btn_size )
btn_seek_end = QXPushButtonCSWSignal(cs.seek_end, image=QXImageDB.play_skip_forward_circle_outline(btn_color), button_size=btn_size )
q_frame_slider = QSliderCSWNumbers(cs.frame_index, cs.frame_count)
grid_l = lib_qt.QXGridLayout(spacing=5)
grid_l = qtx.QXGridLayout(spacing=5)
row = 0
grid_l.addWidget(q_target_width_label, row, 0, 1, 2, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_target_width, row, 2, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget(q_target_width_label, row, 0, 1, 2, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_target_width, row, 2, 1, 2, alignment=qtx.AlignLeft )
row += 1
grid_l.addLayout( lib_qt.QXHBoxLayout([q_is_realtime_label, 5, q_is_realtime, 5, q_fps_label]), row, 0, 1, 2, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget( q_fps, row, 2, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addLayout( qtx.QXHBoxLayout([q_is_realtime_label, 5, q_is_realtime, 5, q_fps_label]), row, 0, 1, 2, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget( q_fps, row, 2, 1, 2, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget( q_is_autorewind_label, row, 0, 1, 2, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget( q_is_autorewind, row, 2, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft )
grid_l.addWidget( q_is_autorewind_label, row, 0, 1, 2, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget( q_is_autorewind, row, 2, 1, 2, alignment=qtx.AlignLeft )
row += 1
grid_l.addWidget(lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([btn_seek_begin, btn_seek_backward, btn_play, btn_pause,btn_seek_forward, btn_seek_end], spacing=1), ),
row, 0, 1, 4, alignment=Qt.AlignmentFlag.AlignCenter)
grid_l.addWidget(qtx.QXFrameHBox([btn_seek_begin, btn_seek_backward, btn_play, btn_pause,btn_seek_forward, btn_seek_end], spacing=1),
row, 0, 1, 4, alignment=qtx.AlignCenter)
row += 1
grid_l.addWidget(q_frame_slider, row, 0, 1, 4)
row += 1
main_l = lib_qt.QXVBoxLayout([q_input_type,
q_input_paths,
q_error,
grid_l
], spacing=5)
main_l = qtx.QXVBoxLayout([q_input_type,
q_input_paths,
q_error,
grid_l], spacing=5)
super().__init__(backend, L('@QFileSource.module_title'),
layout=main_l, content_align_top=True)

View file

@ -1,8 +1,5 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from .widgets.QBackendPanel import QBackendPanel
from .widgets.QLabelPopupInfo import QLabelPopupInfo
@ -19,15 +16,15 @@ class QFrameAdjuster(QBackendPanel):
q_degrade_bicubic_label = QLabelPopupInfo(label=L('@QFrameAdjuster.degrade_bicubic_per'), popup_info_text=L('@QFrameAdjuster.help.degrade_bicubic_per') )
q_degrade_bicubic = QSliderCSWNumber(cs.degrade_bicubic_per, reflect_state_widgets=[q_degrade_bicubic_label])
grid_l = lib_qt.QXGridLayout(spacing=5)
grid_l = qtx.QXGridLayout(spacing=5)
row = 0
grid_l.addWidget(q_median_blur_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_median_blur_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_median_blur, row, 1)
row += 1
grid_l.addWidget(q_degrade_bicubic_label, row, 0, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_degrade_bicubic_label, row, 0, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_degrade_bicubic, row, 1)
row += 1
super().__init__(backend, L('@QFrameAdjuster.module_title'),
layout=lib_qt.QXVBoxLayout([grid_l]) )
layout=qtx.QXVBoxLayout([grid_l]) )

View file

@ -1,8 +1,5 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from ..backend import StreamOutput
from .widgets.QBackendPanel import QBackendPanel
@ -27,7 +24,7 @@ class QStreamOutput(QBackendPanel):
q_source_type_label = QLabelPopupInfo(label=L('@QStreamOutput.source_type') )
q_source_type = QComboBoxCSWDynamicSingleSwitch(cs.source_type, reflect_state_widgets=[q_source_type_label])
q_show_hide_window = QXPushButtonCSWSignal(cs.show_hide_window, text=L('@QStreamOutput.show_hide_window'), button_height=22)
q_show_hide_window = QXPushButtonCSWSignal(cs.show_hide_window, text=L('@QStreamOutput.show_hide_window'), button_size=(None,22) )
q_aligned_face_id_label = QLabelPopupInfo(label=L('@QStreamOutput.aligned_face_id'), popup_info_text=L('@QStreamOutput.help.aligned_face_id'))
q_aligned_face_id = QSpinBoxCSWNumber(cs.aligned_face_id, reflect_state_widgets=[q_aligned_face_id_label])
@ -42,27 +39,27 @@ class QStreamOutput(QBackendPanel):
q_save_fill_frame_gap_label = QLabelPopupInfo(label=L('@QStreamOutput.save_fill_frame_gap'), popup_info_text=L('@QStreamOutput.help.save_fill_frame_gap'))
q_save_fill_frame_gap = QCheckBoxCSWFlag(cs.save_fill_frame_gap, reflect_state_widgets=[q_save_fill_frame_gap_label])
grid_l = lib_qt.QXGridLayout(spacing=5)
grid_l = qtx.QXGridLayout(spacing=5)
row = 0
grid_l.addWidget(q_average_fps_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_average_fps, row, 1, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_average_fps_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_average_fps, row, 1, 1, 2, alignment=qtx.AlignLeft | qtx.AlignVCenter )
row += 1
grid_l.addWidget(q_source_type_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_source_type, row, 1, 1, 1, alignment=Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_source_type_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_source_type, row, 1, 1, 1, alignment=qtx.AlignLeft | qtx.AlignVCenter )
grid_l.addWidget(q_show_hide_window, row, 2, 1, 1)
row += 1
grid_l.addWidget(q_aligned_face_id_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_aligned_face_id, row, 1, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_aligned_face_id_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_aligned_face_id, row, 1, 1, 2, alignment=qtx.AlignLeft | qtx.AlignVCenter )
row += 1
grid_l.addWidget(q_target_delay_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_target_delay, row, 1, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_target_delay_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_target_delay, row, 1, 1, 2, alignment=qtx.AlignLeft | qtx.AlignVCenter )
row += 1
grid_l.addWidget(q_save_sequence_path_label, row, 0, 1, 1, alignment=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_save_sequence_path, row, 1, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter )
grid_l.addWidget(q_save_sequence_path_label, row, 0, 1, 1, alignment=qtx.AlignRight | qtx.AlignVCenter )
grid_l.addWidget(q_save_sequence_path, row, 1, 1, 2, alignment=qtx.AlignLeft | qtx.AlignVCenter )
row += 1
grid_l.addLayout( lib_qt.QXHBoxLayout([q_save_fill_frame_gap, 4, q_save_fill_frame_gap_label]), row, 1, 1, 2, alignment=Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter )
grid_l.addLayout( qtx.QXHBoxLayout([q_save_fill_frame_gap, 4, q_save_fill_frame_gap_label]), row, 1, 1, 2, alignment=qtx.AlignLeft | qtx.AlignVCenter )
row += 1
grid_l.addWidget(q_save_sequence_path_error, row, 0, 1, 3)

View file

@ -1,35 +1,28 @@
import numpy as np
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from ... import backend
class QBCFaceAlignViewer(lib_qt.QXCollapsibleSection):
"""
"""
class QBCFaceAlignViewer(qtx.QXCollapsibleSection):
def __init__(self, backed_weak_heap : backend.BackendWeakHeap,
bc : backend.BackendConnection,
preview_width=256,):
self._preview_width = preview_width
self._timer = lib_qt.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._timer = qtx.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._backed_weak_heap = backed_weak_heap
self._bc = bc
self._bcd_id = None
layered_images = self._layered_images = lib_qt.QXFixedLayeredImages(preview_width, preview_width)
info_label = self._info_label = lib_qt.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
layered_images = self._layered_images = qtx.QXFixedLayeredImages(preview_width, preview_width)
info_label = self._info_label = qtx.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
super().__init__(title=L('@QBCFaceAlignViewer.title'),
content_layout=lib_qt.QXVBoxLayout(
[ (layered_images, Qt.AlignmentFlag.AlignCenter),
(info_label, Qt.AlignmentFlag.AlignCenter),
]) )
content_layout=qtx.QXVBoxLayout([(layered_images, qtx.AlignCenter),
(info_label, qtx.AlignCenter)]) )
def _on_timer_16ms(self):
top_qx = self.get_top_QXWindow()

View file

@ -1,32 +1,28 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from ... import backend
class QBCFaceSwapViewer(lib_qt.QXCollapsibleSection):
class QBCFaceSwapViewer(qtx.QXCollapsibleSection):
"""
"""
def __init__(self, backed_weak_heap : backend.BackendWeakHeap,
bc : backend.BackendConnection,
preview_width=256,):
self._preview_width = preview_width
self._timer = lib_qt.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._timer = qtx.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._backed_weak_heap = backed_weak_heap
self._bc = bc
self._bcd_id = None
layered_images = self._layered_images = lib_qt.QXFixedLayeredImages(preview_width, preview_width)
info_label = self._info_label = lib_qt.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
layered_images = self._layered_images = qtx.QXFixedLayeredImages(preview_width, preview_width)
info_label = self._info_label = qtx.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
main_l = lib_qt.QXVBoxLayout([ (layered_images, Qt.AlignmentFlag.AlignCenter),
(info_label, Qt.AlignmentFlag.AlignCenter),
], spacing=0)
main_l = qtx.QXVBoxLayout([ (layered_images, qtx.AlignCenter),
(info_label, qtx.AlignCenter) ])
super().__init__(title=L('@QBCFaceSwapViewer.title'), content_layout=main_l)

View file

@ -1,30 +1,25 @@
import numpy as np
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from ... import backend
class QBCFrameViewer(lib_qt.QXCollapsibleSection):
class QBCFrameViewer(qtx.QXCollapsibleSection):
def __init__(self, backed_weak_heap : backend.BackendWeakHeap,
bc : backend.BackendConnection,
preview_width=256):
self._timer = lib_qt.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._timer = qtx.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._backed_weak_heap = backed_weak_heap
self._bc = bc
self._bcd_id = None
layered_images = self._layered_images = lib_qt.QXFixedLayeredImages(preview_width, preview_width)
info_label = self._info_label = lib_qt.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
layered_images = self._layered_images = qtx.QXFixedLayeredImages(preview_width, preview_width)
info_label = self._info_label = qtx.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
main_l = lib_qt.QXVBoxLayout([ (layered_images, Qt.AlignmentFlag.AlignCenter),
(info_label, Qt.AlignmentFlag.AlignCenter),
])
main_l = qtx.QXVBoxLayout([ (layered_images, qtx.AlignCenter),
(info_label, qtx.AlignCenter), ])
super().__init__(title=L('@QBCFrameViewer.title'), content_layout=main_l)
def _on_timer_16ms(self):

View file

@ -1,32 +1,29 @@
import numpy as np
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import image as lib_image
from xlib import qt as lib_qt
from xlib import qt as qtx
from ... import backend
class QBCMergedFrameViewer(lib_qt.QXCollapsibleSection):
class QBCMergedFrameViewer(qtx.QXCollapsibleSection):
def __init__(self, backed_weak_heap : backend.BackendWeakHeap,
bc : backend.BackendConnection,
preview_width=256):
self._timer = lib_qt.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._timer = qtx.QXTimer(interval=16, timeout=self._on_timer_16ms, start=True)
self._backed_weak_heap = backed_weak_heap
self._bc = bc
self._bcd_id = None
layered_images = self._layered_images = lib_qt.QXFixedLayeredImages(preview_width, preview_width)
layered_images = self._layered_images = qtx.QXFixedLayeredImages(preview_width, preview_width)
info_label = self._info_label = lib_qt.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
info_label = self._info_label = qtx.QXLabel( font=QXFontDB.get_fixedwidth_font(size=7))
main_l = qtx.QXVBoxLayout([ (layered_images, qtx.AlignCenter),
(info_label, qtx.AlignCenter) ])
main_l = lib_qt.QXVBoxLayout([ (layered_images, Qt.AlignmentFlag.AlignCenter),
(info_label, Qt.AlignmentFlag.AlignCenter),
], spacing=0)
super().__init__(title=L('@QBCMergedFrameViewer.title'), content_layout=main_l)
def _on_timer_16ms(self):

View file

@ -1,66 +1,54 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from resources.gfx import QXImageDB, QXImageSequenceDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from ...backend import BackendHost
class QBackendPanel(lib_qt.QXWidget):
class QBackendPanel(qtx.QXWidget):
"""
Base panel for CSW backend
"""
def __init__(self, backend : BackendHost, name : str, layout, content_align_top=False):
super().__init__()
if not isinstance(backend, BackendHost):
raise ValueError('backend must be an instance of BackendHost')
super().__init__()
self._backend = backend
self._name = name
backend.call_on_state_change(self._on_backend_state_change)
backend.call_on_profile_timing(self._on_backend_profile_timing)
btn_on_off = self._btn_on_off = lib_qt.QXPushButton(tooltip_text=L('@QBackendPanel.start'), fixed_width=20, released=self._on_btn_on_off_released)
btn_on_off = self._btn_on_off = qtx.QXPushButton(tooltip_text=L('@QBackendPanel.start'),
released=self._on_btn_on_off_released,
fixed_width=20)
btn_reset_state = self._btn_reset_state = lib_qt.QXPushButton(image=QXImageDB.settings_reset_outline('gray'),
#size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
fixed_width=20, released=self._on_btn_reset_state_released, tooltip_text=L('@QBackendPanel.reset_settings') )
btn_reset_state = self._btn_reset_state = qtx.QXPushButton(image=QXImageDB.settings_reset_outline('gray'),
released=self._on_btn_reset_state_released, tooltip_text=L('@QBackendPanel.reset_settings'),
fixed_width=20)
timing_label = self._timing_label = lib_qt.QXLabel()
fps_label = self._fps_label = qtx.QXLabel()
bar_widget = self._bar_widget = \
lib_qt.QXFrame(layout=lib_qt.QXHBoxLayout([
lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([
btn_on_off,
1,
btn_reset_state,
2,
lib_qt.QXLabel(name, font=QXFontDB.get_default_font(10)),
qtx.QXFrameHBox(widgets=[btn_on_off, 1, btn_reset_state, 2,
qtx.QXLabel(name, font=QXFontDB.get_default_font(10)),
(fps_label, qtx.AlignRight), 2],
size_policy=('expanding', 'fixed'), fixed_height=24)
(timing_label, Qt.AlignmentFlag.AlignRight),
2
]), fixed_height=24),
]),
size_policy=(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) )
content_widget = self._content_widget = lib_qt.QXFrame(layout=lib_qt.QXHBoxLayout([layout], contents_margins=2),
enabled=False )
content_widget = self._content_widget = qtx.QXFrameHBox([layout], contents_margins=2, enabled=False)
l_widgets = [bar_widget, 1]
if not content_align_top:
l_widgets += [ lib_qt.QXFrame(size_policy=(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) ) ]
l_widgets += [ qtx.QXFrame(size_policy=('expanding','expanding') ) ]
l_widgets += [content_widget]
l_widgets += [ lib_qt.QXFrame(size_policy=(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) ) ]
l_widgets += [ qtx.QXFrame(size_policy=('expanding', 'expanding') ) ]
self.setLayout(lib_qt.QXVBoxLayout(l_widgets))
self.setLayout(qtx.QXVBoxLayout(l_widgets))
lib_qt.disable([self._content_widget])
btn_on_off.set_image( QXImageDB.power_outline('red') )
def _on_backend_state_change(self, backend, started, starting, stopping, stopped, busy):
@ -79,19 +67,19 @@ class QBackendPanel(lib_qt.QXWidget):
btn_on_off.set_image( QXImageDB.power_outline('red') )
if started and not busy:
lib_qt.show_and_enable([self._content_widget, self._timing_label])
self._timing_label.setText(None)
qtx.show_and_enable([self._content_widget, self._fps_label])
self._fps_label.setText(None)
else:
lib_qt.hide_and_disable([self._content_widget, self._timing_label])
self._timing_label.setText(None)
qtx.hide_and_disable([self._content_widget, self._fps_label])
self._fps_label.setText(None)
def _on_backend_profile_timing(self, timing : float):
fps = int(1.0 / timing if timing != 0 else 0)
if fps < 10:
self._timing_label.set_color('red')
self._fps_label.set_color('red')
else:
self._timing_label.set_color(None)
self._timing_label.setText(f"{fps} {L('@QBackendPanel.FPS')}")
self._fps_label.set_color(None)
self._fps_label.setText(f"{fps} {L('@QBackendPanel.FPS')}")
def _on_btn_on_off_released(self):
backend = self._backend

View file

@ -1,27 +1,21 @@
from typing import Union
from localization import Localization
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QButtonCSWDynamicSingleSwitch(QCSWControl):
"""
Implements lib_csw.DynamicSingleSwitch control with radiobuttons or checkboxes
"""
def __init__(self, csw_switch : lib_csw.DynamicSingleSwitch.Client,
horizontal : bool, radio_buttons : bool):
"""
Implements lib_csw.DynamicSingleSwitch control with radiobuttons or checkboxes
"""
if not isinstance(csw_switch, lib_csw.DynamicSingleSwitch.Client):
raise ValueError('csw_switch must be an instance of DynamicSingleSwitch.Client')
super().__init__(csw_control=csw_switch)
self._csw_switch = csw_switch
self._is_radio_buttons = radio_buttons
@ -29,11 +23,8 @@ class QButtonCSWDynamicSingleSwitch(QCSWControl):
csw_switch.call_on_choices(self._on_csw_choices)
self._btns = []
main_l = self._main_l = lib_qt.QXHBoxLayout() if horizontal else lib_qt.QXVBoxLayout()
self.setLayout(lib_qt.QXHBoxLayout([ lib_qt.QXFrame(layout=main_l, size_policy=(QSizePolicy.Policy.Fixed,QSizePolicy.Policy.Fixed) ), ]) )
self.hide()
self._main_l = qtx.QXHBoxLayout() if horizontal else qtx.QXVBoxLayout()
super().__init__(csw_control=csw_switch, layout=self._main_l)
def _on_csw_choices(self, choices, choices_names, none_choice_name : Union[str,None]):
for btn in self._btns:
@ -45,23 +36,23 @@ class QButtonCSWDynamicSingleSwitch(QCSWControl):
for idx, choice in enumerate(choices_names):
choice = Localization.localize(choice)
if self._is_radio_buttons:
btn = lib_qt.QXRadioButton(text=choice, toggled=(lambda checked, idx=idx: self.on_btns_toggled(idx, checked)) )
btn = qtx.QXRadioButton(text=choice, toggled=(lambda checked, idx=idx: self.on_btns_toggled(idx, checked)) )
else:
btn = lib_qt.QXCheckBox(text=choice, toggled=(lambda checked, idx=idx: self.on_btns_toggled(idx, checked)) )
btn = qtx.QXCheckBox(text=choice, toggled=(lambda checked, idx=idx: self.on_btns_toggled(idx, checked)) )
btns.append(btn)
self._main_l.addWidget(btn, alignment=Qt.AlignmentFlag.AlignLeft)
self._main_l.addWidget(btn, alignment=qtx.AlignCenter)
def on_btns_toggled(self, idx, checked):
if checked:
if not self._csw_switch.select(idx):
with lib_qt.BlockSignals(self._btns[idx]):
with qtx.BlockSignals(self._btns[idx]):
self._btns[idx].setChecked(False)
else:
if not self._csw_switch.unselect():
with lib_qt.BlockSignals(self._btns[idx]):
with qtx.BlockSignals(self._btns[idx]):
self._btns[idx].setChecked(True)
def _on_csw_switch_selected(self, idx, choice):
with lib_qt.BlockSignals(self._btns):
with qtx.BlockSignals(self._btns):
for i,btn in enumerate(self._btns):
btn.setChecked(i==idx)

View file

@ -1,21 +1,16 @@
from collections import Iterable
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
class QCSWControl(lib_qt.QXWidget):
"""
base qt widget class for CSWControl
"""
def __init__(self, csw_control : lib_csw.Control, reflect_state_widgets=None):
super().__init__()
class QCSWControl(qtx.QXWidget):
def __init__(self, csw_control : lib_csw.Control, reflect_state_widgets=None, **kwargs):
"""
base qt widget class for CSWControl
"""
super().__init__(hided=True, **kwargs)
self._csw_control = csw_control
self._csw_state_widgets = []
csw_control.call_on_change_state(self._on_csw_state_change)

View file

@ -1,7 +1,4 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
@ -14,20 +11,17 @@ class QCheckBoxCSWFlag(QCSWControl):
def __init__(self, csw_flag : lib_csw.Flag.Client, reflect_state_widgets=None):
if not isinstance(csw_flag, lib_csw.Flag.Client):
raise ValueError('csw_flag must be an instance of Flag.Client')
super().__init__(csw_control=csw_flag, reflect_state_widgets=reflect_state_widgets)
self._csw_flag = csw_flag
csw_flag.call_on_flag(self.on_csw_flag)
# Init UI
chbox = self._chbox = lib_qt.QXCheckBox(clicked=self.on_chbox_clicked)
main_l = lib_qt.QXHBoxLayout([chbox])
self.setLayout(main_l)
self.hide()
chbox = self._chbox = qtx.QXCheckBox(clicked=self.on_chbox_clicked)
super().__init__(csw_control=csw_flag, reflect_state_widgets=reflect_state_widgets,
layout=qtx.QXHBoxLayout([chbox]))
def on_csw_flag(self, flag):
with lib_qt.BlockSignals(self._chbox):
with qtx.BlockSignals(self._chbox):
self._chbox.setChecked(flag)
def on_chbox_clicked(self):

View file

@ -1,11 +1,8 @@
from typing import Union
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
@ -18,35 +15,31 @@ class QComboBoxCSWDynamicSingleSwitch(QCSWControl):
def __init__(self, csw_switch : lib_csw.DynamicSingleSwitch.Client, reflect_state_widgets=None):
if not isinstance(csw_switch, lib_csw.DynamicSingleSwitch.Client):
raise ValueError('csw_switch must be an instance of DynamicSingleSwitch.Client')
super().__init__(csw_control=csw_switch, reflect_state_widgets=reflect_state_widgets)
self._csw_switch = csw_switch
self._has_none_choice = True
csw_switch.call_on_selected(self._on_csw_switch_selected)
csw_switch.call_on_choices(self._on_csw_choices)
# Init UI
self._combobox = None
main_l = self._main_l = lib_qt.QXHBoxLayout()
self.setLayout(main_l)
self.hide()
self._combobox = None
self._main_l = qtx.QXHBoxLayout()
super().__init__(csw_control=csw_switch, reflect_state_widgets=reflect_state_widgets, layout=self._main_l)
def _on_csw_choices(self, choices, choices_names, none_choice_name : Union[str,None]):
if self._combobox is not None:
self._main_l.removeWidget(self._combobox)
self._combobox.deleteLater()
self._choices_names = choices_names
self._has_none_choice = none_choice_name is not None
combobox = self._combobox = lib_qt.QXComboBox(font=QXFontDB.get_fixedwidth_font(), on_index_changed=self.on_combobox_index_changed)
with lib_qt.BlockSignals(self._combobox):
combobox = self._combobox = qtx.QXComboBox(font=QXFontDB.get_fixedwidth_font(), on_index_changed=self.on_combobox_index_changed)
with qtx.BlockSignals(self._combobox):
if none_choice_name is not None:
combobox.addItem( QIcon(), L(none_choice_name) )
combobox.addItem( qtx.QIcon(), L(none_choice_name) )
for choice_name in choices_names:
combobox.addItem( QIcon(), L(choice_name) )
combobox.addItem( qtx.QIcon(), L(choice_name) )
self._main_l.addWidget(combobox)
@ -61,7 +54,7 @@ class QComboBoxCSWDynamicSingleSwitch(QCSWControl):
raise Exception('error on select')
def _on_csw_switch_selected(self, idx, choice):
with lib_qt.BlockSignals(self._combobox):
with qtx.BlockSignals(self._combobox):
if idx is None:
self._combobox.setCurrentIndex(0)
else:

View file

@ -1,17 +1,13 @@
from typing import Union
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from resources.gfx import QXImageDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QErrorCSWError(QCSWControl):
"""
Implements lib_csw.Error control as widget
@ -19,25 +15,19 @@ class QErrorCSWError(QCSWControl):
def __init__(self, csw_error : lib_csw.Error.Client):
if not isinstance(csw_error, lib_csw.Error.Client):
raise ValueError('csw_error must be an instance of Error.Client')
super().__init__(csw_control=csw_error)
self._csw_error = csw_error
csw_error.call_on_error(self._on_csw_error)
label_warning = self._label_warning = lib_qt.QXLabel(image=QXImageDB.warning_outline('red'),
scaled_contents=True,
size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed),
fixed_size=(32,32),
)
self._label_warning = qtx.QXLabel(image=QXImageDB.warning_outline('red'),
scaled_contents=True,
size_policy=('fixed', 'fixed'),
fixed_size=(32,32) )
label = self._label = lib_qt.QXTextEdit( font=QXFontDB.get_default_font(size=7), read_only=True, fixed_height=80 )
self._label = qtx.QXTextEdit( font=QXFontDB.get_default_font(size=7), read_only=True, fixed_height=80)
bar = lib_qt.QXFrame(layout=lib_qt.QXHBoxLayout(
[ lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([label_warning]), size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)) ,
lib_qt.QXWidget(layout=lib_qt.QXHBoxLayout([label]))
], spacing=0) )
self.setLayout(lib_qt.QXHBoxLayout([bar]))
self.hide()
super().__init__(csw_control=csw_error,
layout=qtx.QXHBoxLayout([self._label_warning, self._label]) )
def _on_csw_state_change(self, state):
super()._on_csw_state_change(state)

View file

@ -1,8 +1,5 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
@ -16,7 +13,6 @@ class QLabelCSWNumber(QCSWControl):
if not isinstance(csw_number, lib_csw.Number.Client):
raise ValueError('csw_number must be an instance of Number.Client')
super().__init__(csw_control=csw_number, reflect_state_widgets=reflect_state_widgets)
self._csw_number = csw_number
self._decimals = 0
@ -24,11 +20,10 @@ class QLabelCSWNumber(QCSWControl):
csw_number.call_on_number(self._on_csw_number)
csw_number.call_on_config(self._on_csw_config)
label = self._label = lib_qt.QXLabel( font=QXFontDB.Digital7_Mono(11, italic=True) )
main_l = lib_qt.QXHBoxLayout([label])
label = self._label = qtx.QXLabel( font=QXFontDB.Digital7_Mono(11, italic=True) )
self.setLayout(main_l)
self.hide()
super().__init__(csw_control=csw_number, reflect_state_widgets=reflect_state_widgets,
layout=qtx.QXHBoxLayout([label]))
def _on_csw_number(self, number):
f = (10**self._decimals)

View file

@ -1,48 +1,35 @@
from typing import Union
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from resources.gfx import QXImageDB
from xlib import qt as lib_qt
from xlib import qt as qtx
class QLabelPopupInfo(lib_qt.QXWidget):
"""
text label with optional popup info on click
"""
class QLabelPopupInfo(qtx.QXWidget):
def __init__(self, label : str = None, popup_info_text = None):
"""
text label with optional popup info on click
"""
super().__init__()
self._has_info_text = False
self._label = lib_qt.QXLabel(text='')
self._label.hide()
self._label = qtx.QXLabel(text='', hided=True)
wnd = self._popup_wnd = lib_qt.QXWindow()
wnd.setParent(self)
wnd.setWindowFlags(Qt.WindowType.Popup)
wnd_text_label = self._popup_wnd_text_label = qtx.QXLabel(text='', font=QXFontDB.get_default_font() )
info_btn = self._info_btn = lib_qt.QXPushButton(image=QXImageDB.information_circle_outline('light gray'), fixed_size=(24,22), released=self._on_info_btn_released)
info_btn.hide()
wnd = self._popup_wnd = qtx.QXPopupWindow(layout=qtx.QXHBoxLayout([
qtx.QXFrame(bg_color= qtx.Qt.GlobalColor.black,
layout=qtx.QXHBoxLayout([
qtx.QXFrame(layout=qtx.QXHBoxLayout([qtx.QXLabel(image=QXImageDB.information_circle_outline('yellow'), scaled_contents=True, fixed_size=(24,24)),
wnd_text_label
], contents_margins=2, spacing=2)),
], contents_margins=2, spacing=2), size_policy=('fixed', 'fixed') )
], contents_margins=0) )
wnd_text_label = self._popup_wnd_text_label = lib_qt.QXLabel(text='', font=QXFontDB.get_default_font() )
info_btn = self._info_btn = qtx.QXPushButton(image=QXImageDB.information_circle_outline('light gray'), released=self._on_info_btn_released, fixed_size=(24,22), hided=True)
wnd_layout = lib_qt.QXHBoxLayout([
lib_qt.QXFrame(
bg_color= Qt.GlobalColor.black,
layout=lib_qt.QXHBoxLayout([
lib_qt.QXFrame(layout=lib_qt.QXHBoxLayout([lib_qt.QXLabel(image=QXImageDB.information_circle_outline('yellow'), scaled_contents=True, fixed_size=(24,24)),
wnd_text_label
], contents_margins=2, spacing=2)),
], contents_margins=2, spacing=2), size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) )
], contents_margins=0)
wnd.setLayout(wnd_layout)
self.setLayout(lib_qt.QXHBoxLayout([self._label, info_btn]))
self.setLayout(qtx.QXHBoxLayout([self._label, info_btn]))
self.set_label( label )
self.set_popup_info( popup_info_text )
@ -90,12 +77,12 @@ class QLabelPopupInfo(lib_qt.QXWidget):
if label_widget.isHidden():
label_widget = self._info_btn
screen_size = lib_qt.QXMainApplication.get_singleton().primaryScreen().size()
screen_size = qtx.QXMainApplication.get_singleton().primaryScreen().size()
label_size = label_widget.size()
global_pt = label_widget.mapToGlobal( QPoint(0, label_size.height()))
global_pt = label_widget.mapToGlobal( qtx.QPoint(0, label_size.height()))
popup_wnd_size = popup_wnd.size()
global_pt = QPoint( min(global_pt.x(), screen_size.width() - popup_wnd_size.width()),
min(global_pt.y(), screen_size.height() - popup_wnd_size.height()) )
global_pt = qtx.QPoint( min(global_pt.x(), screen_size.width() - popup_wnd_size.width()),
min(global_pt.y(), screen_size.height() - popup_wnd_size.height()) )
popup_wnd.move(global_pt)

View file

@ -1,8 +1,5 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
@ -10,22 +7,19 @@ from .QLabelPopupInfo import QLabelPopupInfo
class QLabelPopupInfoCSWInfoLabel(QCSWControl):
"""
Implements lib_csw.InfoLabel control as QLabelPopupInfo
"""
def __init__(self, csw_info_label : lib_csw.InfoLabel.Client):
"""
Implements lib_csw.InfoLabel control as QLabelPopupInfo
"""
if not isinstance(csw_info_label, lib_csw.InfoLabel.Client):
raise ValueError('csw_error must be an instance of InfoLabel.Client')
super().__init__(csw_control=csw_info_label)
self._csw_info_label = csw_info_label
csw_info_label.call_on_config(self._on_csw_config)
label_popup_info = self._label_popup_info = QLabelPopupInfo()
self.setLayout(lib_qt.QXHBoxLayout([label_popup_info]))
self.hide()
super().__init__(csw_control=csw_info_label, layout=qtx.QXHBoxLayout([label_popup_info]))
def _on_csw_state_change(self, state):
super()._on_csw_state_change(state)

View file

@ -1,56 +1,48 @@
from pathlib import Path
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from resources.gfx import QXImageDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QPathEditCSWPaths(QCSWControl):
"""
Implements lib_csw.Paths control as LineEdit with Button to manage the Path
"""
def __init__(self, csw_path : lib_csw.Paths.Client, reflect_state_widgets=None):
"""
Implements lib_csw.Paths control as LineEdit with Button to manage the Path
"""
if not isinstance(csw_path, lib_csw.Paths.Client):
raise ValueError('csw_path must be an instance of Paths.Client')
super().__init__(csw_control=csw_path, reflect_state_widgets=reflect_state_widgets)
self._csw_path = csw_path
self._dlg = None
csw_path.call_on_config(self.on_csw_config)
csw_path.call_on_paths(self._on_csw_paths)
lineedit = self._lineedit = lib_qt.QXLineEdit(font=QXFontDB.get_fixedwidth_font(),
placeholder_text='...',
size_policy=(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed),
editingFinished=self.on_lineedit_editingFinished)
lineedit = self._lineedit = qtx.QXLineEdit(font=QXFontDB.get_fixedwidth_font(),
placeholder_text='...',
size_policy=('expanding', 'fixed'),
editingFinished=self.on_lineedit_editingFinished)
btn_open = self._btn_open = lib_qt.QXPushButton(image=QXImageDB.folder_open_outline(color='light gray'),
tooltip_text='Open',
released=self._on_btn_open_released,
fixed_size=(24,22) )
btn_open = self._btn_open = qtx.QXPushButton(image=QXImageDB.folder_open_outline(color='light gray'),
tooltip_text='Open',
released=self._on_btn_open_released,
fixed_size=(24,22) )
btn_reveal = self._btn_reveal = lib_qt.QXPushButton(image=QXImageDB.eye_outline(color='light gray'),
tooltip_text='Reveal in explorer',
released=self._on_btn_reveal_released,
fixed_size=(24,22) )
btn_reveal = self._btn_reveal = qtx.QXPushButton(image=QXImageDB.eye_outline(color='light gray'),
tooltip_text='Reveal in explorer',
released=self._on_btn_reveal_released,
fixed_size=(24,22) )
btn_erase = self._btn_erase = lib_qt.QXPushButton(image=QXImageDB.close_outline(color='light gray'),
tooltip_text='Erase',
released=self._on_btn_erase_released,
fixed_size=(24,22) )
main_l = lib_qt.QXHBoxLayout([lineedit, 2, btn_open, btn_reveal,btn_erase])
self.setLayout(lib_qt.QXHBoxLayout([
lib_qt.QXFrame(layout=main_l, size_policy=(QSizePolicy.Policy.Expanding,QSizePolicy.Policy.Fixed) )
]) )
self.hide()
btn_erase = self._btn_erase = qtx.QXPushButton(image=QXImageDB.close_outline(color='light gray'),
tooltip_text='Erase',
released=self._on_btn_erase_released,
fixed_size=(24,22) )
super().__init__(csw_control=csw_path, reflect_state_widgets=reflect_state_widgets,
layout=qtx.QXHBoxLayout([lineedit, 2, btn_open, btn_reveal, btn_erase]) )
def on_csw_config(self, cfg : lib_csw.Paths.Config):
type = cfg.get_type()
@ -65,20 +57,20 @@ class QPathEditCSWPaths(QCSWControl):
file_filter = f"{caption} ({' '.join(['*'+suf for suf in suffixes])})"
if type == lib_csw.Paths.Config.Type.ANY_FILE:
self._dlg = lib_qt.QXFileDialog(self,
self._dlg = qtx.QXFileDialog(self,
filter=file_filter,
existing_only=False,
is_save=is_save,
accepted=self._on_dlg_accepted)
elif type == lib_csw.Paths.Config.Type.EXISTING_FILE:
self._dlg = lib_qt.QXFileDialog(self,
self._dlg = qtx.QXFileDialog(self,
filter=file_filter,
existing_only=True,
is_save=is_save,
accepted=self._on_dlg_accepted)
elif type == lib_csw.Paths.Config.Type.EXISTING_FILES:
self._dlg = lib_qt.QXFileDialog(self,
self._dlg = qtx.QXFileDialog(self,
multi_files=True,
existing_only=True,
filter=file_filter,
@ -87,7 +79,7 @@ class QPathEditCSWPaths(QCSWControl):
directory = cfg.get_directory_path()
if directory is not None:
directory = str(directory)
self._dlg = lib_qt.QXDirDialog(self, caption=caption, directory=directory, accepted=self._on_dlg_accepted)
self._dlg = qtx.QXDirDialog(self, caption=caption, directory=directory, accepted=self._on_dlg_accepted)
def _on_dlg_accepted(self):
self._lineedit.setText( self._dlg.selectedFiles()[0] )
@ -101,7 +93,7 @@ class QPathEditCSWPaths(QCSWControl):
else:
raise NotImplementedError()
with lib_qt.BlockSignals(self._lineedit):
with qtx.BlockSignals(self._lineedit):
self._lineedit.setText(text)
def _on_btn_erase_released(self):
@ -122,7 +114,7 @@ class QPathEditCSWPaths(QCSWControl):
if dirpath.is_file():
dirpath = dirpath.parent
QDesktopServices.openUrl( QUrl.fromLocalFile(str(dirpath)) )
qtx.QDesktopServices.openUrl( qtx.QUrl.fromLocalFile(str(dirpath)) )
def on_lineedit_editingFinished(self):
text = self._lineedit.text()

View file

@ -1,39 +1,30 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QProgressBarCSWProgress(QCSWControl):
"""
"""
def __init__(self, csw_progress : lib_csw.Progress.Client):
if not isinstance(csw_progress, lib_csw.Progress.Client):
raise ValueError('csw_progress must be an instance of Progress.Client')
super().__init__(csw_control=csw_progress)
self._csw_progress = csw_progress
csw_progress.call_on_progress(self._on_csw_progress)
csw_progress.call_on_config(self._on_csw_config)
label_title = self._label_title = lib_qt.QXLabel('', word_wrap=True, hided=True)
progressbar = self._progressbar = lib_qt.QXProgressBar( min=0, max=100, font=QXFontDB.Digital7_Mono(11, italic=True) ) # ,, step=1, decimals=0, readonly=self._read_only, valueChanged=self._on_spinbox_valueChanged, editingFinished=self._on_spinbox_editingFinished)
label_title = self._label_title = qtx.QXLabel('', word_wrap=True, hided=True)
progressbar = self._progressbar = qtx.QXProgressBar( min=0, max=100, font=QXFontDB.Digital7_Mono(11, italic=True) )
self.setLayout( lib_qt.QXVBoxLayout([label_title, progressbar]) )
self.hide()
super().__init__(csw_control=csw_progress, layout=qtx.QXVBoxLayout([label_title, progressbar]) )
def _on_csw_progress(self, progress):
with lib_qt.BlockSignals(self._progressbar):
with qtx.BlockSignals(self._progressbar):
self._progressbar.setValue(progress)
def _on_csw_config(self, config : lib_csw.Progress.Config):
title = config.get_title()
if title is not None:

View file

@ -1,38 +1,32 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QSliderCSWNumber(QCSWControl):
"""
Implements lib_csw.Number control by Slider
"""
def __init__(self, csw_number: lib_csw.Number.Client, reflect_state_widgets=None):
"""
Implements lib_csw.Number control by Slider
"""
if not isinstance(csw_number, lib_csw.Number.Client):
raise ValueError('csw_number must be an instance of Number.Client')
super().__init__(csw_control=csw_number, reflect_state_widgets=reflect_state_widgets)
self._csw_number = csw_number
csw_number.call_on_number(self._on_csw_number)
csw_number.call_on_config(self._on_csw_config)
slider = self._slider = lib_qt.QXSlider(orientation=Qt.Orientation.Horizontal,
min=0,
max=0,
tick_position=QSlider.TickPosition.NoTicks,
tick_interval=1,
sliderReleased=self._on_slider_sliderReleased,
valueChanged=self._on_slider_valueChanged)
slider = self._slider = qtx.QXSlider(orientation=qtx.Qt.Orientation.Horizontal,
min=0,
max=0,
tick_position=qtx.QSlider.TickPosition.NoTicks,
tick_interval=1,
sliderReleased=self._on_slider_sliderReleased,
valueChanged=self._on_slider_valueChanged)
self.setLayout(lib_qt.QXVBoxLayout([slider]))
self.hide()
super().__init__(csw_control=csw_number, reflect_state_widgets=reflect_state_widgets,
layout=qtx.QXVBoxLayout([slider]))
def _on_csw_config(self, config : lib_csw.Number.Config):
self._config = config
@ -56,7 +50,7 @@ class QSliderCSWNumber(QCSWControl):
if value is not None:
config = self._config
value = (value-config.min) / config.step
with lib_qt.BlockSignals([self._slider]):
with qtx.BlockSignals([self._slider]):
self._slider.setValue(value)
def _set_csw_value(self):

View file

@ -1,65 +1,55 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QSliderCSWNumbers(QCSWControl):
"""
Implements controlable Slider with lib_csw.Number controls
"""
def __init__(self, csw_idx : lib_csw.Number.Client,
csw_idx_count : lib_csw.Number.Client,
):
"""
Implements controlable Slider with lib_csw.Number controls
"""
if not isinstance(csw_idx, lib_csw.Number.Client):
raise ValueError('csw_idx must be an instance of Number.Client')
if not isinstance(csw_idx_count, lib_csw.Number.Client):
raise ValueError('csw_idx_count must be an instance of Number.Client')
super().__init__(csw_control=csw_idx)
self._csw_idx = csw_idx
self._csw_idx_count = csw_idx_count
csw_idx.call_on_number(self._on_csw_idx)
csw_idx_count.call_on_number(self._on_csw_idx_count)
# Init UI
slider = self._slider = lib_qt.QXSlider(orientation=Qt.Orientation.Horizontal,
min=0,
max=0,
tick_position=QSlider.TickPosition.NoTicks,
tick_interval=1,
valueChanged=self._on_slider_valueChanged)
slider = self._slider = qtx.QXSlider(orientation=qtx.Qt.Orientation.Horizontal,
min=0,
max=0,
tick_position=qtx.QSlider.TickPosition.NoTicks,
tick_interval=1,
valueChanged=self._on_slider_valueChanged)
spinbox_font = QXFontDB.Digital7_Mono(11, italic=True)
spinbox_index = self._spinbox_index = lib_qt.QXSpinBox( font=spinbox_font, min=0, max=0, step=1, alignment=Qt.AlignmentFlag.AlignRight, button_symbols=QAbstractSpinBox.ButtonSymbols.NoButtons, editingFinished=self._on_spinbox_index_editingFinished)
spinbox_count = self._spinbox_count = lib_qt.QXSpinBox( font=spinbox_font, min=0, max=0, step=1, alignment=Qt.AlignmentFlag.AlignRight, button_symbols=QAbstractSpinBox.ButtonSymbols.NoButtons, readonly=True)
spinbox_index = self._spinbox_index = qtx.QXSpinBox( font=spinbox_font, min=0, max=0, step=1, alignment=qtx.AlignRight, button_symbols=qtx.QAbstractSpinBox.ButtonSymbols.NoButtons, editingFinished=self._on_spinbox_index_editingFinished)
spinbox_count = self._spinbox_count = qtx.QXSpinBox( font=spinbox_font, min=0, max=0, step=1, alignment=qtx.AlignRight, button_symbols=qtx.QAbstractSpinBox.ButtonSymbols.NoButtons, readonly=True)
main_l = lib_qt.QXVBoxLayout([
slider,
lib_qt.QXHBoxLayout([lib_qt.QXFrame(layout=lib_qt.QXHBoxLayout([spinbox_index, lib_qt.QXLabel(text='/', ), spinbox_count]),
size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) )])
])
self.setLayout(main_l)
self.hide()
super().__init__(csw_control=csw_idx,
layout=qtx.QXVBoxLayout([slider,
(qtx.QXFrameHBox([spinbox_index, qtx.QXLabel(text='/'), spinbox_count], size_policy=('fixed', 'fixed') ) , qtx.AlignCenter),
]) )
def _on_csw_idx(self, idx):
#print('_on_csw_idx', idx)
if idx is not None:
with lib_qt.BlockSignals([self._slider, self._spinbox_index]):
with qtx.BlockSignals([self._slider, self._spinbox_index]):
self._slider.setValue(idx+1)
self._spinbox_index.setValue(idx+1)
def _on_csw_idx_count(self, idx_count):
#print('_on_csw_idx_count', idx_count)
if idx_count is not None:
with lib_qt.BlockSignals([self._slider, self._spinbox_index, self._spinbox_count]):
with qtx.BlockSignals([self._slider, self._spinbox_index, self._spinbox_count]):
self._slider.setMinimum(1)
self._slider.setMaximum(idx_count)
self._spinbox_index.setMinimum(1)

View file

@ -1,23 +1,18 @@
from localization import L
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QSpinBoxCSWNumber(QCSWControl):
"""
Implements lib_csw.Number control as SpinBox
"""
def __init__(self, csw_number : lib_csw.Number.Client, reflect_state_widgets=None):
"""
Implements lib_csw.Number control as SpinBox
"""
if not isinstance(csw_number, lib_csw.Number.Client):
raise ValueError('csw_number must be an instance of Number.Client')
super().__init__(csw_control=csw_number, reflect_state_widgets=reflect_state_widgets)
self._csw_number = csw_number
self._instant_update = False
@ -27,16 +22,14 @@ class QSpinBoxCSWNumber(QCSWControl):
csw_number.call_on_number(self._on_csw_number)
csw_number.call_on_config(self._on_csw_config)
spinbox = self._spinbox = lib_qt.QXDoubleSpinBox( font=QXFontDB.Digital7_Mono(11, italic=True), min=0, max=999999999, step=1, decimals=0, readonly=self._read_only, valueChanged=self._on_spinbox_valueChanged, editingFinished=self._on_spinbox_editingFinished)
btn_auto = self._btn_auto = lib_qt.QXPushButton(text=L('@misc.auto'), hided=True, released=self._on_btn_auto_released, fixed_height=21)
spinbox = self._spinbox = qtx.QXDoubleSpinBox( font=QXFontDB.Digital7_Mono(11, italic=True), min=0, max=999999999, step=1, decimals=0, readonly=self._read_only, valueChanged=self._on_spinbox_valueChanged, editingFinished=self._on_spinbox_editingFinished)
btn_auto = self._btn_auto = qtx.QXPushButton(text=L('@misc.auto'), released=self._on_btn_auto_released, fixed_height=21, hided=True)
main_l = lib_qt.QXHBoxLayout([spinbox, 1, btn_auto])
self.setLayout(main_l)
self.hide()
super().__init__(csw_control=csw_number, reflect_state_widgets=reflect_state_widgets,
layout=qtx.QXHBoxLayout([spinbox, 1, btn_auto]) )
def _on_csw_number(self, number):
with lib_qt.BlockSignals(self._spinbox):
with qtx.BlockSignals(self._spinbox):
self._spinbox.setValue(number)
self._btn_auto_update()
@ -64,9 +57,9 @@ class QSpinBoxCSWNumber(QCSWControl):
self._read_only = cfg.read_only
self._spinbox.setReadOnly(cfg.read_only)
if cfg.read_only:
self._spinbox.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
self._spinbox.setButtonSymbols(qtx.QAbstractSpinBox.ButtonSymbols.NoButtons)
else:
self._spinbox.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.UpDownArrows)
self._spinbox.setButtonSymbols(qtx.QAbstractSpinBox.ButtonSymbols.UpDownArrows)
self._btn_auto_update()

View file

@ -1,32 +1,28 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from xlib import qt as lib_qt
from xlib import qt as qtx
from xlib.mp import csw as lib_csw
from .QCSWControl import QCSWControl
class QXPushButtonCSWSignal(QCSWControl):
"""
Implements lib_csw.Signal control as PushButton
"""
def __init__(self, csw_signal : lib_csw.Signal.Client, reflect_state_widgets=None,
image=None,
text=None, button_size=None, button_height=None,):
text=None, button_size=None, **kwargs):
"""
Implements lib_csw.Signal control as QXPushButton
"""
if not isinstance(csw_signal, lib_csw.Signal.Client):
raise ValueError('csw_signal must be an instance of Signal.Client')
super().__init__(csw_control=csw_signal, reflect_state_widgets=reflect_state_widgets)
self._csw_signal = csw_signal
# Init UI
btn = self._btn = lib_qt.QXPushButton(image=image, text=text, released=self.on_btn_released, minimum_size=button_size, minimum_height=button_height)
btn = self._btn = qtx.QXPushButton(image=image, text=text, released=self.on_btn_released, fixed_size=button_size)
main_l = lib_qt.QXHBoxLayout([btn])
self.setLayout(main_l)
self.hide()
super().__init__(csw_control=csw_signal, reflect_state_widgets=reflect_state_widgets,
layout=qtx.QXHBoxLayout([btn]), **kwargs)
def on_btn_released(self):
self._csw_signal.signal()
self._csw_signal.signal()

View file

@ -1,3 +1,22 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
AlignLeft = Qt.AlignmentFlag.AlignLeft
AlignLeading = Qt.AlignmentFlag.AlignLeading
AlignRight = Qt.AlignmentFlag.AlignRight
AlignTrailing = Qt.AlignmentFlag.AlignTrailing
AlignHCenter = Qt.AlignmentFlag.AlignHCenter
AlignJustify = Qt.AlignmentFlag.AlignJustify
AlignAbsolute = Qt.AlignmentFlag.AlignAbsolute
AlignHorizontal_Mask = Qt.AlignmentFlag.AlignHorizontal_Mask
AlignTop = Qt.AlignmentFlag.AlignTop
AlignBottom = Qt.AlignmentFlag.AlignBottom
AlignVCenter = Qt.AlignmentFlag.AlignVCenter
AlignVertical_Mask = Qt.AlignmentFlag.AlignVertical_Mask
AlignCenter = Qt.AlignmentFlag.AlignCenter
AlignBaseline = Qt.AlignmentFlag.AlignBaseline
from .core.QXTimeLine import QXTimeLine
from .core.QXTimer import QXTimer
from .core.widget import (BlockSignals, disable, enable, hide,
@ -16,6 +35,8 @@ from .widgets.QXDoubleSpinBox import QXDoubleSpinBox
from .widgets.QXFileDialog import QXFileDialog
from .widgets.QXFixedLayeredImages import QXFixedLayeredImages
from .widgets.QXFrame import QXFrame
from .widgets.QXFrameHBox import QXFrameHBox
from .widgets.QXFrameVBox import QXFrameVBox
from .widgets.QXGridLayout import QXGridLayout
from .widgets.QXHBoxLayout import QXHBoxLayout
from .widgets.QXHorizontalLine import QXHorizontalLine
@ -24,6 +45,7 @@ from .widgets.QXLineEdit import QXLineEdit
from .widgets.QXMainApplication import QXMainApplication
from .widgets.QXMenuBar import QXMenuBar
from .widgets.QXOpenGLWidget import QXOpenGLWidget
from .widgets.QXPopupWindow import QXPopupWindow
from .widgets.QXProgressBar import QXProgressBar
from .widgets.QXPushButton import QXPushButton
from .widgets.QXRadioButton import QXRadioButton
@ -31,9 +53,12 @@ from .widgets.QXSaveableComboBox import QXSaveableComboBox
from .widgets.QXScrollArea import QXScrollArea
from .widgets.QXSlider import QXSlider
from .widgets.QXSpinBox import QXSpinBox
from .widgets.QXSplashWindow import QXSplashWindow
from .widgets.QXTextEdit import QXTextEdit
from .widgets.QXToolButton import QXToolButton
from .widgets.QXVBoxLayout import QXVBoxLayout
from .widgets.QXVerticalLine import QXVerticalLine
from .widgets.QXWidget import QXWidget
from .widgets.QXWidgetHBox import QXWidgetHBox
from .widgets.QXWidgetVBox import QXWidgetVBox
from .widgets.QXWindow import QXWindow

View file

@ -6,17 +6,15 @@ from ._part_QXWidget import _part_QXWidget
class QXCheckBox(QCheckBox, _part_QXWidget):
def __init__(self, text=None, color=None, clicked=None, toggled=None, font=None, size_policy=None, hided=False, enabled=True):
def __init__(self, text=None, color=None, clicked=None, toggled=None, **kwargs):
super().__init__()
if text is not None:
self.setText(text)
if color is not None:
self.setStyleSheet(f'QCheckBox {{ color: {color};}}')
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(clicked, self.clicked)
_part_QXWidget.connect_signal(toggled, self.toggled)
_part_QXWidget.__init__(self, font=font, size_policy=size_policy, hided=hided, enabled=enabled )
if text is not None:
self.setText(text)
if color is not None:
self.setStyleSheet(f'QCheckBox {{ color: {color};}}')
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -7,7 +7,8 @@ from .QXHBoxLayout import QXHBoxLayout
from .QXLabel import QXLabel
from .QXToolButton import QXToolButton
from .QXVBoxLayout import QXVBoxLayout
from .QXFrameVBox import QXFrameVBox
from .QXFrameHBox import QXFrameHBox
class QXCollapsibleSection(QXFrame):
"""
@ -15,10 +16,8 @@ class QXCollapsibleSection(QXFrame):
Open/close state is saved to app db.
"""
def __init__(self, title, content_layout, vertical=False, is_opened=True, allow_open_close=True):
super().__init__()
self._is_opened = is_opened
self._vertical = vertical
@ -27,10 +26,9 @@ class QXCollapsibleSection(QXFrame):
label_title = self.label_title = QXLabel(text=title)
btn = self.btn = QXToolButton(checkable=True)
btn = self.btn = QXToolButton(checkable=True, checked=False)
btn.setStyleSheet('border: none;')
btn.setArrowType(Qt.ArrowType.RightArrow)
btn.setChecked(False)
if allow_open_close:
btn.toggled.connect(self.on_btn_toggled)
@ -38,23 +36,16 @@ class QXCollapsibleSection(QXFrame):
frame = self.frame = QXFrame(layout=content_layout, size_policy=(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding), hided=True)
if vertical:
main_l = QXHBoxLayout([ ( QXFrame(layout=
QXVBoxLayout([ (btn, Qt.AlignmentFlag.AlignTop),
(label_title, Qt.AlignmentFlag.AlignCenter)
]),
size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) ), Qt.AlignmentFlag.AlignTop),
frame ])
main_l = QXHBoxLayout([ ( QXFrameVBox([ (btn, Qt.AlignmentFlag.AlignTop),
(label_title, Qt.AlignmentFlag.AlignCenter)
], size_policy=('fixed', 'fixed') ), Qt.AlignmentFlag.AlignTop),
frame])
else:
main_l = QXVBoxLayout( [ ( QXFrame(layout=
QXHBoxLayout([ (btn, Qt.AlignmentFlag.AlignTop),
(label_title, Qt.AlignmentFlag.AlignCenter)
]),
size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) ) , Qt.AlignmentFlag.AlignTop),
frame])
self.setLayout(main_l)
main_l = QXVBoxLayout( [ ( QXFrameHBox([ (btn, Qt.AlignmentFlag.AlignTop),
(label_title, Qt.AlignmentFlag.AlignCenter)
], size_policy=('fixed', 'fixed')) , Qt.AlignmentFlag.AlignTop),
frame])
super().__init__(layout=main_l)
if self._is_opened:
self.open()

View file

@ -6,23 +6,11 @@ from ._part_QXWidget import _part_QXWidget
from typing import List
class QXComboBox(QComboBox, _part_QXWidget):
def __init__(self, choices : List[str] = None,
on_index_changed=None,
font=None, tooltip_text=None,
minimum_width=None, maximum_width=None, fixed_width=None, minimum_height=None, maximum_height=None, fixed_height=None, size_policy=None, hided=False, enabled=True):
def __init__(self, choices : List[str] = None, on_index_changed=None, **kwargs):
super().__init__()
if choices is not None:
for choice in choices:
self.addItem(choice)
[ self.addItem(choice) for choice in choices ] if choices is not None else []
_part_QXWidget.connect_signal(on_index_changed, self.currentIndexChanged)
_part_QXWidget.__init__(self, font=font, tooltip_text=tooltip_text,
size_policy=size_policy,
minimum_width=minimum_width, maximum_width=maximum_width,
minimum_height=minimum_height, maximum_height=maximum_height,
fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
_part_QXWidget.__init__(self, **kwargs)
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -6,8 +6,11 @@ from ._part_QXWidget import _part_QXWidget
class QXDoubleSpinBox(QDoubleSpinBox, _part_QXWidget):
def __init__(self, min=None, max=None, step=None, decimals=None, readonly=False, special_value_text=None, color=None, alignment=None, editingFinished=None, valueChanged=None, font=None, size_policy=None, hided=False, enabled=True):
def __init__(self, min=None, max=None, step=None, decimals=None, readonly=False, special_value_text=None, color=None, alignment=None, editingFinished=None, valueChanged=None, **kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
if min is not None:
self.setMinimum(min)
@ -27,11 +30,6 @@ class QXDoubleSpinBox(QDoubleSpinBox, _part_QXWidget):
if color is not None:
self.setStyleSheet(f'QDoubleSpinBox {{ color: {color};}}\n QDoubleSpinBox::disabled {{ color: dark-gray;}}')
_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
_part_QXWidget.__init__(self, font=font, size_policy=size_policy, hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -14,10 +14,10 @@ class QXFixedLayeredImages(QXWidget):
all images must have the same aspect ratio
"""
def __init__(self, fixed_width, fixed_height):
def __init__(self, fwidth, height):
super().__init__()
self._fixed_width = fixed_width
self._fixed_height = fixed_height
self._fwidth = fwidth
self._height = height
self._qp = QPainter()
self._images : List = []
@ -44,7 +44,7 @@ class QXFixedLayeredImages(QXWidget):
self.update()
def sizeHint(self):
return QSize(self._fixed_width, self._fixed_height)
return QSize(self._fwidth, self._height)
def paintEvent(self, event):
super().paintEvent(event)
@ -53,8 +53,8 @@ class QXFixedLayeredImages(QXWidget):
qp.begin(self)
qp.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
w = self._fixed_width
h = self._fixed_height
w = self._fwidth
h = self._height
w_half = w /2
h_half = h /2

View file

@ -3,18 +3,11 @@ from PyQt6.QtWidgets import *
from ._part_QXWidget import _part_QXWidget
from .QXMainApplication import QXMainApplication
from .QXWidget import QXWidget
class QXFrame(QFrame, _part_QXWidget):
def __init__(self, bg_color=None, layout=None, minimum_width=None, maximum_width=None, fixed_width=None, minimum_height=None, maximum_height=None, fixed_height=None, size_policy=None, hided=False, enabled=True):
QFrame.__init__(self)
_part_QXWidget.__init__(self, layout=layout,
size_policy=size_policy,
minimum_width=minimum_width, maximum_width=maximum_width,
minimum_height=minimum_height, maximum_height=maximum_height,
fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
class QXFrame(QXWidget):
def __init__(self, bg_color=None, **kwargs):
super().__init__(**kwargs)
pal = QXMainApplication.get_singleton().palette()
@ -37,10 +30,7 @@ class QXFrame(QFrame, _part_QXWidget):
_part_QXWidget.resizeEvent(self, ev)
def paintEvent(self, ev : QPaintEvent):
rect = self.rect()
qp = self._qp
qp.begin(self)
qp.fillRect(rect, self._bg_color )
qp.fillRect(self.rect(), self._bg_color )
qp.end()

View file

@ -0,0 +1,9 @@
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from .QXFrame import QXFrame
from .QXHBoxLayout import QXHBoxLayout
class QXFrameHBox(QXFrame):
def __init__(self, widgets=None, contents_margins=0, spacing=0, **kwargs):
super().__init__(layout=QXHBoxLayout(widgets=widgets, contents_margins=contents_margins, spacing=spacing), **kwargs)

View file

@ -0,0 +1,9 @@
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from .QXFrame import QXFrame
from .QXVBoxLayout import QXVBoxLayout
class QXFrameVBox(QXFrame):
def __init__(self, widgets=None, contents_margins=0, spacing=0, **kwargs):
super().__init__(layout=QXVBoxLayout(widgets=widgets, contents_margins=contents_margins, spacing=spacing), **kwargs)

View file

@ -8,6 +8,6 @@ class QXHorizontalLine(QXLabel):
color=None):
super().__init__(size_policy=(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed),
fixed_height=thickness )
fixed_size=(None,thickness) )
if color is not None:
self.setStyleSheet(f'background: {color};')

View file

@ -1,4 +1,4 @@
from typing import Union, Any
from typing import Any, Union
from PyQt6.QtCore import *
from PyQt6.QtGui import *
@ -9,22 +9,14 @@ from ._part_QXWidget import _part_QXWidget
class QXLabel(QLabel, _part_QXWidget):
def __init__(self, text = None,
color = None,
image : QXImage = None,
movie = None,
word_wrap = False, scaled_contents = False,
font=None, tooltip_text=None,
size_policy=None,
minimum_size=None, minimum_width=None, minimum_height=None,
maximum_size=None, maximum_width=None, maximum_height=None,
fixed_size=None, fixed_width=None, fixed_height=None,
hided=False, enabled=True
):
def __init__(self, text = None,
color = None,
image : QXImage = None,
movie = None,
word_wrap = False, scaled_contents = False,
**kwargs):
super().__init__()
self._default_pal = QPalette( self.palette() )
_part_QXWidget.__init__(self, **kwargs)
if text is not None:
self.setText(text)
@ -36,15 +28,10 @@ class QXLabel(QLabel, _part_QXWidget):
self.setWordWrap(True)
self.setScaledContents(scaled_contents)
self._default_pal = QPalette( self.palette() )
self.set_color(color)
_part_QXWidget.__init__(self, font=font, tooltip_text=tooltip_text,
size_policy=size_policy,
minimum_size=minimum_size, minimum_width=minimum_width, minimum_height=minimum_height,
maximum_size=maximum_size, maximum_width=maximum_width, maximum_height=maximum_height,
fixed_size=fixed_size, fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
def _update_color(self):
if self._color is not None:
pal = QPalette(self._default_pal)
@ -53,18 +40,15 @@ class QXLabel(QLabel, _part_QXWidget):
else:
self.setPalette(self._default_pal)
def set_color(self, color : Union[Any,None] ):
self._color = QColor(color) if color is not None else None
self._update_color()
def changeEvent(self, ev : QEvent):
super().changeEvent(ev)
if ev.type() == QEvent.Type.EnabledChange:
self._update_color()
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)
_part_QXWidget.focusInEvent(self, ev)

View file

@ -10,20 +10,18 @@ class QXLineEdit(QLineEdit, _part_QXWidget):
style_sheet=None,
read_only=False,
editingFinished=None,
font=None, size_policy=None, hided=False, enabled=True):
**kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
if placeholder_text is not None:
self.setPlaceholderText(placeholder_text)
if style_sheet is not None:
self.setStyleSheet(style_sheet)
if read_only:
self.setReadOnly(True)
_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
_part_QXWidget.__init__(self, font=font, size_policy=size_policy, hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)
_part_QXWidget.focusInEvent(self, ev)

View file

@ -5,17 +5,9 @@ from ._part_QXWidget import _part_QXWidget
class QXMenuBar(QMenuBar, _part_QXWidget):
def __init__(self,
font=None, size_policy=None, minimum_width=None, maximum_width=None, fixed_width=None, minimum_height=None, maximum_height=None, fixed_height=None, hided=False, enabled=True):
def __init__(self, **kwargs):
QMenuBar.__init__(self)
_part_QXWidget.__init__(self, font=font,
size_policy=size_policy,
minimum_width=minimum_width, maximum_width=maximum_width,
minimum_height=minimum_height, maximum_height=maximum_height,
fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
_part_QXWidget.__init__(self, **kwargs)
self.setStyleSheet(f"""
QMenuBar {{
border: 0px;

View file

@ -5,43 +5,13 @@ from PyQt6.QtWidgets import *
from ._part_QXWidget import _part_QXWidget
_size_policy_from_str = {
'fixed' : QSizePolicy.Policy.Fixed,
'minimum' : QSizePolicy.Policy.Minimum,
'maximum' : QSizePolicy.Policy.Maximum,
'preferred' : QSizePolicy.Policy.Preferred,
'minimumexpanding' : QSizePolicy.Policy.MinimumExpanding,
'expanding' : QSizePolicy.Policy.Expanding,
'ignored' : QSizePolicy.Policy.Ignored,
}
class QXOpenGLWidget(QOpenGLWidget, _part_QXWidget):
def __init__(self,
font=None, tooltip_text=None,
size_policy=None,
minimum_size=None, minimum_width=None, minimum_height=None,
maximum_size=None, maximum_width=None, maximum_height=None,
fixed_size=None, fixed_width=None, fixed_height=None,
hided=False, enabled=True
):
def __init__(self, **kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
self._default_pal = QPalette( self.palette() )
if size_policy is not None:
x1, x2 = size_policy
if isinstance(x1, str):
x1 = _size_policy_from_str[x1.lower()]
if isinstance(x2, str):
x2 = _size_policy_from_str[x2.lower()]
size_policy = (x1, x2)
_part_QXWidget.__init__(self, font=font, tooltip_text=tooltip_text,
size_policy=size_policy,
minimum_size=minimum_size, minimum_width=minimum_width, minimum_height=minimum_height,
maximum_size=maximum_size, maximum_width=maximum_width, maximum_height=maximum_height,
fixed_size=fixed_size, fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)
_part_QXWidget.focusInEvent(self, ev)

View file

@ -0,0 +1,13 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from .QXWindow import QXWindow
class QXPopupWindow(QXWindow):
def __init__(self, **kwargs):
"""
represents top widget which has no parent
"""
super().__init__(**kwargs)
self.setWindowFlags(Qt.WindowType.Popup)

View file

@ -6,18 +6,14 @@ from ._part_QXWidget import _part_QXWidget
class QXProgressBar(QProgressBar, _part_QXWidget):
def __init__(self, min=None,
max=None,
valueChanged=None,
font=None, size_policy=None, hided=False, enabled=True, ):
def __init__(self, min=None, max=None, valueChanged=None, **kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
if min is not None:
self.setMinimum(min)
if max is not None:
self.setMaximum(max)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
_part_QXWidget.__init__(self, font=font, size_policy=size_policy, hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -11,18 +11,16 @@ class QXPushButton(QPushButton, _part_QXWidget):
def __init__(self, image : QXImage = None, flat=False,
text=None, padding=4, checkable=False,
toggled=None, released=None,
font=None, tooltip_text=None, size_policy=None,
minimum_size=None, minimum_width=None, minimum_height=None,
fixed_size=None, fixed_width=None, fixed_height=None, hided=False, enabled=True
):
**kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(released, self.released)
_part_QXWidget.connect_signal(toggled, self.toggled)
self._image = None
self._image_sequence = None
self._tl = None
if size_policy is None:
size_policy = (QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
if text is not None:
self.setText(text)
@ -39,7 +37,6 @@ QPushButton {{
padding: {padding}px;
}}
QPushButton:hover {{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #434343, stop: 0.3 #515151, stop: 0.6 #515151, stop: 1.0 #434343);
@ -49,16 +46,8 @@ QPushButton:pressed {{
}}
""")
_part_QXWidget.connect_signal(released, self.released)
_part_QXWidget.connect_signal(toggled, self.toggled)
_part_QXWidget.__init__(self, font=font, tooltip_text=tooltip_text,
size_policy=size_policy, minimum_size=minimum_size, minimum_width=minimum_width, minimum_height=minimum_height,
fixed_size=fixed_size, fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
def sizeHint(self) -> QSize:
return QSize(0,0)
#def sizeHint(self) -> QSize:
# return QSize(0,0)
def setText(self, text):
QPushButton.setText(self, text)
@ -73,27 +62,30 @@ QPushButton:pressed {{
if self._image is not None:
rect = self.rect()
image = self._image
w, h = rect.width(), rect.height()
rect_aspect = w / h
size = image.size()
pixmap_aspect = size.width() / size.height()
if h != 0:
rect_aspect = w / h
if pixmap_aspect != rect_aspect:
if pixmap_aspect > rect_aspect:
pw, ph = w, int(h * (rect_aspect / pixmap_aspect))
px, py = 0, h/2-ph/2
elif pixmap_aspect < rect_aspect:
pw, ph = int( w * (pixmap_aspect / rect_aspect) ), h
px, py = w/2-pw/2, 0
else:
px, py, pw, ph = 0, 0, w, h
self.setIconSize( QSize(pw-4,ph-4) )
size = image.size()
pixmap_aspect = size.width() / size.height()
if pixmap_aspect != rect_aspect:
if pixmap_aspect > rect_aspect:
pw, ph = w, int(h * (rect_aspect / pixmap_aspect))
px, py = 0, h/2-ph/2
elif pixmap_aspect < rect_aspect:
pw, ph = int( w * (pixmap_aspect / rect_aspect) ), h
px, py = w/2-pw/2, 0
else:
px, py, pw, ph = 0, 0, w, h
self.setIconSize( QSize(pw-4,ph-4) )
def _set_image(self, image : QXImage ):
self._image = image
self.setIcon( image.as_QIcon() )
self._update_icon_size()
def set_image(self, image : QXImage ):
self.stop_image_sequence()
@ -128,5 +120,4 @@ QPushButton:pressed {{
def resizeEvent(self, ev : QResizeEvent):
super().resizeEvent(ev)
_part_QXWidget.resizeEvent(self, ev)
self._update_icon_size()

View file

@ -10,8 +10,12 @@ class QXRadioButton(QRadioButton, _part_QXWidget):
disabled_color=None,
auto_exclusive=False,
clicked=None, toggled=None,
font=None, size_policy=None, hided=False, enabled=True):
**kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(clicked, self.clicked)
_part_QXWidget.connect_signal(toggled, self.toggled)
if text is not None:
self.setText(text)
self.setAutoExclusive(auto_exclusive)
@ -23,10 +27,6 @@ class QXRadioButton(QRadioButton, _part_QXWidget):
if len(style_sheet) != 0:
self.setStyleSheet(style_sheet)
_part_QXWidget.connect_signal(clicked, self.clicked)
_part_QXWidget.connect_signal(toggled, self.toggled)
_part_QXWidget.__init__(self, font=font, size_policy=size_policy, hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)
_part_QXWidget.focusInEvent(self, ev)

View file

@ -6,14 +6,9 @@ from ._part_QXWidget import _part_QXWidget
class QXScrollArea(QScrollArea, _part_QXWidget):
def __init__(self,
size_policy=None, hided=False, enabled=True):
def __init__(self, **kwargs):
super().__init__()
_part_QXWidget.__init__(self, size_policy=size_policy, hided=hided, enabled=enabled )
_part_QXWidget.__init__(self, **kwargs)
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -15,11 +15,16 @@ class QXSlider(QSlider, _part_QXWidget):
sliderMoved=None,
sliderPressed=None,
sliderReleased=None,
size_policy=None, hided=False, enabled=True):
**kwargs):
if orientation is not None:
super().__init__(orientation)
else:
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
_part_QXWidget.connect_signal(sliderMoved, self.sliderMoved)
_part_QXWidget.connect_signal(sliderPressed, self.sliderPressed)
_part_QXWidget.connect_signal(sliderReleased, self.sliderReleased)
if min is not None:
self.setMinimum(min)
@ -30,13 +35,6 @@ class QXSlider(QSlider, _part_QXWidget):
if tick_interval is not None:
self.setTickInterval(tick_interval)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
_part_QXWidget.connect_signal(sliderMoved, self.sliderMoved)
_part_QXWidget.connect_signal(sliderPressed, self.sliderPressed)
_part_QXWidget.connect_signal(sliderReleased, self.sliderReleased)
_part_QXWidget.__init__(self, size_policy=size_policy, hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)
_part_QXWidget.focusInEvent(self, ev)

View file

@ -14,8 +14,13 @@ class QXSpinBox(QSpinBox, _part_QXWidget):
alignment=None,
button_symbols=None, readonly=False,
editingFinished=None, textChanged=None, valueChanged=None,
font=None, size_policy=None, hided=False, enabled=True):
**kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
_part_QXWidget.connect_signal(textChanged, self.textChanged)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
if min is not None:
self.setMinimum(min)
if max is not None:
@ -33,12 +38,6 @@ class QXSpinBox(QSpinBox, _part_QXWidget):
if color is not None:
self.setStyleSheet(f'QSpinBox {{ color: {color};}}')
_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
_part_QXWidget.connect_signal(textChanged, self.textChanged)
_part_QXWidget.connect_signal(valueChanged, self.valueChanged)
_part_QXWidget.__init__(self, font=font, size_policy=size_policy, hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)
_part_QXWidget.focusInEvent(self, ev)

View file

@ -0,0 +1,13 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from .QXWindow import QXWindow
class QXSplashWindow(QXWindow):
def __init__(self, **kwargs):
"""
represents top widget which has no parent
"""
super().__init__(**kwargs)
self.setWindowFlags(Qt.WindowType.SplashScreen)

View file

@ -9,31 +9,17 @@ class QXTextEdit(QTextEdit, _part_QXWidget):
def __init__(self, placeholder_text=None,
style_sheet=None,
read_only=False,
font=None, tooltip_text=None,
size_policy=None,
minimum_size=None, minimum_width=None, minimum_height=None,
maximum_size=None, maximum_width=None, maximum_height=None,
fixed_size=None, fixed_width=None, fixed_height=None,
hided=False, enabled=True
):
**kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
#_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
if placeholder_text is not None:
self.setPlaceholderText(placeholder_text)
if style_sheet is not None:
self.setStyleSheet(style_sheet)
if read_only:
self.setReadOnly(True)
self.setWordWrapMode
#_part_QXWidget.connect_signal(editingFinished, self.editingFinished)
_part_QXWidget.__init__(self, font=font, tooltip_text=tooltip_text,
size_policy=size_policy,
minimum_size=minimum_size, minimum_width=minimum_width, minimum_height=minimum_height,
maximum_size=maximum_size, maximum_width=maximum_width, maximum_height=maximum_height,
fixed_size=fixed_size, fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -6,22 +6,22 @@ from ._part_QXWidget import _part_QXWidget
class QXToolButton(QToolButton, _part_QXWidget):
def __init__(self, text=None,
checkable=False,
checked=None,
toggled=None, released=None,
font=None, size_policy=None, hided=False, enabled=True):
**kwargs):
super().__init__()
_part_QXWidget.__init__(self, **kwargs)
_part_QXWidget.connect_signal(released, self.released)
_part_QXWidget.connect_signal(toggled, self.toggled)
if text is not None:
self.setText(text)
self.setCheckable(checkable)
_part_QXWidget.connect_signal(released, self.released)
_part_QXWidget.connect_signal(toggled, self.toggled)
_part_QXWidget.__init__(self, font=font, size_policy=size_policy, hided=hided, enabled=enabled )
if checked is not None:
self.setChecked(checked)
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -6,6 +6,6 @@ from .QXLabel import QXLabel
class QXVerticalLine(QXLabel):
def __init__(self, thickness=1, color=None):
super().__init__(size_policy=(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Expanding),
fixed_width=thickness)
fixed_size=(thickness,None) )
if color is not None:
self.setStyleSheet(f'background: {color.name()};')

View file

@ -6,20 +6,11 @@ from ._part_QXWidget import _part_QXWidget
class QXWidget(QWidget, _part_QXWidget):
"""
"""
def __init__(self, layout=None, font=None, tooltip_text=None,
minimum_width=None, maximum_width=None, fixed_width=None, minimum_height=None, maximum_height=None, fixed_height=None, size_policy=None, hided=False, enabled=True):
def __init__(self, **kwargs):
"""
"""
super().__init__()
_part_QXWidget.__init__(self, layout=layout, font=font, tooltip_text=tooltip_text,
size_policy=size_policy,
minimum_width=minimum_width, maximum_width=maximum_width,
minimum_height=minimum_height, maximum_height=maximum_height,
fixed_width=fixed_width, fixed_height=fixed_height,
hided=hided, enabled=enabled )
_part_QXWidget.__init__(self, **kwargs)
def focusInEvent(self, ev : QFocusEvent):
super().focusInEvent(ev)

View file

@ -0,0 +1,9 @@
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from .QXWidget import QXWidget
from .QXHBoxLayout import QXHBoxLayout
class QXWidgetHBox(QXWidget):
def __init__(self, widgets=None, contents_margins=0, spacing=0, **kwargs):
super().__init__(layout=QXHBoxLayout(widgets=widgets, contents_margins=contents_margins, spacing=spacing), **kwargs)

View file

@ -0,0 +1,9 @@
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from .QXWidget import QXWidget
from .QXVBoxLayout import QXVBoxLayout
class QXWidgetVBox(QXWidget):
def __init__(self, widgets=None, contents_margins=0, spacing=0, **kwargs):
super().__init__(layout=QXVBoxLayout(widgets=widgets, contents_margins=contents_margins, spacing=spacing), **kwargs)

View file

@ -9,15 +9,11 @@ from .QXWidget import QXWidget
class QXWindow(QXWidget):
"""
represents top widget which has no parent
"""
def __init__(self, save_load_state=False,
size_policy=None):
super().__init__(size_policy=size_policy)
def __init__(self, save_load_state=False, **kwargs):
"""
represents top widget which has no parent
"""
super().__init__(**kwargs)
self._save_load_state = save_load_state
#QXMainApplication.get_singleton().register_QXWindow(self)

View file

@ -1,18 +1,28 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from ..core.widget import BlockSignals
from .QXMainApplication import QXMainApplication
_size_policy_from_str = {
'fixed' : QSizePolicy.Policy.Fixed,
'minimum' : QSizePolicy.Policy.Minimum,
'maximum' : QSizePolicy.Policy.Maximum,
'preferred' : QSizePolicy.Policy.Preferred,
'minimumexpanding' : QSizePolicy.Policy.MinimumExpanding,
'expanding' : QSizePolicy.Policy.Expanding,
'ignored' : QSizePolicy.Policy.Ignored,
}
class _part_QXWidget:
def __init__(self, layout=None,
font=None,
tooltip_text=None,
size_policy=None,
minimum_size=None, minimum_width=None, minimum_height=None,
maximum_size=None, maximum_width=None, maximum_height=None,
fixed_size=None, fixed_width=None, fixed_height=None,
minimum_width=None, maximum_width=None, fixed_width=None,
minimum_height=None, maximum_height=None, fixed_height=None,
minimum_size=None, maximum_size=None, fixed_size=None,
hided=False, enabled=True):
self._registered = False
@ -23,8 +33,16 @@ class _part_QXWidget:
self.setFont(font)
if tooltip_text is not None:
self.setToolTip(tooltip_text)
if size_policy is not None:
x1, x2 = size_policy
if isinstance(x1, str):
x1 = _size_policy_from_str[x1.lower()]
if isinstance(x2, str):
x2 = _size_policy_from_str[x2.lower()]
size_policy = (x1, x2)
self.setSizePolicy(*size_policy)
if layout is not None:
self.setLayout(layout)
@ -41,7 +59,7 @@ class _part_QXWidget:
self.setMaximumWidth(maximum_width)
if maximum_height is not None:
self.setMaximumHeight(maximum_height)
if fixed_size is not None:
fixed_width, fixed_height = fixed_size
if fixed_width is not None: