提交一下,准备更换总线通信架构

This commit is contained in:
2025-09-27 08:36:08 +08:00
parent bb3ae1e65a
commit c7c0d15545
27 changed files with 267 additions and 209 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,7 @@
from pathlib import Path from pathlib import Path
from threading import Lock from threading import Lock
import atexit
base_path = Path(__file__).resolve().parent.parent.parent base_path = Path(__file__).resolve().parent.parent.parent
lock = Lock() lock = Lock()
@@ -10,6 +12,10 @@ avatar = f"{base_path}/assets/media/avatar.jpg"
proverb = "佛曰Time will say~" proverb = "佛曰Time will say~"
bg = f"{base_path}/assets/media/bg.jpg" bg = f"{base_path}/assets/media/bg.jpg"
win_width, win_height = 1100, 500 win_width, win_height = 1100, 500
conn, cursor = None, None
listW_items = ["实用工具", "效率提升", "财务分析"]
def delete_files_in_directory(directory): def delete_files_in_directory(directory):
path = Path(directory) path = Path(directory)
if path.exists() and path.is_dir(): if path.exists() and path.is_dir():

View File

@@ -1,7 +1,6 @@
import sqlite3 import sqlite3
import time import time
from codes.common import clibs from codes.common import clibs
from pathlib import Path
def db_init(db_file): def db_init(db_file):
@@ -74,7 +73,34 @@ def db_conn():
return conn, cursor return conn, cursor
@db_lock @db_lock
def db_close(conn, cursor): def db_close():
cursor.close() if clibs.cursor is not None:
conn.close() clibs.cursor.close()
if clibs.conn is not None:
clibs.conn.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"]:
level = "unknown"
clibs.cursor.execute(f"INSERT INTO logs (level, module, content) VALUES (?, ?, ?)", (level, module, content))
@db_lock
def db_query_logs():
...
@db_lock
def db_write_users(username, password_encrypted, salt):
clibs.cursor.execute("INSERT INTO users (username, password, salt) VALUES (?, ?, ?)", (username, password_encrypted, salt))
@db_lock
def db_delete_users(username):
# clibs.cursor.execute("INSERT INTO users (username, password, salt) VALUES (?, ?, ?)", (username, password_encrypted, salt))
...
@db_lock
def db_query_users(username):
clibs.cursor.execute(f""" SELECT * FROM users where username = "{username}" """)
record = clibs.cursor.fetchall()
return record

View File

