总线通信架构整改完成
This commit is contained in:
		
							
								
								
									
										0
									
								
								toolbox/codes/ui/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toolbox/codes/ui/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								toolbox/codes/ui/components/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toolbox/codes/ui/components/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										45
									
								
								toolbox/codes/ui/components/list_widget_ui.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								toolbox/codes/ui/components/list_widget_ui.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
from PySide6.QtGui import QFocusEvent
 | 
			
		||||
from PySide6.QtWidgets import QListWidget, QListWidgetItem
 | 
			
		||||
from PySide6.QtCore import Qt, QEvent
 | 
			
		||||
 | 
			
		||||
from codes.common import clibs
 | 
			
		||||
from codes.common.signal_bus import signal_bus
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SListWidget(QListWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.init_ui()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def init_ui(self):
 | 
			
		||||
        for item in clibs.listW_items:
 | 
			
		||||
            _ = QListWidgetItem(item)
 | 
			
		||||
            _.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
			
		||||
            self.addItem(_)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        self.itemClicked.connect(self.item_clicked)
 | 
			
		||||
        signal_bus.qa_stacked_page_switch.connect(self.hide)
 | 
			
		||||
        signal_bus.list_widget_on_off.connect(self.lw_show_hide)
 | 
			
		||||
 | 
			
		||||
    def item_clicked(self, item):
 | 
			
		||||
        page_id = clibs.listW_items[item.text()]
 | 
			
		||||
        signal_bus.list_widget_click.emit(page_id)
 | 
			
		||||
 | 
			
		||||
    def lw_show_hide(self, enabled: bool):
 | 
			
		||||
        if enabled:
 | 
			
		||||
            self.clearSelection()
 | 
			
		||||
            self.show()
 | 
			
		||||
            signal_bus.init_stacked_page.emit("w10_practical")
 | 
			
		||||
        else:
 | 
			
		||||
            self.hide()
 | 
			
		||||
 | 
			
		||||
    def focusOutEvent(self, event: QFocusEvent):
 | 
			
		||||
        self.clearSelection()
 | 
			
		||||
        super().focusOutEvent(event)
 | 
			
		||||
							
								
								
									
										62
									
								
								toolbox/codes/ui/components/stacked_widget_ui.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								toolbox/codes/ui/components/stacked_widget_ui.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
import importlib.util
 | 
			
		||||
 | 
			
		||||
from PySide6.QtWidgets import QStackedWidget, QWidget, QLabel
 | 
			
		||||
from PySide6.QtCore import Qt
 | 
			
		||||
 | 
			
		||||
from codes.common import clibs
 | 
			
		||||
from codes.common.signal_bus import signal_bus
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SStackedWidget(QStackedWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.init_ui()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        self.page_list = {}
 | 
			
		||||
 | 
			
		||||
    def init_ui(self):
 | 
			
		||||
        # stacked widget  1x: 10为一级按钮页,其余为二级按钮页,2-9同理 | 0x. 日志/设置/关于等页面
 | 
			
		||||
        self.load_pages()
 | 
			
		||||
        w = self.page_list.get("w01_setting")
 | 
			
		||||
        self.setCurrentWidget(w)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        signal_bus.init_stacked_page.connect(self.set_current_page)
 | 
			
		||||
        signal_bus.qa_stacked_page_switch.connect(self.set_current_page)
 | 
			
		||||
        signal_bus.list_widget_click.connect(self.set_current_page)
 | 
			
		||||
 | 
			
		||||
    def set_current_page(self, page_id: str):
 | 
			
		||||
        w = self.page_list.get(page_id)
 | 
			
		||||
        self.setCurrentWidget(w)
 | 
			
		||||
        signal_bus.current_stacked_page.emit(page_id)
 | 
			
		||||
 | 
			
		||||
    def load_pages(self):
 | 
			
		||||
        def to_camel(snake: str) -> str:
 | 
			
		||||
            # w01_setting -> W01Setting
 | 
			
		||||
            return "".join(word.capitalize() for word in snake.split('_'))
 | 
			
		||||
 | 
			
		||||
        def instantiate(pyFile: Path, className: str) -> QWidget | None:
 | 
			
		||||
            try:
 | 
			
		||||
                spec = importlib.util.spec_from_file_location(pyFile.stem, pyFile)
 | 
			
		||||
                module = importlib.util.module_from_spec(spec)
 | 
			
		||||
                spec.loader.exec_module(module)
 | 
			
		||||
                cls = getattr(module, className)
 | 
			
		||||
                if issubclass(cls, QWidget):
 | 
			
		||||
                    return cls()
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                print(f"加载 {pyFile} 失败: {e}")
 | 
			
		||||
 | 
			
		||||
        pages_dir = clibs.base_path / "codes/ui/stacked_pages/"
 | 
			
		||||
        for py_file in pages_dir.glob("w*.py"):
 | 
			
		||||
            page_id = py_file.stem          # w01_setting
 | 
			
		||||
            class_name = to_camel(page_id)  # W01Setting
 | 
			
		||||
            widget = instantiate(py_file, class_name)
 | 
			
		||||
            if widget:
 | 
			
		||||
                widget.setObjectName(page_id)    # 用于 findChild / 切换
 | 
			
		||||
                self.addWidget(widget)
 | 
			
		||||
                self.page_list[page_id] = widget
 | 
			
		||||
							
								
								
									
										0
									
								
								toolbox/codes/ui/components/statusbar_ui.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toolbox/codes/ui/components/statusbar_ui.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										110
									
								
								toolbox/codes/ui/components/toolbar_ui.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								toolbox/codes/ui/components/toolbar_ui.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
from PySide6.QtWidgets import QToolBar
 | 
			
		||||
from PySide6.QtGui import QAction, QIcon
 | 
			
		||||
from PySide6.QtCore import QSize
 | 
			
		||||
 | 
			
		||||
from codes.common import clibs
 | 
			
		||||
from codes.common.signal_bus import signal_bus
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SToolBar(QToolBar):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.init_ui()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def init_ui(self):
 | 
			
		||||
        # switch
 | 
			
		||||
        self.on_icon  = QIcon(f"{clibs.base_path}/assets/media/switch_on.png")   # 开状态图标
 | 
			
		||||
        self.off_icon = QIcon(f"{clibs.base_path}/assets/media/switch_off.png")  # 关状态图标
 | 
			
		||||
        self.ac_switch = QAction(self.on_icon, "", self)
 | 
			
		||||
        self.ac_switch.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_switch.setStatusTip("Switch side bar")
 | 
			
		||||
        self.ac_switch.setToolTip("Ctrl+Alt+T")
 | 
			
		||||
        self.ac_switch.setCheckable(True)          # 二态
 | 
			
		||||
        self.ac_switch.setChecked(True)
 | 
			
		||||
        self.ac_switch.setObjectName("acSwitch")
 | 
			
		||||
        self.setIconSize(QSize(30, 30))  # ← 一行决定图标像素
 | 
			
		||||
        self.addAction(self.ac_switch)
 | 
			
		||||
        btn = self.widgetForAction(self.ac_switch)  # 取出实际 QToolButton
 | 
			
		||||
        btn.setStyleSheet("""
 | 
			
		||||
            QToolButton {
 | 
			
		||||
                background: transparent;
 | 
			
		||||
                border: none;
 | 
			
		||||
                outline: none;
 | 
			
		||||
            }
 | 
			
		||||
            /* 所有伪状态都透明,不让 Qt 画实心矩形 */
 | 
			
		||||
            QToolButton::hover,
 | 
			
		||||
            QToolButton::pressed,
 | 
			
		||||
            QToolButton::checked {
 | 
			
		||||
                background: transparent;
 | 
			
		||||
                border: none;
 | 
			
		||||
                outline: none;
 | 
			
		||||
            }
 | 
			
		||||
        """)
 | 
			
		||||
 | 
			
		||||
        # homepage
 | 
			
		||||
        self.ac_homepage = QAction()
 | 
			
		||||
        self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_homepage.setStatusTip("Go to home page")
 | 
			
		||||
        self.ac_homepage.setToolTip("Ctrl+Alt+H")
 | 
			
		||||
        self.ac_homepage.setText("主页")
 | 
			
		||||
        self.addAction(self.ac_homepage)
 | 
			
		||||
 | 
			
		||||
        # setting
 | 
			
		||||
        self.ac_setting = QAction()
 | 
			
		||||
        self.ac_setting.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_setting.setStatusTip("Go to setting page")
 | 
			
		||||
        self.ac_setting.setToolTip("Ctrl+Alt+S")
 | 
			
		||||
        self.ac_setting.setText("设置")
 | 
			
		||||
        self.addAction(self.ac_setting)
 | 
			
		||||
 | 
			
		||||
        # log
 | 
			
		||||
        self.ac_log = QAction()
 | 
			
		||||
        self.ac_log.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_log.setStatusTip("Go to log page")
 | 
			
		||||
        self.ac_log.setToolTip("Ctrl+Alt+L")
 | 
			
		||||
        self.ac_log.setText("日志")
 | 
			
		||||
        self.addAction(self.ac_log)
 | 
			
		||||
 | 
			
		||||
        # about
 | 
			
		||||
        self.ac_about = QAction()
 | 
			
		||||
        self.ac_about.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_about.setStatusTip("Go to about page")
 | 
			
		||||
        self.ac_about.setToolTip("Ctrl+Alt+A")
 | 
			
		||||
        self.ac_about.setText("关于")
 | 
			
		||||
        self.addAction(self.ac_about)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        self.ac_switch.toggled.connect(self.ac_sw)
 | 
			
		||||
        self.ac_homepage.triggered.connect(self.ac_hp)
 | 
			
		||||
        self.ac_setting.triggered.connect(self.ac_sp)
 | 
			
		||||
        self.ac_log.triggered.connect(self.ac_lp)
 | 
			
		||||
        self.ac_about.triggered.connect(self.ac_ap)
 | 
			
		||||
        signal_bus.qa_stacked_page_switch.connect(self.change2hide)
 | 
			
		||||
 | 
			
		||||
    def ac_sw(self, checked: bool):
 | 
			
		||||
        self.ac_switch.setIcon(self.on_icon if checked else self.off_icon)
 | 
			
		||||
        print(f"checked: {checked}")
 | 
			
		||||
        signal_bus.list_widget_on_off.emit(checked)
 | 
			
		||||
 | 
			
		||||
    def ac_hp(self):
 | 
			
		||||
        signal_bus.home_overlay_trigger.emit()
 | 
			
		||||
 | 
			
		||||
    def ac_sp(self):
 | 
			
		||||
        signal_bus.qa_stacked_page_switch.emit("w01_setting")
 | 
			
		||||
 | 
			
		||||
    def ac_lp(self):
 | 
			
		||||
        signal_bus.qa_stacked_page_switch.emit("w08_log")
 | 
			
		||||
 | 
			
		||||
    def ac_ap(self):
 | 
			
		||||
        signal_bus.qa_stacked_page_switch.emit("w09_about")
 | 
			
		||||
 | 
			
		||||
    def change2hide(self):
 | 
			
		||||
        self.ac_switch.setChecked(False)
 | 
			
		||||
        self.ac_switch.setIcon(self.off_icon)
 | 
			
		||||
 | 
			
		||||
@@ -1,19 +1,23 @@
 | 
			
		||||
import sys
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QListWidget, QStackedWidget, QCheckBox, QSpinBox, QToolBox, QLineEdit, QTableWidget, QTreeWidget, QCalendarWidget, QMessageBox, QToolBar, QSizePolicy
 | 
			
		||||
from PySide6.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread
 | 
			
		||||
from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut
 | 
			
		||||
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QLineEdit, QMessageBox, QSizePolicy
 | 
			
		||||
from PySide6.QtCore import Qt, QSize
 | 
			
		||||
from PySide6.QtGui import QFont, QIcon, QPixmap, QShortcut
 | 
			
		||||
from codes.common import clibs, db_operation
 | 
			
		||||
from codes.common.secure_encrypt import PassCipher
 | 
			
		||||
from codes.ui import main_ui
 | 
			
		||||
from codes.common.exception_handler import handle_exception
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LoginWindow(QWidget):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.init_ui()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.le_username.setFocus()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        db_operation.db_init()
 | 
			
		||||
        db_operation.db_conn()
 | 
			
		||||
 | 
			
		||||
    def init_ui(self):
 | 
			
		||||
        self.setMinimumSize(420, 200)
 | 
			
		||||
@@ -23,21 +27,21 @@ class LoginWindow(QWidget):
 | 
			
		||||
        self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
 | 
			
		||||
        self.setFont(QFont("Consolas", 14))
 | 
			
		||||
 | 
			
		||||
        self.layout_outter = QHBoxLayout()
 | 
			
		||||
        self.layout_outer = QHBoxLayout()
 | 
			
		||||
        self.lb_logo = QLabel()
 | 
			
		||||
        self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
			
		||||
        self.lb_logo.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
 | 
			
		||||
        self.lb_logo.setPixmap(QPixmap(f"{clibs.base_path}/assets/media/logo.png"))
 | 
			
		||||
        self.lb_logo.setFixedSize(QSize(120, 120))
 | 
			
		||||
        self.lb_logo.setScaledContents(True)
 | 
			
		||||
        self.layout_outter.addWidget(self.lb_logo)
 | 
			
		||||
        self.layout_outer.addWidget(self.lb_logo)
 | 
			
		||||
 | 
			
		||||
        self.tabW_login = QTabWidget()
 | 
			
		||||
        self.tab_login = QWidget()
 | 
			
		||||
        self.tabW_login.addTab(self.tab_login, "登录")
 | 
			
		||||
        self.tab_register = QWidget()
 | 
			
		||||
        self.tabW_login.addTab(self.tab_register, "注册")
 | 
			
		||||
        self.layout_outter.addWidget(self.tabW_login)
 | 
			
		||||
        self.layout_outer.addWidget(self.tabW_login)
 | 
			
		||||
 | 
			
		||||
        # 登陆页面
 | 
			
		||||
        self.layout_H_username = QHBoxLayout()
 | 
			
		||||
@@ -110,7 +114,8 @@ class LoginWindow(QWidget):
 | 
			
		||||
        self.layout_V_user_pass_reg.addLayout(self.layout_H_button_reg)
 | 
			
		||||
        self.tab_register.setLayout(self.layout_V_user_pass_reg)
 | 
			
		||||
 | 
			
		||||
        self.setLayout(self.layout_outter)
 | 
			
		||||
        self.setLayout(self.layout_outer)
 | 
			
		||||
        self.le_username.setFocus()
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        self.tabW_login.currentChanged.connect(self.onChange_tabW)
 | 
			
		||||
@@ -118,15 +123,9 @@ class LoginWindow(QWidget):
 | 
			
		||||
        self.btn_cancel.clicked.connect(self.close)
 | 
			
		||||
        self.btn_login_reg.clicked.connect(self.register_check)
 | 
			
		||||
        self.btn_cancel_reg.clicked.connect(self.close)
 | 
			
		||||
        QShortcut("Esc", self).activated.connect(self.close)
 | 
			
		||||
        self.le_password.returnPressed.connect(self.login_check)
 | 
			
		||||
        self.le_password_reg_confirm.returnPressed.connect(self.register_check)
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        self.m = Path(__file__).stem
 | 
			
		||||
        db_file = clibs.base_path / "assets/database/toolbox.db"
 | 
			
		||||
        if not db_file.exists():
 | 
			
		||||
            db_operation.db_init(db_file)
 | 
			
		||||
        QShortcut("Esc", self).activated.connect(self.close)
 | 
			
		||||
 | 
			
		||||
    def onChange_tabW(self):
 | 
			
		||||
        text = self.tabW_login.tabText(self.tabW_login.currentIndex())
 | 
			
		||||
@@ -139,26 +138,25 @@ class LoginWindow(QWidget):
 | 
			
		||||
            self.le_password_reg.clear()
 | 
			
		||||
            self.le_password_reg_confirm.clear()
 | 
			
		||||
            self.le_username_reg.setFocus()
 | 
			
		||||
        else:
 | 
			
		||||
            raise Exception(f"Unknown TabWidget Name: {text}")
 | 
			
		||||
 | 
			
		||||
    @handle_exception()
 | 
			
		||||
    def login_check(self):
 | 
			
		||||
        def login_failed(exception: bool = False):
 | 
			
		||||
        def login_failed(flag: int = 0):
 | 
			
		||||
            reason = {-1: "用户名或密码为空", 0: "用户名未注册", 1: "解迷成功,密码错误", 2: "解迷失败,密码错误", 3: "数据库中有重复的用户名"}
 | 
			
		||||
            self.le_username.clear()
 | 
			
		||||
            self.le_password.clear()
 | 
			
		||||
            self.le_username.setFocus()
 | 
			
		||||
            if not exception:
 | 
			
		||||
                QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
 | 
			
		||||
            else:
 | 
			
		||||
                QMessageBox.critical(self, "错误", "账号重复,需检查数据库,更正后再尝试登录!")
 | 
			
		||||
            QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
 | 
			
		||||
            raise Exception(f"username:{username} login failed, reason: {reason[flag]}")
 | 
			
		||||
 | 
			
		||||
        def validate_login():
 | 
			
		||||
            nonlocal username, password
 | 
			
		||||
            clibs.conn, clibs.cursor = db_operation.db_conn()
 | 
			
		||||
            record = db_operation.db_query_users(username)
 | 
			
		||||
            if username == "" or password == "":
 | 
			
		||||
                login_failed(flag=-1)
 | 
			
		||||
 | 
			
		||||
            if len(record) == 0:
 | 
			
		||||
                login_failed()
 | 
			
		||||
                return False
 | 
			
		||||
                login_failed(flag=0)
 | 
			
		||||
            elif len(record) == 1:
 | 
			
		||||
                keys = ["id", "timestamp", "username", "password", "salt"]
 | 
			
		||||
                login_info = dict(zip(keys, record[0]))
 | 
			
		||||
@@ -167,52 +165,46 @@ class LoginWindow(QWidget):
 | 
			
		||||
                try:
 | 
			
		||||
                    decrypt_password = cipher.decrypt(login_info["password"])
 | 
			
		||||
                    if password != decrypt_password:
 | 
			
		||||
                        login_failed()
 | 
			
		||||
                        return False
 | 
			
		||||
                        login_failed(flag=1)
 | 
			
		||||
                    else:
 | 
			
		||||
                        self.mainWindow = main_ui.MainWindow()
 | 
			
		||||
                        self.mainWindow.show()
 | 
			
		||||
                        db_operation.db_close()
 | 
			
		||||
                        clibs.username = username
 | 
			
		||||
                        clibs.password = password
 | 
			
		||||
                        self.close()
 | 
			
		||||
                        return True
 | 
			
		||||
                        db_operation.db_write_logs(f"username:{username} 登录成功!")
 | 
			
		||||
                        db_operation.db_close()
 | 
			
		||||
                        self.deleteLater()
 | 
			
		||||
                except ValueError:
 | 
			
		||||
                    login_failed()
 | 
			
		||||
                    return False
 | 
			
		||||
                    login_failed(flag=2)
 | 
			
		||||
            else:
 | 
			
		||||
                db_operation.db_write_logs(f"username duplicated: {username}", self.m, "error")
 | 
			
		||||
                login_failed(exception=True)
 | 
			
		||||
                return False
 | 
			
		||||
                login_failed(flag=3)
 | 
			
		||||
 | 
			
		||||
        username = self.le_username.text()
 | 
			
		||||
        password = self.le_password.text()
 | 
			
		||||
        validate_login()
 | 
			
		||||
 | 
			
		||||
    @handle_exception()
 | 
			
		||||
    def register_check(self):
 | 
			
		||||
        def register_failed(flag: int = 0):
 | 
			
		||||
            reason = {-1: "用户名或密码为空", 0: "两次密码不一致", 1: "密码长度不合规", 2: "用户名已存在", 3: "数据库中有重复的用户名"}
 | 
			
		||||
            self.le_username_reg.clear()
 | 
			
		||||
            self.le_password_reg.clear()
 | 
			
		||||
            self.le_password_reg_confirm.clear()
 | 
			
		||||
            self.le_username_reg.setFocus()
 | 
			
		||||
            if flag == 0:
 | 
			
		||||
                QMessageBox.critical(self, "错误", "账号已存在,或两次输入密码不一致,请重新输入!")
 | 
			
		||||
            elif flag == 1:
 | 
			
		||||
                QMessageBox.critical(self, "错误", "密码长度不符合要求,请重新输入!")
 | 
			
		||||
            elif flag == 2:
 | 
			
		||||
                QMessageBox.critical(self, "错误", "账号重复,需检查数据库,更正后再尝试登录!")
 | 
			
		||||
            QMessageBox.critical(self, "错误", "账号错误,密码长度(>8)不合规,或两次输入密码不一致,请确认后重新输入!")
 | 
			
		||||
            raise Exception(f"register failed, reason: {reason[flag]}")
 | 
			
		||||
 | 
			
		||||
        def validate_register():
 | 
			
		||||
            nonlocal username, password, password_confirm
 | 
			
		||||
            clibs.conn, clibs.cursor = db_operation.db_conn()
 | 
			
		||||
            record = db_operation.db_query_users(username)
 | 
			
		||||
            if password != password_confirm:
 | 
			
		||||
                register_failed()
 | 
			
		||||
                return False
 | 
			
		||||
            if username == "" or password == "" or password_confirm == "":
 | 
			
		||||
                register_failed(flag=-1)
 | 
			
		||||
 | 
			
		||||
            if len(password) < clibs.account["minimum_password_length"]:
 | 
			
		||||
            if password != password_confirm:
 | 
			
		||||
                register_failed(flag=0)
 | 
			
		||||
 | 
			
		||||
            if len(password) < clibs.config["minimum_password_length"]:
 | 
			
		||||
                register_failed(flag=1)
 | 
			
		||||
                return False
 | 
			
		||||
 | 
			
		||||
            if len(record) == 0:
 | 
			
		||||
                salt = PassCipher.gen_salt("@".join([username, password]))
 | 
			
		||||
@@ -221,20 +213,20 @@ class LoginWindow(QWidget):
 | 
			
		||||
                db_operation.db_write_users(username, password_encrypted, salt)
 | 
			
		||||
                QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!")
 | 
			
		||||
                self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login))
 | 
			
		||||
                return True
 | 
			
		||||
            elif len(record) == 1:
 | 
			
		||||
                register_failed()
 | 
			
		||||
                return False
 | 
			
		||||
            else:
 | 
			
		||||
                db_operation.db_write_logs(f"username duplicated: {username}", self.m, "error")
 | 
			
		||||
                register_failed(flag=2)
 | 
			
		||||
                return False
 | 
			
		||||
            else:
 | 
			
		||||
                register_failed(flag=3)
 | 
			
		||||
 | 
			
		||||
        username = self.le_username_reg.text()
 | 
			
		||||
        password = self.le_password_reg.text()
 | 
			
		||||
        password_confirm = self.le_password_reg_confirm.text()
 | 
			
		||||
        validate_register()
 | 
			
		||||
 | 
			
		||||
    def closeEvent(self, event):
 | 
			
		||||
        db_operation.db_close()
 | 
			
		||||
        event.accept()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    app = QApplication(sys.argv)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,22 @@
 | 
			
		||||
