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()