@@ -0,0 +1,15 @@
from functools import wraps
from codes.common import db_operation
def handle_exception(module, stop: bool = False):
def exceptions(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
db_operation.db_write_logs(e, module, "exception")
if stop:
raise e
return wrapper
return exceptions

View File

@@ -1,4 +1,5 @@
import sys 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.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.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread
from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut
@@ -122,6 +123,7 @@ class LoginWindow(QWidget):
self.le_password_reg_confirm.returnPressed.connect(self.register_check) self.le_password_reg_confirm.returnPressed.connect(self.register_check)
def predos(self): def predos(self):
self.m = Path(__file__).stem
db_file = clibs.base_path / "assets/database/toolbox.db" db_file = clibs.base_path / "assets/database/toolbox.db"
if not db_file.exists(): if not db_file.exists():
db_operation.db_init(db_file) db_operation.db_init(db_file)
@@ -141,27 +143,27 @@ class LoginWindow(QWidget):
raise Exception(f"Unknown TabWidget Name: {text}") raise Exception(f"Unknown TabWidget Name: {text}")
def login_check(self): def login_check(self):
def login_failed(): def login_failed(exception: bool = False):
self.le_username.clear() self.le_username.clear()
self.le_password.clear() self.le_password.clear()
self.le_username.setFocus() self.le_username.setFocus()
if not exception:
QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!") QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
else:
QMessageBox.critical(self, "错误", "账号重复,需检查数据库,更正后再尝试登录!")
def validate_login(): def validate_login():
nonlocal username, password nonlocal username, password
conn, cursor = db_operation.db_conn() clibs.conn, clibs.cursor = db_operation.db_conn()
cursor.execute(f""" SELECT * FROM users where username = "{username}" """) record = db_operation.db_query_users(username)
record = cursor.fetchall()
if len(record) == 0: if len(record) == 0:
login_failed() login_failed()
return False
elif len(record) == 1: elif len(record) == 1:
keys = ["id", "timestamp", "username", "password", "salt"] keys = ["id", "timestamp", "username", "password", "salt"]
login_info = dict(zip(keys, record[0])) login_info = dict(zip(keys, record[0]))
salt = PassCipher.gen_salt("@".join([username, password])) salt = PassCipher.gen_salt("@".join([username, password]))
cipher = PassCipher(salt) cipher = PassCipher(salt)
# password_encrypt = cipher.encrypt("@".join([username, password]))
# print(f"password_encrypt = {password_encrypt}")
# exit()
try: try:
decrypt_password = cipher.decrypt(login_info["password"]) decrypt_password = cipher.decrypt(login_info["password"])
if password != decrypt_password: if password != decrypt_password:
@@ -170,7 +172,7 @@ class LoginWindow(QWidget):
else: else:
self.mainWindow = main_ui.MainWindow() self.mainWindow = main_ui.MainWindow()
self.mainWindow.show() self.mainWindow.show()
db_operation.db_close(conn, cursor) db_operation.db_close()
clibs.username = username clibs.username = username
clibs.password = password clibs.password = password
self.close() self.close()
@@ -179,11 +181,12 @@ class LoginWindow(QWidget):
login_failed() login_failed()
return False return False
else: else:
raise Exception(f"username duplicated: {username}") db_operation.db_write_logs(f"username duplicated: {username}", self.m, "error")
login_failed(exception=True)
return False
username = self.le_username.text() username = self.le_username.text()
password = self.le_password.text() password = self.le_password.text()
validate_login() validate_login()
def register_check(self): def register_check(self):
@@ -196,9 +199,13 @@ class LoginWindow(QWidget):
QMessageBox.critical(self, "错误", "账号已存在,或两次输入密码不一致,请重新输入!") QMessageBox.critical(self, "错误", "账号已存在,或两次输入密码不一致,请重新输入!")
elif flag == 1: elif flag == 1:
QMessageBox.critical(self, "错误", "密码长度不符合要求,请重新输入!") QMessageBox.critical(self, "错误", "密码长度不符合要求,请重新输入!")
elif flag == 2:
QMessageBox.critical(self, "错误", "账号重复,需检查数据库,更正后再尝试登录!")
def validate_register(): def validate_register():
nonlocal username, password, password_confirm, record, conn, cursor nonlocal username, password, password_confirm
clibs.conn, clibs.cursor = db_operation.db_conn()
record = db_operation.db_query_users(username)
if password != password_confirm: if password != password_confirm:
register_failed() register_failed()
return False return False
@@ -211,7 +218,7 @@ class LoginWindow(QWidget):
salt = PassCipher.gen_salt("@".join([username, password])) salt = PassCipher.gen_salt("@".join([username, password]))
cipher = PassCipher(salt) cipher = PassCipher(salt)
password_encrypted = cipher.encrypt(password) password_encrypted = cipher.encrypt(password)
cursor.execute("INSERT INTO users (username, password, salt) VALUES (?, ?, ?)", (username, password_encrypted, salt)) db_operation.db_write_users(username, password_encrypted, salt)
QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!") QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!")
self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login)) self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login))
return True return True
@@ -219,14 +226,13 @@ class LoginWindow(QWidget):
register_failed() register_failed()
return False return False
else: else:
raise Exception(f"username duplicated: {username}") db_operation.db_write_logs(f"username duplicated: {username}", self.m, "error")
register_failed(flag=2)
return False
username = self.le_username_reg.text() username = self.le_username_reg.text()
password = self.le_password_reg.text() password = self.le_password_reg.text()
password_confirm = self.le_password_reg_confirm.text() password_confirm = self.le_password_reg_confirm.text()
conn, cursor = db_operation.db_conn()
cursor.execute(f""" SELECT * FROM users where username = "{username}" """)
record = cursor.fetchall()
validate_register() validate_register()

View File