import json
 | 
			
		||||
from shutil import copy
 | 
			
		||||
from random import choice
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
import sys
 | 
			
		||||
from random import choice
 | 
			
		||||
from shutil import copy
 | 
			
		||||
import requests
 | 
			
		||||
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QListWidget, QStackedWidget, QCheckBox, QSpinBox, QToolBox, QLineEdit, QTableWidget, QTreeWidget, QCalendarWidget, QMessageBox, QToolBar, QSizePolicy, QMainWindow, QStatusBar, QListWidgetItem
 | 
			
		||||
from PySide6.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread
 | 
			
		||||
from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut, QAction, QKeySequence, QResizeEvent
 | 
			
		||||
import json
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from PySide6.QtWidgets import QApplication, QWidget, QHBoxLayout, QListWidget, QStackedWidget, QMessageBox, QToolBar, QMainWindow, QStatusBar
 | 
			
		||||
from PySide6.QtGui import QFont, QIcon, QResizeEvent, QShortcut, QKeySequence, QAction
 | 
			
		||||
from PySide6.QtCore import Qt
 | 
			
		||||
 | 
			
		||||
from codes.common import clibs, db_operation
 | 
			
		||||
from codes.ui.widget_bg_ui import WidgetWithBg
 | 
			
		||||
from codes.ui.components.toolbar_ui import SToolBar
 | 
			
		||||
