修复一些问题

This commit is contained in:
2025-09-29 11:26:29 +08:00
parent 943130b875
commit ed947743fc
8 changed files with 130 additions and 69 deletions

View File

@@ -16,7 +16,7 @@ win_width, win_height = 1100, 500
conn, cursor = None, None conn, cursor = None, None
listW_items = {"实用工具": "w10_practical", "效率提升": "w20_efficiency", "财务分析": "w30_financial"} listW_items = {"实用工具": "w10_practical", "效率提升": "w20_efficiency", "财务分析": "w30_financial"}
icon = f"{base_path}/assets/media/icon.ico" icon = f"{base_path}/assets/media/icon.ico"
caller_frame = None
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,7 @@
import sqlite3 import sqlite3
import time import time
from inspect import currentframe from inspect import currentframe
from functools import singledispatch from functools import singledispatch, wraps
from codes.common import clibs from codes.common import clibs
@@ -45,7 +45,9 @@ def db_init():
conn.close() conn.close()
def db_lock(func): def db_lock(func):
@wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
clibs.caller_frame = currentframe().f_back
try: try:
clibs.lock.acquire(True) clibs.lock.acquire(True)
ret = func(*args, **kwargs) ret = func(*args, **kwargs)
@@ -93,11 +95,11 @@ def db_close():
@db_lock @db_lock
def db_write_logs(content, module="", level="info"): def db_write_logs(content, module="", level="info"):
if module == "": if module == "" and clibs.caller_frame is not None:
frame = currentframe().f_back module_name = clibs.caller_frame.f_globals["__name__"].split(".")[-1] #
module_name = frame.f_globals["__name__"] func_name = clibs.caller_frame.f_code.co_name
line_no = frame.f_lineno line_no = clibs.caller_frame.f_lineno
module = f"{module_name}.{line_no}" module = f"{module_name}-{func_name}:{line_no}"
if level.lower() not in ["info", "warning", "error", "exception"]: if level.lower() not in ["info", "warning", "error", "exception"]:
level = "unknown" level = "unknown"

View File

@@ -1,19 +1,28 @@
from functools import wraps from functools import wraps
from codes.common import db_operation from codes.common import db_operation
from inspect import getfile from inspect import currentframe
from pathlib import Path import traceback
def handle_exception(stop: bool = False): def handle_exception(stop: bool = False):
def exceptions(func): def exceptions(func):
module = Path(getfile(func)).stem
func_name = func.__name__
@wraps(func) @wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
real_frame = currentframe().f_back
try: try:
return func(*args, **kwargs) return func(*args, **kwargs)
except Exception as e: except Exception as e:
db_operation.db_write_logs(str(e), "@".join([func_name, module]), "exception") for frame, lineno in traceback.walk_tb(e.__traceback__):
if frame.f_code.co_name == func.__name__:
real_frame = frame
break
tb = traceback.format_exc() # 完整堆栈
module_name = real_frame.f_globals["__name__"].split(".")[-1]
func_name = real_frame.f_code.co_name
line_no = real_frame.f_lineno
module = f"{module_name}-{func_name}:{line_no}"
db_operation.db_write_logs(tb, module, "exception")
if stop: if stop:
raise e raise e
return wrapper return wrapper

View File