@@ -1,25 +1,32 @@
import json import json
from math import lgamma
from shutil import copy from shutil import copy
from random import choice from random import choice
from pathlib import Path from pathlib import Path
import sys import sys
import requests 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 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.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread
from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut, QAction, QKeySequence, QResizeEvent from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut, QAction, QKeySequence, QResizeEvent
from codes.common import clibs, db_operation from codes.common import clibs, db_operation
from codes.ui.widget_bg_ui import WidgetWithBg from codes.ui.widget_bg_ui import WidgetWithBg
from codes.common.worker import Worker from codes.common.worker import Worker
from typing import Callable, Any from typing import Callable, Any
from codes.common.exception_handler import handle_exception
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.predos()
self.init_ui() self.init_ui()
self.setup_slot() self.setup_slot()
self.predos() self.setup_sc()
def predos(self):
self.m = Path(__file__).stem
self.home_overlay = None
db_operation.db_backup()
clibs.conn, clibs.cursor = db_operation.db_conn()
def init_ui(self): def init_ui(self):
self.setMinimumSize(clibs.win_width, clibs.win_height) self.setMinimumSize(clibs.win_width, clibs.win_height)
@@ -34,9 +41,18 @@ class MainWindow(QMainWindow):
self.centralW = QWidget() self.centralW = QWidget()
self.setCentralWidget(self.centralW) self.setCentralWidget(self.centralW)
self.statusBar = QStatusBar() self.statusBar = QStatusBar()
self.statusBar.setStyleSheet("""
QStatusBar {
background: #8B8989; /* 背景色 */
color: #000000; /* 文字色 */
border: none;
font: 14px "Consolas";
}
""")
self.setStatusBar(self.statusBar) self.setStatusBar(self.statusBar)
# toolbar # toolbar
# homepage
self.ac_homepage = QAction() self.ac_homepage = QAction()
self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole) self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole)
self.ac_homepage.setStatusTip("Go to home page") self.ac_homepage.setStatusTip("Go to home page")
@@ -44,15 +60,91 @@ class MainWindow(QMainWindow):
self.ac_homepage.setText("主页") self.ac_homepage.setText("主页")
self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H")) self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
self.toolBar.addAction(self.ac_homepage) 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.centralW.setLayout(layout_h)
def setup_slot(self): def setup_slot(self):
self.ac_homepage.triggered.connect(self.ac_hp) self.ac_homepage.triggered.connect(self.ac_hp)
# QShortcut("Esc", self).activated.connect(self.close) 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)
def predos(self): def setup_sc(self, stat: bool = True):
self.home_overlay = None if stat:
db_operation.db_backup() self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
self.conn, self.cursor = db_operation.db_conn() self.f11_sc.setEnabled(True)
else:
self.ac_homepage.setShortcut(QKeySequence())
self.f11_sc.setEnabled(False)
def ac_hp(self): def ac_hp(self):
def get_files(dir_path): def get_files(dir_path):
@@ -104,6 +196,7 @@ class MainWindow(QMainWindow):
except Exception as e: except Exception as e:
pass pass
@handle_exception(self.m)
def change_resources(): def change_resources():
# avatar # avatar
src, _ = get_files(f"{clibs.base_path}/assets/media/avatar") src, _ = get_files(f"{clibs.base_path}/assets/media/avatar")
@@ -123,10 +216,10 @@ class MainWindow(QMainWindow):
copy(src, dst) copy(src, dst)
def gen_page(): def gen_page():
self.set_shortcuts(False) self.setup_sc(False)
self.home_overlay = WidgetWithBg(parent=self) self.home_overlay = WidgetWithBg(parent=self)
self.home_overlay.on_closed.connect(self.exit_overlay) self.home_overlay.on_closed.connect(self.exit_overlay)
self.home_overlay.on_full_screen.connect(self.full_screen) self.home_overlay.on_full_screen.connect(self.toggle_full_screen)
self.home_overlay.show() self.home_overlay.show()
width, height = self.width(), self.height() width, height = self.width(), self.height()
if width > clibs.win_width: if width > clibs.win_width:
@@ -138,8 +231,16 @@ class MainWindow(QMainWindow):
self.launch_get_resources(get_resources) self.launch_get_resources(get_resources)
gen_page() gen_page()
def full_screen(self, flag: bool): def ac_sp(self):
if flag == 0: 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 toggle_full_screen(self):
if self.isFullScreen(): if self.isFullScreen():
self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint) self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
self.show() self.show()
@@ -147,33 +248,22 @@ class MainWindow(QMainWindow):
else: else:
self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint) self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
self.showFullScreen() self.showFullScreen()
elif flag == 1:
self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
self.show()
self.showMaximized()
def exit_overlay(self): def exit_overlay(self):
self.set_shortcuts(True) self.setup_sc(True)
self.home_overlay = None
if self.isFullScreen(): if self.isFullScreen():
self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint) self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
self.show() self.show()
self.showMaximized() self.showMaximized()
def set_shortcuts(self, stat: bool = True): def change_stackedW(self, w_item):
if stat: if w_item.text() == "实用工具":
self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H")) self.stackedW.setCurrentWidget(self.w10_practical)
# self.ac_settings.setShortcut(QKeySequence("Ctrl+Alt+S")) elif w_item.text() == "效率提升":
# self.ac_logs.setShortcut(QKeySequence("Ctrl+Alt+L")) self.stackedW.setCurrentWidget(self.w20_efficiency)
# self.ac_about.setShortcut(QKeySequence("Ctrl+Alt+A")) elif w_item.text() == "财务分析":
# self.ac_caging.setShortcut(QKeySequence("Ctrl+Alt+C")) self.stackedW.setCurrentWidget(self.w30_financial)
# self.ac_quit.setShortcut(QKeySequence("Ctrl+Alt+Q"))
else:
self.ac_homepage.setShortcut(QKeySequence())
# self.ac_settings.setShortcut(QKeySequence())
# self.ac_logs.setShortcut(QKeySequence())
# self.ac_about.setShortcut(QKeySequence())
# self.ac_caging.setShortcut(QKeySequence())
# self.ac_quit.setShortcut(QKeySequence())
def launch_get_resources(self, func, on_anything: Callable[..., Any] = None, *args, **kwargs): 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 = Worker(func, *args, **kwargs)
@@ -183,6 +273,11 @@ class MainWindow(QMainWindow):
self.td_get_resources.finished.connect(lambda: None) self.td_get_resources.finished.connect(lambda: None)
self.td_get_resources.start() self.td_get_resources.start()
def sc_F11(self):
if not self.home_overlay:
self.ac_hp()
self.toggle_full_screen()
def resizeEvent(self, event: QResizeEvent): def resizeEvent(self, event: QResizeEvent):
super().resizeEvent(event) super().resizeEvent(event)
if self.home_overlay: if self.home_overlay:
@@ -192,10 +287,9 @@ class MainWindow(QMainWindow):
if self.isFullScreen(): if self.isFullScreen():
event.ignore() event.ignore()
return return
reply = QMessageBox.question(self, "退出", "\n程序可能在运行,确定要退出吗?") reply = QMessageBox.question(self, "退出", "\n程序可能在运行,确定要退出吗?")
if reply == QMessageBox.StandardButton.Yes: if reply == QMessageBox.StandardButton.Yes:
db_operation.db_close(self.conn, self.cursor) db_operation.db_close()
event.accept() event.accept()
else: else:
event.ignore() event.ignore()