from codes.ui.components.list_widget_ui import SListWidget
 | 
			
		||||
from codes.ui.components.stacked_widget_ui import SStackedWidget
 | 
			
		||||
from codes.common.signal_bus import signal_bus
 | 
			
		||||
from codes.common.worker import Worker
 | 
			
		||||
from typing import Callable, Any
 | 
			
		||||
from codes.common.exception_handler import handle_exception
 | 
			
		||||
from codes.ui.overlay_page.overlay_ui import WidgetWithBg
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MainWindow(QMainWindow):
 | 
			
		||||
@@ -26,7 +31,7 @@ class MainWindow(QMainWindow):
 | 
			
		||||
        self.m = Path(__file__).stem
 | 
			
		||||
        self.home_overlay = None
 | 
			
		||||
        db_operation.db_backup()
 | 
			
		||||
        clibs.conn, clibs.cursor = db_operation.db_conn()
 | 
			
		||||
        db_operation.db_conn()
 | 
			
		||||
 | 
			
		||||
    def init_ui(self):
 | 
			
		||||
        self.setMinimumSize(clibs.win_width, clibs.win_height)
 | 
			
		||||
@@ -35,7 +40,7 @@ class MainWindow(QMainWindow):
 | 
			
		||||
        self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
 | 
			
		||||
        self.setFont(QFont("Consolas", 14))
 | 
			
		||||
        # 任务栏/主窗口/状态栏
 | 
			
		||||
        self.toolBar = QToolBar()
 | 
			
		||||
        self.toolBar = SToolBar()
 | 
			
		||||
        self.addToolBar(self.toolBar)
 | 
			
		||||
        self.toolBar.setMovable(False)
 | 
			
		||||
        self.centralW = QWidget()
 | 
			
		||||
