提交一下,准备更换总线通信架构
This commit is contained in:
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.
Binary file not shown.
Binary file not shown.
BIN
toolbox/assets/database/toolbox.20250926171243.db
Normal file
BIN
toolbox/assets/database/toolbox.20250926171243.db
Normal file
Binary file not shown.
BIN
toolbox/assets/database/toolbox.20250926171258.db
Normal file
BIN
toolbox/assets/database/toolbox.20250926171258.db
Normal file
Binary file not shown.
BIN
toolbox/assets/database/toolbox.20250926171311.db
Normal file
BIN
toolbox/assets/database/toolbox.20250926171311.db
Normal file
Binary file not shown.
BIN
toolbox/assets/database/toolbox.20250926171522.db
Normal file
BIN
toolbox/assets/database/toolbox.20250926171522.db
Normal file
Binary file not shown.
BIN
toolbox/assets/database/toolbox.20250927083347.db
Normal file
BIN
toolbox/assets/database/toolbox.20250927083347.db
Normal file
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 |
BIN
toolbox/assets/media/bg/20250926.jpg
Normal file
BIN
toolbox/assets/media/bg/20250926.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 324 KiB |
File diff suppressed because one or more lines are too long
@@ -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():
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
15
toolbox/codes/common/exception_handler.py
Normal file
15
toolbox/codes/common/exception_handler.py
Normal 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
|
||||||
@@ -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()
|
||||||
QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
|
if not exception:
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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,25 +41,110 @@ 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 homepage")
|
self.ac_homepage.setStatusTip("Go to home page")
|
||||||
self.ac_homepage.setToolTip("Ctrl+Alt+H")
|
self.ac_homepage.setToolTip("Ctrl+Alt+H")
|
||||||
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,42 +231,39 @@ 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)
|
||||||
if self.isFullScreen():
|
|
||||||
self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
|
def ac_lp(self):
|
||||||
self.show()
|
self.stackedW.setCurrentWidget(self.w08_log)
|
||||||
self.showMaximized()
|
|
||||||
else:
|
def ac_ap(self):
|
||||||
self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
|
self.stackedW.setCurrentWidget(self.w09_about)
|
||||||
self.showFullScreen()
|
|
||||||
elif flag == 1:
|
def toggle_full_screen(self):
|
||||||
|
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()
|
||||||
|
else:
|
||||||
|
self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
|
||||||
|
self.showFullScreen()
|
||||||
|
|
||||||
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()
|
||||||
|
|||||||
@@ -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>
|
||||||
</property>
|
</rect>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
<widget class="QLabel" name="label_2">
|
<property name="geometry">
|
||||||
<property name="minimumSize">
|
<rect>
|
||||||
<size>
|
<x>320</x>
|
||||||
<width>125</width>
|
<y>180</y>
|
||||||
<height>125</height>
|
<width>120</width>
|
||||||
</size>
|
<height>80</height>
|
||||||
</property>
|
</rect>
|
||||||
<property name="maximumSize">
|
</property>
|
||||||
<size>
|
<widget class="QWidget" name="page_3"/>
|
||||||
<width>125</width>
|
<widget class="QWidget" name="page_4"/>
|
||||||
<height>125</height>
|
</widget>
|
||||||
</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>
|
|
||||||
</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/>
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# 工具箱
|
||||||
|
|
||||||
|
## 功能
|
||||||
|
|
||||||
|
|
||||||
|
## TODOs
|
||||||
|
|
||||||
|
### 自定义快捷键
|
||||||
|
|
||||||
|
### 修改密码
|
||||||
|
|
||||||
|
### 自定义图标
|
||||||
Reference in New Issue
Block a user