总线通信架构整改完成
This commit is contained in:
@@ -4,8 +4,9 @@ import atexit
|
||||
|
||||
|
||||
base_path = Path(__file__).resolve().parent.parent.parent
|
||||
db_file = base_path / "assets/database/toolbox.db"
|
||||
lock = Lock()
|
||||
account = None
|
||||
config = None
|
||||
code_dict = [4, 11, 4, 31, 22, 12, 19, 23, 7, 16, 7, 23, 1, 8, 7, 18, 27, 32, 28, 25, 7, 32, 9, 15, 2, 32, 0, 12, 26, 15, 14, 17]
|
||||
username, password = "", ""
|
||||
avatar = f"{base_path}/assets/media/avatar.jpg"
|
||||
@@ -13,7 +14,7 @@ proverb = "佛曰:Time will say~"
|
||||
bg = f"{base_path}/assets/media/bg.jpg"
|
||||
win_width, win_height = 1100, 500
|
||||
conn, cursor = None, None
|
||||
listW_items = ["实用工具", "效率提升", "财务分析"]
|
||||
listW_items = {"实用工具": "w10_practical", "效率提升": "w20_efficiency", "财务分析": "w30_financial"}
|
||||
|
||||
|
||||
def delete_files_in_directory(directory):
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import sqlite3
|
||||
import time
|
||||
from inspect import currentframe
|
||||
|
||||
from codes.common import clibs
|
||||
|
||||
|
||||
def db_init(db_file):
|
||||
conn = sqlite3.connect(db_file, isolation_level=None, check_same_thread=False, cached_statements=2048, timeout=10.0)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("PRAGMA journal_mode=wal")
|
||||
cursor.execute("PRAGMA wal_checkpoint=TRUNCATE")
|
||||
cursor.execute("PRAGMA synchronous=normal")
|
||||
cursor.execute("PRAGMA temp_store=memory")
|
||||
cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
cursor.execute("PRAGMA cache_size=200000")
|
||||
cursor.execute(
|
||||
def db_init():
|
||||
if clibs.db_file.exists():
|
||||
return
|
||||
|
||||
clibs.conn = sqlite3.connect(clibs.db_file, isolation_level=None, check_same_thread=False, cached_statements=2048, timeout=10.0)
|
||||
clibs.cursor = clibs.conn.cursor()
|
||||
clibs.cursor.execute("PRAGMA journal_mode=wal")
|
||||
clibs.cursor.execute("PRAGMA wal_checkpoint=TRUNCATE")
|
||||
clibs.cursor.execute("PRAGMA synchronous=normal")
|
||||
clibs.cursor.execute("PRAGMA temp_store=memory")
|
||||
clibs.cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
clibs.cursor.execute("PRAGMA cache_size=200000")
|
||||
clibs.cursor.execute(
|
||||
"""
|
||||
create table if not exists logs(
|
||||
id integer primary key autoincrement,
|
||||
@@ -23,7 +28,7 @@ def db_init(db_file):
|
||||
)
|
||||
"""
|
||||
)
|
||||
cursor.execute(
|
||||
clibs.cursor.execute(
|
||||
"""
|
||||
create table if not exists users(
|
||||
id integer primary key autoincrement,
|
||||
@@ -34,8 +39,8 @@ def db_init(db_file):
|
||||
)
|
||||
"""
|
||||
)
|
||||
cursor.close()
|
||||
conn.close()
|
||||
db_write_logs("数据库初始化成功!", "login_ui")
|
||||
db_close()
|
||||
|
||||
def db_lock(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
@@ -49,28 +54,22 @@ def db_lock(func):
|
||||
|
||||
def db_backup():
|
||||
t = time.strftime("%Y%m%d%H%M%S", time.localtime())
|
||||
db_file = clibs.base_path / "assets/database/toolbox.db"
|
||||
db_file_backup = clibs.base_path / f"assets/database/toolbox.{t}.db"
|
||||
if not (db_file.exists() and db_file.is_file()):
|
||||
db_init(db_file)
|
||||
else:
|
||||
db_file_backup.write_bytes(db_file.read_bytes())
|
||||
db_dir = clibs.base_path / "assets/database"
|
||||
db_list = [db for db in db_dir.glob("*.db")]
|
||||
for db in sorted(db_list)[:-clibs.account["maximum_db_number"]]:
|
||||
db.unlink()
|
||||
db_file_backup.write_bytes(clibs.db_file.read_bytes())
|
||||
db_dir = clibs.base_path / "assets/database"
|
||||
db_list = [db for db in db_dir.glob("*.db")]
|
||||
for db in sorted(db_list)[:-clibs.config["maximum_db_number"]]:
|
||||
db.unlink()
|
||||
|
||||
def db_conn():
|
||||
db_file = clibs.base_path / "assets/database/toolbox.db"
|
||||
conn = sqlite3.connect(db_file, isolation_level=None, check_same_thread=False, cached_statements=2048, timeout=3.0)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("PRAGMA journal_mode=wal")
|
||||
cursor.execute("PRAGMA wal_checkpoint=TRUNCATE")
|
||||
cursor.execute("PRAGMA synchronous=normal")
|
||||
cursor.execute("PRAGMA temp_store=memory")
|
||||
cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
cursor.execute("PRAGMA cache_size=200000")
|
||||
return conn, cursor
|
||||
clibs.conn = sqlite3.connect(clibs.db_file, isolation_level=None, check_same_thread=False, cached_statements=2048, timeout=3.0)
|
||||
clibs.cursor = clibs.conn.cursor()
|
||||
clibs.cursor.execute("PRAGMA journal_mode=wal")
|
||||
clibs.cursor.execute("PRAGMA wal_checkpoint=TRUNCATE")
|
||||
clibs.cursor.execute("PRAGMA synchronous=normal")
|
||||
clibs.cursor.execute("PRAGMA temp_store=memory")
|
||||
clibs.cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
clibs.cursor.execute("PRAGMA cache_size=200000")
|
||||
|
||||
@db_lock
|
||||
def db_close():
|
||||
@@ -81,9 +80,16 @@ def db_close():
|
||||
clibs.conn, clibs.cursor = None, None
|
||||
|
||||
@db_lock
|
||||
def db_write_logs(content, module, level="info"):
|
||||
if level.lower() not in ["debug", "info", "warning", "error", "exception"]:
|
||||
def db_write_logs(content, module="", level="info"):
|
||||
if module == "":
|
||||
frame = currentframe().f_back
|
||||
module_name = frame.f_globals["__name__"]
|
||||
line_no = frame.f_lineno
|
||||
module = f"{module_name}.{line_no}"
|
||||
|
||||
if level.lower() not in ["info", "warning", "error", "exception"]:
|
||||
level = "unknown"
|
||||
|
||||
clibs.cursor.execute(f"INSERT INTO logs (level, module, content) VALUES (?, ?, ?)", (level, module, content))
|
||||
|
||||
@db_lock
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
from functools import wraps
|
||||
from codes.common import db_operation
|
||||
from inspect import getfile
|
||||
from pathlib import Path
|
||||
|
||||
def handle_exception(module, stop: bool = False):
|
||||
|
||||
def handle_exception(stop: bool = False):
|
||||
def exceptions(func):
|
||||
module = Path(getfile(func)).stem
|
||||
func_name = func.__name__
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
db_operation.db_write_logs(e, module, "exception")
|
||||
db_operation.db_write_logs(str(e), "@".join([func_name, module]), "exception")
|
||||
if stop:
|
||||
raise e
|
||||
return wrapper
|
||||
|
||||
26
toolbox/codes/common/signal_bus.py
Normal file
26
toolbox/codes/common/signal_bus.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from PySide6.QtCore import QObject, Signal
|
||||
|
||||
|
||||
class SignalBus(QObject):
|
||||
instance = None
|
||||
|
||||
def __new__(cls):
|
||||
if cls.instance is None:
|
||||
cls.instance = super(SignalBus, cls).__new__(cls)
|
||||
return cls.instance
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
current_stacked_page = Signal(str) # 获取当前页面的page_id
|
||||
init_stacked_page = Signal(str) # 设置打开侧边栏后的初始页面
|
||||
qa_stacked_page_switch = Signal(str) # 切换stacked widget页面
|
||||
home_overlay_trigger = Signal() # 触发软件锁屏
|
||||
home_overlay_auth = Signal() # 触发密码框的显示与隐藏
|
||||
home_overlay_close = Signal() # 退出锁屏后的收尾信号
|
||||
list_widget_click = Signal(str) # 触发点击list widget信号
|
||||
list_widget_on_off = Signal(bool) # 主动控制是否显示list widget组件
|
||||
|
||||
|
||||
|
||||
signal_bus = SignalBus()
|
||||
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