@@ -51,106 +56,65 @@ class MainWindow(QMainWindow):
 | 
			
		||||
        """)
 | 
			
		||||
        self.setStatusBar(self.statusBar)
 | 
			
		||||
 | 
			
		||||
        # toolbar
 | 
			
		||||
        # homepage
 | 
			
		||||
        self.ac_homepage = QAction()
 | 
			
		||||
        self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_homepage.setStatusTip("Go to home page")
 | 
			
		||||
        self.ac_homepage.setToolTip("Ctrl+Alt+H")
 | 
			
		||||
        self.ac_homepage.setText("主页")
 | 
			
		||||
        self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
 | 
			
		||||
        self.toolBar.addAction(self.ac_homepage)
 | 
			
		||||
        # setting
 | 
			
		||||
        self.ac_setting = QAction()
 | 
			
		||||
        self.ac_setting.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_setting.setStatusTip("Go to setting page")
 | 
			
		||||
        self.ac_setting.setToolTip("Ctrl+Alt+S")
 | 
			
		||||
        self.ac_setting.setText("设置")
 | 
			
		||||
        self.ac_setting.setShortcut(QKeySequence("Ctrl+Alt+S"))
 | 
			
		||||
        self.toolBar.addAction(self.ac_setting)
 | 
			
		||||
 | 
			
		||||
        # log
 | 
			
		||||
        self.ac_log = QAction()
 | 
			
		||||
        self.ac_log.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_log.setStatusTip("Go to log page")
 | 
			
		||||
        self.ac_log.setToolTip("Ctrl+Alt+L")
 | 
			
		||||
        self.ac_log.setText("日志")
 | 
			
		||||
        self.ac_log.setShortcut(QKeySequence("Ctrl+Alt+L"))
 | 
			
		||||
        self.toolBar.addAction(self.ac_log)
 | 
			
		||||
 | 
			
		||||
        # about
 | 
			
		||||
        self.ac_about = QAction()
 | 
			
		||||
        self.ac_about.setMenuRole(QAction.MenuRole.NoRole)
 | 
			
		||||
        self.ac_about.setStatusTip("Go to about page")
 | 
			
		||||
        self.ac_about.setToolTip("Ctrl+Alt+A")
 | 
			
		||||
        self.ac_about.setText("关于")
 | 
			
		||||
        self.ac_about.setShortcut(QKeySequence("Ctrl+Alt+A"))
 | 
			
		||||
        self.toolBar.addAction(self.ac_about)
 | 
			
		||||
 | 
			
		||||
        layout_h = QHBoxLayout()
 | 
			
		||||
        # list widget
 | 
			
		||||
        self.listW = QListWidget()
 | 
			
		||||
        for item in clibs.listW_items:
 | 
			
		||||
            _ = QListWidgetItem(item)
 | 
			
		||||
            _.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
			
		||||
            self.listW.addItem(_)
 | 
			
		||||
 | 
			
		||||
        layout_h.addWidget(self.listW)
 | 
			
		||||
 | 
			
		||||
        # stacked widget  1x: 10为一级按钮页,其余为二级按钮页,2-9同理 | 0x. 日志/设置/关于等页面
 | 
			
		||||
        self.stackedW =QStackedWidget()
 | 
			
		||||
        self.w00_setting = QWidget()
 | 
			
		||||
        self.stackedW.addWidget(self.w00_setting)
 | 
			
		||||
        self.lb_test00 = QLabel("testing text on setting widget", parent=self.w00_setting)
 | 
			
		||||
 | 
			
		||||
        self.w08_log = QWidget()
 | 
			
		||||
        self.stackedW.addWidget(self.w08_log)
 | 
			
		||||
        self.lb_test08 = QLabel("testing text on log widget", parent=self.w08_log)
 | 
			
		||||
 | 
			
		||||
        self.w09_about = QWidget()
 | 
			
		||||
        self.stackedW.addWidget(self.w09_about)
 | 
			
		||||
        self.lb_test09 = QLabel("testing text on about widget", parent=self.w09_about)
 | 
			
		||||
 | 
			
		||||
        self.w10_practical = QWidget()
 | 
			
		||||
        self.stackedW.addWidget(self.w10_practical)
 | 
			
		||||
        self.lb_test10 = QLabel("testing text on practical widget", parent=self.w10_practical)
 | 
			
		||||
 | 
			
		||||
        self.w20_efficiency = QWidget()
 | 
			
		||||
        self.stackedW.addWidget(self.w20_efficiency)
 | 
			
		||||
        self.lb_test20 = QLabel("testing text on efficiency widget", parent=self.w20_efficiency)
 | 
			
		||||
 | 
			
		||||
        self.w30_financial = QWidget()
 | 
			
		||||
        self.stackedW.addWidget(self.w30_financial)
 | 
			
		||||
        self.lb_test30 = QLabel("testing text on financial widget", parent=self.w30_financial)
 | 
			
		||||
 | 
			
		||||
        layout_h.addWidget(self.stackedW)
 | 
			
		||||
        layout_h.setStretch(0, 1)
 | 
			
		||||
        layout_h.setStretch(1, 5)
 | 
			
		||||
        self.listW = SListWidget()
 | 
			
		||||
        layout_h.addWidget(self.listW, stretch=1)
 | 
			
		||||
        self.stackedW =SStackedWidget()
 | 
			
		||||
        layout_h.addWidget(self.stackedW, stretch=5)
 | 
			
		||||
        self.centralW.setLayout(layout_h)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        self.ac_homepage.triggered.connect(self.ac_hp)
 | 
			
		||||
        self.ac_setting.triggered.connect(self.ac_sp)
 | 
			
		||||
        self.ac_log.triggered.connect(self.ac_lp)
 | 
			
		||||
        self.ac_about.triggered.connect(self.ac_ap)
 | 
			
		||||
        self.f11_sc = QShortcut(QKeySequence("F11"), self)
 | 
			
		||||
        self.f11_sc.activated.connect(self.sc_F11)
 | 
			
		||||
        # self.listW.currentItemChanged.connect(self.change_stackedW)
 | 
			
		||||
        self.listW.itemClicked.connect(self.change_stackedW)
 | 
			
		||||
        signal_bus.home_overlay_trigger.connect(self.ac_hp)
 | 
			
		||||
        signal_bus.home_overlay_close.connect(self.exit_overlay)
 | 
			
		||||
        self.install_sc()
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self, stat: bool = True):
 | 
			
		||||
        if stat:
 | 
			
		||||
            self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
 | 
			
		||||
            self.f11_sc.setEnabled(True)
 | 
			
		||||
        else:
 | 
			
		||||
            self.ac_homepage.setShortcut(QKeySequence())
 | 
			
		||||
            self.f11_sc.setEnabled(False)
 | 
			
		||||
    def setup_sc(self, enable: bool = True):
 | 
			
		||||
        for sc_id, obj in self.sc_pool.items():
 | 
			
		||||
            if isinstance(obj, QAction):
 | 
			
		||||
                obj.setEnabled(enable)
 | 
			
		||||
            elif isinstance(obj, QShortcut):
 | 
			
		||||
                obj.setEnabled(enable)
 | 
			
		||||
 | 
			
		||||
            if enable == False and (sc_id == "esc" or sc_id == "ctrl_alt_m") and self.home_overlay:
 | 
			
		||||
                obj.setEnabled(True)
 | 
			
		||||
            if (sc_id == "esc" or sc_id == "ctrl_alt_m") and self.home_overlay is None:
 | 
			
		||||
                obj.setEnabled(False)
 | 
			
		||||
 | 
			
		||||
    def install_sc(self):
 | 
			
		||||
        self.sc_pool = {}
 | 
			
		||||
        # QAction
 | 
			
		||||
        self.toolBar.ac_switch.setShortcut(QKeySequence("Ctrl+Alt+T"))
 | 
			
		||||
        self.sc_pool["ctrl_alt_t"] = self.toolBar.ac_switch
 | 
			
		||||
        self.toolBar.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
 | 
			
		||||
        self.sc_pool["ctrl_alt_h"] = self.toolBar.ac_homepage
 | 
			
		||||
        self.toolBar.ac_setting.setShortcut(QKeySequence("Ctrl+Alt+S"))
 | 
			
		||||
        self.sc_pool["ctrl_alt_s"] = self.toolBar.ac_setting
 | 
			
		||||
        self.toolBar.ac_log.setShortcut(QKeySequence("Ctrl+Alt+L"))
 | 
			
		||||
        self.sc_pool["ctrl_alt_l"] = self.toolBar.ac_log
 | 
			
		||||
        self.toolBar.ac_about.setShortcut(QKeySequence("Ctrl+Alt+A"))
 | 
			
		||||
        self.sc_pool["ctrl_alt_a"] = self.toolBar.ac_about
 | 
			
		||||
        # QShortcut
 | 
			
		||||
        self.sc_f11 = QShortcut(QKeySequence("F11"), self)
 | 
			
		||||
        self.sc_f11.activated.connect(self.shortcut_f11)
 | 
			
		||||
        self.sc_pool["f11"] = self.sc_f11
 | 
			
		||||
        # Subpage
 | 
			
		||||
        self.sc_Esc = QShortcut(QKeySequence("Esc"), self)
 | 
			
		||||
        self.sc_Esc.activated.connect(signal_bus.home_overlay_auth.emit)
 | 
			
		||||
        self.sc_pool["esc"] = self.sc_Esc
 | 
			
		||||
        self.sc_caM = QShortcut(QKeySequence("Ctrl+Alt+M"), self)
 | 
			
		||||
        self.sc_caM.activated.connect(self.toggle_full_screen)
 | 
			
		||||
        self.sc_pool["ctrl_alt_m"] = self.sc_caM
 | 
			
		||||
 | 
			
		||||
    def ac_hp(self):
 | 
			
		||||
        def get_files(dir_path):
 | 
			
		||||
            folder = Path(dir_path)
 | 
			
		||||
            files = [p for p in folder.rglob("*") if p.is_file()]
 | 
			
		||||
            return choice(files), files
 | 
			
		||||
            if files:
 | 
			
		||||
                rand_choice = choice(files)
 | 
			
		||||
            else:
 | 
			
		||||
                rand_choice = ""
 | 
			
		||||
            return rand_choice, files
 | 
			
		||||
 | 
			
		||||
        def del_repeat_proverb(proverbs: list):
 | 
			
		||||
            _proverbs = []
 | 
			
		||||
@@ -159,6 +123,7 @@ class MainWindow(QMainWindow):
 | 
			
		||||
                    _proverbs.append(proverb)
 | 
			
		||||
            return _proverbs
 | 
			
		||||
 | 
			
		||||
        @handle_exception()
 | 
			
		||||
        def get_resources():
 | 
			
		||||
            # background image
 | 
			
		||||
            bing = "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=8"
 | 
			
		||||
@@ -169,12 +134,12 @@ class MainWindow(QMainWindow):
 | 
			
		||||
            for file in files:
 | 
			
		||||
                image_names.append(file.name.removesuffix(".jpg"))
 | 
			
		||||
            for image in res["images"]:
 | 
			
		||||
                startdate = image["startdate"]
 | 
			
		||||
                if startdate in image_names:
 | 
			
		||||
                image_name = "-".join([image["startdate"], image["title"]])
 | 
			
		||||
                if image_name in image_names:
 | 
			
		||||
                    continue
 | 
			
		||||
                else:
 | 
			
		||||
                    image_url = f"""https://www.bing.com{image["url"]}"""
 | 
			
		||||
                    file = Path(f"{clibs.base_path}/assets/media/bg/{startdate}.jpg")
 | 
			
		||||
                    file = Path(f"{clibs.base_path}/assets/media/bg/{image_name}.jpg")
 | 
			
		||||
                    try:
 | 
			
		||||
                        req = requests.get(image_url, stream=True, timeout=10)
 | 
			
		||||
                        with open(file, "wb") as f:
 | 
			
		||||