View File

@@ -6,139 +6,35 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>602</width> <width>691</width>
<height>376</height> <height>403</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <widget class="QListWidget" name="listWidget">
<item> <property name="geometry">
<layout class="QVBoxLayout" name="verticalLayout"> <rect>
<item> <x>80</x>
<widget class="QLabel" name="label"> <y>60</y>
<property name="text"> <width>101</width>
<string>TextLabel</string> <height>241</height>
</rect>
</property> </property>
</widget> </widget>
</item> <widget class="QStackedWidget" name="stackedWidget">
<item> <property name="geometry">
<widget class="QLabel" name="label_2"> <rect>
<property name="minimumSize"> <x>320</x>
<size> <y>180</y>
<width>125</width> <width>120</width>
<height>125</height> <height>80</height>
</size> </rect>
</property>
<property name="maximumSize">
<size>
<width>125</width>
<height>125</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>../../assets/media/avatar.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property> </property>
<widget class="QWidget" name="page_3"/>
<widget class="QWidget" name="page_4"/>
</widget> </widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Manford Fan · Code Create Life</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>16777215</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LayoutDirection::LeftToRight</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Sunken</enum>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="frameShadow">
<enum>QFrame::Shadow::Sunken</enum>
</property>
<property name="text">
<string>memo</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,9">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>

View File

