Files
Projects/toolbox/codes/ui/main_ui.py

303 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
from shutil import copy
from random import choice
from pathlib import Path
import sys
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
from codes.common import clibs, db_operation
from codes.ui.widget_bg_ui import WidgetWithBg
from codes.common.worker import Worker
from typing import Callable, Any
from codes.common.exception_handler import handle_exception
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.predos()
self.init_ui()
self.setup_slot()
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):
self.setMinimumSize(clibs.win_width, clibs.win_height)
self.resize(clibs.win_width, clibs.win_height)
self.setWindowTitle("Toolbox")
self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
self.setFont(QFont("Consolas", 14))
# 任务栏/主窗口/状态栏
self.toolBar = QToolBar()
self.addToolBar(self.toolBar)
self.toolBar.setMovable(False)
self.centralW = QWidget()
self.setCentralWidget(self.centralW)
self.statusBar = QStatusBar()
self.statusBar.setStyleSheet("""
QStatusBar {
background: #8B8989; /* 背景色 */
color: #000000; /* 文字色 */
border: none;
font: 14px "Consolas";
}
""")
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.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)
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 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
def del_repeat_proverb(proverbs: list):
_proverbs = []
for proverb in proverbs:
if proverb not in _proverbs:
_proverbs.append(proverb)
return _proverbs
def get_resources():
# background image
bing = "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=8"
req = requests.get(bing)
res = req.json()
_, files = get_files(f"{clibs.base_path}/assets/media/bg")
image_names = []
for file in files:
image_names.append(file.name.removesuffix(".jpg"))
for image in res["images"]:
startdate = image["startdate"]
if startdate 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")
try:
req = requests.get(image_url, stream=True, timeout=10)
with open(file, "wb") as f:
for chunk in req.iter_content(chunk_size=8192):
f.write(chunk)
except Exception as e:
pass
# 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
@handle_exception(self.m)
def change_resources():
# avatar
src, _ = get_files(f"{clibs.base_path}/assets/media/avatar")
dst = f"{clibs.base_path}/assets/media/avatar.jpg"
copy(src, dst)
# proverbs
with open(f"{clibs.base_path}/assets/media/hitokoto.json", mode="r", encoding="utf-8") as f:
proverbs = json.load(f)
res = choice(proverbs)
sentence = res["hitokoto"]
from_where = res["from"]
from_who = res["from_who"]
clibs.proverb = f"{sentence}\t\t※⌈{from_where}⌋ | {from_who}"
# bg
src, _ = get_files(f"{clibs.base_path}/assets/media/bg")
dst = f"{clibs.base_path}/assets/media/bg.jpg"
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()
width, height = self.width(), self.height()
if width > clibs.win_width:
self.resize(self.width()-1, self.height()-1)
else:
self.resize(clibs.win_width+1, clibs.win_height+1)
change_resources()
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 toggle_full_screen(self):
if self.isFullScreen():
self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
self.show()
self.showMaximized()
else:
self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
self.showFullScreen()
def exit_overlay(self):
self.setup_sc(True)
self.home_overlay = None
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):
if not self.home_overlay:
self.ac_hp()
self.toggle_full_screen()
def resizeEvent(self, event: QResizeEvent):
super().resizeEvent(event)
if self.home_overlay:
self.home_overlay.setGeometry(self.rect())
def closeEvent(self, event):
if self.isFullScreen():
event.ignore()
return
reply = QMessageBox.question(self, "退出", "\n程序可能在运行,确定要退出吗?")
if reply == QMessageBox.StandardButton.Yes:
db_operation.db_close()
event.accept()
else:
event.ignore()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())