@@ -185,18 +150,22 @@ class MainWindow(QMainWindow):
 | 
			
		||||
            # proverbs
 | 
			
		||||
            hitokoto = "https://v1.hitokoto.cn/"
 | 
			
		||||
            proverbs = []
 | 
			
		||||
            try:
 | 
			
		||||
                req = requests.get(hitokoto)
 | 
			
		||||
                with open(f"{clibs.base_path}/assets/media/hitokoto.json", mode="rt", encoding="utf-8") as f:
 | 
			
		||||
                    proverbs = json.load(f)
 | 
			
		||||
                    proverbs.append(eval(req.text))
 | 
			
		||||
                    proverbs = del_repeat_proverb(proverbs)
 | 
			
		||||
                with open(f"{clibs.base_path}/assets/media/hitokoto.json", mode="wt", encoding="utf-8") as f:
 | 
			
		||||
                    json.dump(proverbs, f, ensure_ascii=False)
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                pass
 | 
			
		||||
            proverb_file = Path(f"{clibs.base_path}/assets/media/hitokoto.json")
 | 
			
		||||
            req = requests.get(hitokoto)
 | 
			
		||||
            if not proverb_file.exists():
 | 
			
		||||
                proverb_file.touch()
 | 
			
		||||
                proverb_file.write_text("[]")
 | 
			
		||||
                with open(proverb_file, "w") as f:
 | 
			
		||||
                    f.write("[]")
 | 
			
		||||
 | 
			
		||||
        @handle_exception(self.m)
 | 
			
		||||
            with open(proverb_file, mode="rt", encoding="utf-8") as f:
 | 
			
		||||
                proverbs = json.load(f)
 | 
			
		||||
                proverbs.append(eval(req.text))
 | 
			
		||||
                proverbs = del_repeat_proverb(proverbs)
 | 
			
		||||
            with open(proverb_file, mode="wt", encoding="utf-8") as f:
 | 
			
		||||
                json.dump(proverbs, f, ensure_ascii=False)
 | 
			
		||||
 | 
			
		||||
        @handle_exception()
 | 
			
		||||
        def change_resources():
 | 
			
		||||
            # avatar
 | 
			
		||||
            src, _ = get_files(f"{clibs.base_path}/assets/media/avatar")
 | 
			
		||||