@@ -34,7 +34,7 @@ class DoubleClickLabel(QLabel):
class WidgetWithBg(QWidget): class WidgetWithBg(QWidget):
on_closed = Signal() on_closed = Signal()
on_full_screen = Signal(int) on_full_screen = Signal()
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
@@ -109,7 +109,6 @@ class WidgetWithBg(QWidget):
layout_h.addWidget(self.line_right) layout_h.addWidget(self.line_right)
layout_h.addStretch(1) layout_h.addStretch(1)
layout_v.addLayout(layout_h) layout_v.addLayout(layout_h)
# layout_v.addWidget(self.line, alignment=Qt.AlignmentFlag.AlignCenter)
self.lb_proverb = QLabel(self) self.lb_proverb = QLabel(self)
self.lb_proverb.setAlignment(Qt.AlignmentFlag.AlignCenter) self.lb_proverb.setAlignment(Qt.AlignmentFlag.AlignCenter)
@@ -123,8 +122,8 @@ class WidgetWithBg(QWidget):
self.le_password.setFont(QFont("Consolas", 12, QFont.Weight.Normal)) self.le_password.setFont(QFont("Consolas", 12, QFont.Weight.Normal))
self.le_password.setMinimumWidth(300) self.le_password.setMinimumWidth(300)
self.le_password.setFixedHeight(30) self.le_password.setFixedHeight(30)
self.hide_le_password()
layout_v.addWidget(self.le_password, alignment=Qt.AlignmentFlag.AlignCenter) layout_v.addWidget(self.le_password, alignment=Qt.AlignmentFlag.AlignCenter)
self.hide_le_password()
self.lb_empty_down = QLabel(self) self.lb_empty_down = QLabel(self)
layout_v.addWidget(self.lb_empty_down) layout_v.addWidget(self.lb_empty_down)
@@ -139,28 +138,29 @@ class WidgetWithBg(QWidget):
self.setLayout(layout_v) self.setLayout(layout_v)
def setup_slot(self): def setup_slot(self):
self.lb_avatar.doubleClicked.connect(self.auth_show) self.lb_avatar.doubleClicked.connect(self.toggle_auth_show)
self.le_password.returnPressed.connect(self.validate_password) self.le_password.returnPressed.connect(self.validate_password)
QShortcut(QKeySequence("Ctrl+Alt+L"), self, self.auth_show) self.sc_caL = QShortcut(QKeySequence("Ctrl+Alt+L"), self)
QShortcut(QKeySequence("Ctrl+Alt+S"), self, lambda: self.on_full_screen.emit(0)) self.sc_caL.activated.connect(self.toggle_auth_show)
# QShortcut(QKeySequence("Esc"), self).activated.connect(lambda: self.on_full_screen.emit(1)) self.sc_caS = QShortcut(QKeySequence("Ctrl+Alt+S"), self)
self.sc_caS.activated.connect(lambda: self.on_full_screen.emit())
def auth_show(self): def toggle_auth_show(self):
if self.input_hide: if self.le_is_visible:
self.show_le_password()
else:
self.hide_le_password() self.hide_le_password()
else:
self.show_le_password()
def show_le_password(self): def show_le_password(self):
self.input_hide = False self.le_is_visible = True
self.le_password.clear() self.le_password.clear()
self.le_password.setPlaceholderText("Password") self.le_password.setPlaceholderText("Password")
self.le_password.setStyleSheet("") self.le_password.setStyleSheet("border:none; border-radius: 5px;")
self.le_password.setDisabled(False) self.le_password.setDisabled(False)
self.le_password.setFocus() self.le_password.setFocus()
def hide_le_password(self): def hide_le_password(self):
self.input_hide = True self.le_is_visible = False
self.le_password.clear() self.le_password.clear()
self.le_password.setDisabled(True) self.le_password.setDisabled(True)
self.le_password.setPlaceholderText("") self.le_password.setPlaceholderText("")
@@ -169,14 +169,17 @@ class WidgetWithBg(QWidget):
def validate_password(self): def validate_password(self):
password = self.le_password.text() password = self.le_password.text()
if password == clibs.password: if password == clibs.password:
self.hide_le_password()
self.on_closed.emit() self.on_closed.emit()
self.close() self.deleteLater()
return True
elif password == "": elif password == "":
self.hide_le_password() self.hide_le_password()
return return False
else: else:
QMessageBox.critical(self, "错误", "密码不正确,请确认后重新输入!") QMessageBox.critical(self, "错误", "密码不正确,请确认后重新输入!")
self.show_le_password() self.show_le_password()
return False
@staticmethod @staticmethod
def circle_pixmap(src: QPixmap, diameter: int) -> QPixmap: def circle_pixmap(src: QPixmap, diameter: int) -> QPixmap:

View File

@@ -1,6 +1,6 @@
import sys import sys
import json import json
from PySide6.QtWidgets import QMainWindow, QApplication from PySide6.QtWidgets import QApplication
from codes.ui import login_ui, main_ui from codes.ui import login_ui, main_ui
from codes.common import clibs from codes.common import clibs
@@ -20,7 +20,7 @@ if __name__ == '__main__':
clibs.account = json.load(f) clibs.account = json.load(f)
app = QApplication(sys.argv) app = QApplication(sys.argv)
window = LoginWindow() # window = LoginWindow()
# window = MainWindow() window = MainWindow()
window.show() window.show()
sys.exit(app.exec()) sys.exit(app.exec())

View File

@@ -0,0 +1,12 @@
# 工具箱
## 功能
## TODOs
### 自定义快捷键
### 修改密码
### 自定义图标