@@ -1,28 +0,0 @@
import subprocess
import sys
from codes.common import clibs
from pathlib import Path
UIC_CMD = "pyside6-uic"
def single_uic(ui_path: str, py_path: str):
for file in Path(ui_path).rglob("*.ui"):
file_name = file.stem
ui_file = file
py_file = Path(py_path) / f"{file_name}.py"
cmd = [UIC_CMD, "-o", py_file, ui_file]
print(f"Processing {ui_file} -> {py_file}")
try:
subprocess.run(cmd, check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
print(f"转换失败: {ui_file}\n{e.stderr}", file=sys.stderr)
def main():
ui_path = clibs.base_path / "assets" / "ui"
py_path = clibs.base_path / "codes" / "ui"
single_uic(str(ui_path), str(py_path))
if __name__ == "__main__":
main()

View File

@@ -140,18 +140,16 @@ class MainWindow(QMainWindow):
else: else:
image_url = f"""https://www.bing.com{image["url"]}""" image_url = f"""https://www.bing.com{image["url"]}"""
file = Path(f"{clibs.base_path}/assets/media/bg/{image_name}.jpg") file = Path(f"{clibs.base_path}/assets/media/bg/{image_name}.jpg")
try:
req = requests.get(image_url, stream=True, timeout=10) req = requests.get(image_url, stream=True, timeout=10)
with open(file, "wb") as f: with open(file, "wb") as f:
for chunk in req.iter_content(chunk_size=8192): for chunk in req.iter_content(chunk_size=8192):
f.write(chunk) f.write(chunk)
except Exception as e:
pass
# proverbs # proverbs
hitokoto = "https://v1.hitokoto.cn/" hitokoto = "https://v1.hitokoto.cn/"
proverbs = [] proverbs = []
proverb_file = Path(f"{clibs.base_path}/assets/media/hitokoto.json") proverb_file = Path(f"{clibs.base_path}/assets/media/hitokoto.json")
req = requests.get(hitokoto) req = requests.get(hitokoto)
print(f"req.text = {req.text}")
if not proverb_file.exists(): if not proverb_file.exists():
proverb_file.touch() proverb_file.touch()
proverb_file.write_text("[]") proverb_file.write_text("[]")
@@ -160,7 +158,18 @@ class MainWindow(QMainWindow):
with open(proverb_file, mode="rt", encoding="utf-8") as f: with open(proverb_file, mode="rt", encoding="utf-8") as f:
proverbs = json.load(f) proverbs = json.load(f)
proverbs.append(eval(req.text)) proverb = json.loads(req.text)
if None in proverb.values():
for k, v in proverb.items():
if v is None:
if v == "from_who":
proverb.update({k: "佚名"})
elif v == "from":
proverb.update({k: "不知道"})
else:
proverb.update({k: "-"})
proverbs.append(proverb)
proverbs = del_repeat_proverb(proverbs) proverbs = del_repeat_proverb(proverbs)
with open(proverb_file, mode="wt", encoding="utf-8") as f: with open(proverb_file, mode="wt", encoding="utf-8") as f:
json.dump(proverbs, f, ensure_ascii=False) json.dump(proverbs, f, ensure_ascii=False)

View File

@@ -10,20 +10,32 @@ from codes.common.signal_bus import signal_bus
class LunarClockLabel(QLabel): class LunarClockLabel(QLabel):
def __init__(self, parent=None): def __init__(self, parent=None, flag=0):
super().__init__(parent) super().__init__(parent)
self.setMinimumWidth(350) self.setMinimumWidth(350)
timer = QTimer(self) timer = QTimer(self)
timer.timeout.connect(self.update_time)
timer.start(1000) timer.start(1000)
if flag == 0:
self.update_date()
timer.timeout.connect(self.update_date)
else:
self.update_time() self.update_time()
timer.timeout.connect(self.update_time)
def update_date(self):
dt = QDateTime.currentDateTime()
g = dt.date()
z = ZhDate.today()
week = "一二三四五六日"[g.dayOfWeek() - 1]
text = f"{g.year()}{g.month()}{g.day()}{z.chinese()[5:]} 星期{week}"
self.setText(text)
def update_time(self): def update_time(self):
dt = QDateTime.currentDateTime() dt = QDateTime.currentDateTime()
g = dt.date() g = dt.date()
z = ZhDate.today() z = ZhDate.today()
week = "一二三四五六日"[g.dayOfWeek() - 1] week = "一二三四五六日"[g.dayOfWeek() - 1]
text = f"{g.year()}{g.month()}{g.day()}{z.chinese()[5:]} 星期{week} {dt.toString('hh:mm:ss')}" text = f"{dt.toString('hh:mm:ss')}"
self.setText(text) self.setText(text)
@@ -54,6 +66,8 @@ class WidgetWithBg(QWidget):
self.lb_empty_up = QLabel(self) self.lb_empty_up = QLabel(self)
layout_v.addWidget(self.lb_empty_up) layout_v.addWidget(self.lb_empty_up)
# 头像区 # 头像区
layout_h_1 = QHBoxLayout()
layout_h_1.addStretch(1)
self.lb_avatar = DoubleClickLabel(self) self.lb_avatar = DoubleClickLabel(self)
self.lb_avatar.setAlignment(Qt.AlignmentFlag.AlignCenter) self.lb_avatar.setAlignment(Qt.AlignmentFlag.AlignCenter)
avatar = QPixmap(clibs.avatar) avatar = QPixmap(clibs.avatar)
@@ -61,7 +75,15 @@ class WidgetWithBg(QWidget):
self.lb_avatar.setPixmap(avatar) self.lb_avatar.setPixmap(avatar)
self.lb_avatar.setScaledContents(True) self.lb_avatar.setScaledContents(True)
self.lb_avatar.setFixedSize(144, 144) self.lb_avatar.setFixedSize(144, 144)
layout_v.addWidget(self.lb_avatar, alignment=Qt.AlignmentFlag.AlignCenter) layout_h_1.addWidget(self.lb_avatar)
self.lb_time = LunarClockLabel(self, flag=1)
self.lb_time.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.lb_time.setStyleSheet("color: rgba(255,255,255,255);")
self.lb_time.setFont(QFont("Arial Black", 56, QFont.Weight.Bold))
layout_h_1.addWidget(self.lb_time)
layout_h_1.addStretch(1)
layout_v.addLayout(layout_h_1)
# layout_v.addWidget(self.lb_avatar, alignment=Qt.AlignmentFlag.AlignCenter)
# 艺术字区 # 艺术字区
self.lb_name = QLabel(self) self.lb_name = QLabel(self)
self.lb_name.setAlignment(Qt.AlignmentFlag.AlignCenter) self.lb_name.setAlignment(Qt.AlignmentFlag.AlignCenter)
@@ -99,13 +121,13 @@ class WidgetWithBg(QWidget):
self.line_right.setLineWidth(1) self.line_right.setLineWidth(1)
self.line_right.setFixedWidth(100) self.line_right.setFixedWidth(100)
# 时间区-时间 # 时间区-时间
self.lb_time = LunarClockLabel(self) self.lb_date = LunarClockLabel(self)
self.lb_time.setAlignment(Qt.AlignmentFlag.AlignCenter) self.lb_date.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.lb_time.setStyleSheet("color: rgba(255,255,255,255);") self.lb_date.setStyleSheet("color: rgba(255,255,255,255);")
self.lb_time.setFont(QFont("Consolas", 12, QFont.Weight.Bold)) self.lb_date.setFont(QFont("Consolas", 12, QFont.Weight.Bold))
layout_h.addStretch(1) layout_h.addStretch(1)
layout_h.addWidget(self.line_left) layout_h.addWidget(self.line_left)
layout_h.addWidget(self.lb_time) layout_h.addWidget(self.lb_date)
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)
@@ -141,10 +163,6 @@ class WidgetWithBg(QWidget):
self.lb_avatar.doubleClicked.connect(self.toggle_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)
signal_bus.home_overlay_auth.connect(self.toggle_auth_show) 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): def toggle_auth_show(self):
if self.le_is_visible: if self.le_is_visible:
@@ -178,7 +196,7 @@ class WidgetWithBg(QWidget):
self.hide_le_password() self.hide_le_password()
return False return False
else: else:
QMessageBox.critical(self, "错误", "密码不正确,请确认后重新输入!") # QMessageBox.critical(self, "错误", "密码不正确,请确认后重新输入!")
self.show_le_password() self.show_le_password()
return False return False