@@ -216,11 +185,9 @@ class MainWindow(QMainWindow):
 | 
			
		||||
            copy(src, dst)
 | 
			
		||||
 | 
			
		||||
        def gen_page():
 | 
			
		||||
            self.setup_sc(False)
 | 
			
		||||
            self.home_overlay = WidgetWithBg(parent=self)
 | 
			
		||||
            self.home_overlay.on_closed.connect(self.exit_overlay)
 | 
			
		||||
            self.home_overlay.on_full_screen.connect(self.toggle_full_screen)
 | 
			
		||||
            self.home_overlay.show()
 | 
			
		||||
            self.setup_sc(False)
 | 
			
		||||
            width, height = self.width(), self.height()
 | 
			
		||||
            if width > clibs.win_width:
 | 
			
		||||
                self.resize(self.width()-1, self.height()-1)
 | 
			
		||||
@@ -231,14 +198,13 @@ class MainWindow(QMainWindow):
 | 
			
		||||
        self.launch_get_resources(get_resources)
 | 
			
		||||
        gen_page()
 | 
			
		||||
 | 
			
		||||
    def ac_sp(self):
 | 
			
		||||
        self.stackedW.setCurrentWidget(self.w00_setting)
 | 
			
		||||
 | 
			
		||||
    def ac_lp(self):
 | 
			
		||||
        self.stackedW.setCurrentWidget(self.w08_log)
 | 
			
		||||
 | 
			
		||||
    def ac_ap(self):
 | 
			
		||||
        self.stackedW.setCurrentWidget(self.w09_about)
 | 
			
		||||
    def launch_get_resources(self, func, on_anything=None, *args, **kwargs):
 | 
			
		||||
        self.td_get_resources = Worker(func, *args, **kwargs)
 | 
			
		||||
        self.td_get_resources.started.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.result.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.error.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.finished.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.start()
 | 
			
		||||
 | 
			
		||||
    def toggle_full_screen(self):
 | 
			
		||||
        if self.isFullScreen():
 | 
			
		||||
@@ -250,30 +216,14 @@ class MainWindow(QMainWindow):
 | 
			
		||||
            self.showFullScreen()
 | 
			
		||||
 | 
			
		||||
    def exit_overlay(self):
 | 
			
		||||
        self.setup_sc(True)
 | 
			
		||||
        self.home_overlay = None
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
        if self.isFullScreen():
 | 
			
		||||
            self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
 | 
			
		||||
            self.show()
 | 
			
		||||
            self.showMaximized()
 | 
			
		||||
 | 
			
		||||
    def change_stackedW(self, w_item):
 | 
			
		||||
        if w_item.text() == "实用工具":
 | 
			
		||||
            self.stackedW.setCurrentWidget(self.w10_practical)
 | 
			
		||||
        elif w_item.text() == "效率提升":
 | 
			
		||||
            self.stackedW.setCurrentWidget(self.w20_efficiency)
 | 
			
		||||
        elif w_item.text() == "财务分析":
 | 
			
		||||
            self.stackedW.setCurrentWidget(self.w30_financial)
 | 
			
		||||
 | 
			
		||||
    def launch_get_resources(self, func, on_anything: Callable[..., Any] = None, *args, **kwargs):
 | 
			
		||||
        self.td_get_resources = Worker(func, *args, **kwargs)
 | 
			
		||||
        self.td_get_resources.started.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.result.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.error.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.finished.connect(lambda: None)
 | 
			
		||||
        self.td_get_resources.start()
 | 
			
		||||
 | 
			
		||||
    def sc_F11(self):
 | 
			
		||||
    def shortcut_f11(self):
 | 
			
		||||
        if not self.home_overlay:
 | 
			
		||||
            self.ac_hp()
 | 
			
		||||
            self.toggle_full_screen()
 | 
			
		||||