View File

@@ -1,4 +1,4 @@
from PySide6.QtWidgets import QWidget, QLabel, QMessageBox, QVBoxLayout, QTreeWidget, QHBoxLayout, QPushButton, QFrame, QLineEdit, QCheckBox, QTreeWidgetItem, QDialog from PySide6.QtWidgets import QWidget, QLabel, QMessageBox, QVBoxLayout, QTreeWidget, QHeaderView, QHBoxLayout, QPushButton, QFrame, QLineEdit, QCheckBox, QTreeWidgetItem, QDialog, QPlainTextEdit, QApplication
from PySide6.QtCore import Qt, Signal from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QColor, QIcon, QFont, QKeySequence, QIntValidator, QShortcut from PySide6.QtGui import QColor, QIcon, QFont, QKeySequence, QIntValidator, QShortcut
@@ -6,6 +6,30 @@ from codes.common.signal_bus import signal_bus
from codes.common import db_operation from codes.common import db_operation
from codes.common import clibs from codes.common import clibs
class LogDialog(QDialog):
def __init__(self, content, parent=None):
super().__init__(parent)
self.setWindowTitle("日志详情")
self.setGeometry(100, 100, 700, 300)
self.center_on_screen()
layout = QVBoxLayout(self)
self.plain_text_edit = QPlainTextEdit()
self.plain_text_edit.setReadOnly(True)
self.plain_text_edit.setPlainText(content)
layout.addWidget(self.plain_text_edit)
def center_on_screen(self):
screen_geometry = QApplication.primaryScreen().geometry()
screen_width = screen_geometry.width()
screen_height = screen_geometry.height()
dialog_width = self.width()
dialog_height = self.height()
x = (screen_width - dialog_width) // 2
y = (screen_height - dialog_height) // 2
self.move(x, y)
class PageNumberInput(QDialog): class PageNumberInput(QDialog):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
@@ -64,7 +88,11 @@ class W08Log(QWidget):
def ui_init(self): def ui_init(self):
layout_v = QVBoxLayout(self) layout_v = QVBoxLayout(self)
self.treeW = QTreeWidget() self.treeW = QTreeWidget()
self.treeW.setUniformRowHeights(True)
self.treeW.setHeaderLabels(["ID", "时间戳", "告警级别", "模块信息", "告警内容"]) self.treeW.setHeaderLabels(["ID", "时间戳", "告警级别", "模块信息", "告警内容"])
header = self.treeW.header()
for i in range(self.treeW.columnCount()):
header.setSectionResizeMode(i, QHeaderView.ResizeMode.ResizeToContents)
layout_v.addWidget(self.treeW, stretch=9) layout_v.addWidget(self.treeW, stretch=9)
layout_h = QHBoxLayout() layout_h = QHBoxLayout()
@@ -113,6 +141,7 @@ class W08Log(QWidget):
self.setLayout(layout_v) self.setLayout(layout_v)
def setup_slot(self): def setup_slot(self):
self.treeW.itemDoubleClicked.connect(self.show_single_log)
self.pb_previous.clicked.connect(self.previous_page) self.pb_previous.clicked.connect(self.previous_page)
self.pb_next.clicked.connect(self.next_page) self.pb_next.clicked.connect(self.next_page)
self.pb_search.clicked.connect(self.search_page) self.pb_search.clicked.connect(self.search_page)
@@ -153,9 +182,6 @@ class W08Log(QWidget):
self.records, self.len_records = db_operation.db_query_logs(levels=levels) self.records, self.len_records = db_operation.db_query_logs(levels=levels)
if search_text: if search_text:
# ids = [_[0] for _ in self.records]
# placeholder = ",".join(ids)
# clibs.cursor.execute(f"SELECT * FROM logs WHERE id IN ({placeholder}) and content like ?", (ids + [search_text, ]))
self.records, self.len_records = db_operation.db_query_logs(search_text, self.records) self.records, self.len_records = db_operation.db_query_logs(search_text, self.records)
self.is_searching = True self.is_searching = True
@@ -219,6 +245,16 @@ class W08Log(QWidget):
color = colors[record[2]] color = colors[record[2]]
for col in range(5): for col in range(5):
item.setBackground(col, color) item.setBackground(col, color)
item.setTextAlignment(0, Qt.AlignmentFlag.AlignRight)
self.treeW.scrollToBottom() self.treeW.scrollToBottom()
def show_single_log(self, item, column):
log_id = f"id = {item.text(0)}"
log_ts = f"ts = {item.text(1)}"
log_level = f"level = {item.text(2)}"
log_module = f"module = {item.text(3)}\n"
deco_line = "=" * 40
log_msg = item.text(4)
content = "\n".join([log_id, log_ts, log_level, log_module, deco_line, log_msg])
dialog = LogDialog(content, self)
dialog.exec()

View File

@@ -2,6 +2,19 @@
## 功能 ## 功能
### 计算器
### 颜色板
### 时间转换
### ASCII码速查
### 账本
### 待办提醒
### 密码
## TODOs ## TODOs
@@ -10,3 +23,5 @@
### 修改密码 ### 修改密码
### 自定义图标 ### 自定义图标