@@ -287,6 +237,7 @@ class MainWindow(QMainWindow):
 | 
			
		||||
        if self.isFullScreen():
 | 
			
		||||
            event.ignore()
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        reply = QMessageBox.question(self, "退出", "\n程序可能在运行,确定要退出吗?")
 | 
			
		||||
        if reply == QMessageBox.StandardButton.Yes:
 | 
			
		||||
            db_operation.db_close()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								toolbox/codes/ui/overlay_page/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toolbox/codes/ui/overlay_page/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -1,9 +1,12 @@
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QApplication, QSizePolicy, QVBoxLayout, QLabel, QFrame, QHBoxLayout, QLineEdit, QMessageBox
 | 
			
		||||
from PySide6.QtGui import QPixmap, QPainter, QFontDatabase, QFont, QBrush, QShortcut, QKeySequence, QColor
 | 
			
		||||
from PySide6.QtCore import Qt, QPoint, QDateTime, Signal, QTimer
 | 
			
		||||
from zhdate import ZhDate
 | 
			
		||||
 | 
			
		||||
from codes.common import clibs
 | 
			
		||||
from codes.common.signal_bus import signal_bus
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LunarClockLabel(QLabel):
 | 
			
		||||
@@ -33,9 +36,6 @@ class DoubleClickLabel(QLabel):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class WidgetWithBg(QWidget):
 | 
			
		||||
    on_closed = Signal()
 | 
			
		||||
    on_full_screen = Signal()
 | 
			
		||||
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
        self.predos()
 | 
			
		||||
@@ -140,10 +140,11 @@ class WidgetWithBg(QWidget):
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        self.lb_avatar.doubleClicked.connect(self.toggle_auth_show)
 | 
			
		||||
        self.le_password.returnPressed.connect(self.validate_password)
 | 
			
		||||
        self.sc_caL = QShortcut(QKeySequence("Ctrl+Alt+L"), self)
 | 
			
		||||
        self.sc_caL.activated.connect(self.toggle_auth_show)
 | 
			
		||||
        self.sc_caS = QShortcut(QKeySequence("Ctrl+Alt+S"), self)
 | 
			
		||||
        self.sc_caS.activated.connect(lambda: self.on_full_screen.emit())
 | 
			
		||||
        signal_bus.home_overlay_auth.connect(self.toggle_auth_show)
 | 
			
		||||
        # self.sc_caL = QShortcut(QKeySequence("Esc"), self)
 | 
			
		||||
        # self.sc_caL.activated.connect(self.toggle_auth_show)
 | 
			
		||||
        # self.sc_caS = QShortcut(QKeySequence("Ctrl+Alt+M"), self)
 | 
			
		||||
        # self.sc_caS.activated.connect(signal_bus.ho_full_screen.emit)
 | 
			
		||||
 | 
			
		||||
    def toggle_auth_show(self):
 | 
			
		||||
        if self.le_is_visible:
 | 
			
		||||
@@ -170,7 +171,7 @@ class WidgetWithBg(QWidget):
 | 
			
		||||
        password = self.le_password.text()
 | 
			
		||||
        if password == clibs.password:
 | 
			
		||||
            self.hide_le_password()
 | 
			
		||||
            self.on_closed.emit()
 | 
			
		||||
            signal_bus.home_overlay_close.emit()
 | 
			
		||||
            self.deleteLater()
 | 
			
		||||
            return True
 | 
			
		||||
        elif password == "":
 | 
			
		||||
							
								
								
									
										0
									
								
								toolbox/codes/ui/stacked_pages/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								toolbox/codes/ui/stacked_pages/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w01_setting.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w01_setting.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class W01Setting(QWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.ui_init()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def ui_init(self):
 | 
			
		||||
        self.lb_test = QLabel(f"testing text on widget: \n{__file__}", parent=self)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								toolbox/codes/ui/stacked_pages/w08_log.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								toolbox/codes/ui/stacked_pages/w08_log.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class W08Log(QWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.ui_init()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def ui_init(self):
 | 
			
		||||
        self.lb_test = QLabel(f"testing text on widget: \n{__file__}", parent=self)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w09_about.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w09_about.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class W09About(QWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.ui_init()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def ui_init(self):
 | 
			
		||||
        self.lb_test = QLabel(f"testing text on widget: \n{__file__}", parent=self)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w10_practical.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w10_practical.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class W10Practical(QWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.ui_init()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def ui_init(self):
 | 
			
		||||
        self.lb_test = QLabel(f"testing text on widget: \n{__file__}", parent=self)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w20_efficiency.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w20_efficiency.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class W20Efficiency(QWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.ui_init()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def ui_init(self):
 | 
			
		||||
        self.lb_test = QLabel(f"testing text on widget: \n{__file__}", parent=self)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w30_financial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								toolbox/codes/ui/stacked_pages/w30_financial.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
from PySide6.QtWidgets import QWidget, QLabel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class W30Financial(QWidget):
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
 | 
			
		||||
        self.predos()
 | 
			
		||||
        self.ui_init()
 | 
			
		||||
        self.setup_slot()
 | 
			
		||||
        self.setup_sc()
 | 
			
		||||
 | 
			
		||||
    def predos(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def ui_init(self):
 | 
			
		||||
        self.lb_test = QLabel(f"testing text on widget: \n{__file__}", parent=self)
 | 
			
		||||
 | 
			
		||||
    def setup_slot(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
    def setup_sc(self):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>Form</class>
 | 
			
		||||
 <widget class="QWidget" name="Form">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>691</width>
 | 
			
		||||
    <height>403</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Form</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <widget class="QListWidget" name="listWidget">
 | 
			
		||||
   <property name="geometry">
 | 
			
		||||
    <rect>
 | 
			
		||||
     <x>80</x>
 | 
			
		||||
     <y>60</y>
 | 
			
		||||
     <width>101</width>
 | 
			
		||||
     <height>241</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
   </property>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <widget class="QStackedWidget" name="stackedWidget">
 | 
			
		||||
   <property name="geometry">
 | 
			
		||||
    <rect>
 | 
			
		||||
     <x>320</x>
 | 
			
		||||
     <y>180</y>
 | 
			
		||||
     <width>120</width>
 | 
			
		||||
     <height>80</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
   </property>
 | 
			
		||||
   <widget class="QWidget" name="page_3"/>
 | 
			
		||||
   <widget class="QWidget" name="page_4"/>
 | 
			
		||||
  </widget>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
		Reference in New Issue
	
	Block a user