new project for personal toolbox

This commit is contained in:
2025-09-09 16:22:57 +08:00
parent 4bacbb7bb8
commit 648dedb611
33 changed files with 1555 additions and 20 deletions

14
gui/Readme.md Normal file
View File

@@ -0,0 +1,14 @@
## README
###
### 收支记录
### 图片处理
### 颜色拾取
### 密码管理

View File

@@ -0,0 +1,5 @@
{
"account": {
"Fan": "Ka2trNyfHPci26UGt3bVyvFjNuUoW9/0QcBVOR79KIw="
}
}

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.

View File

BIN
gui/assets/media/avatar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

BIN
gui/assets/media/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

94
gui/assets/ui/app.ui Normal file
View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1100</width>
<height>550</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>1100</width>
<height>550</height>
</size>
</property>
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Toolbox</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1100</width>
<height>33</height>
</rect>
</property>
<widget class="QMenu" name="menu">
<property name="title">
<string>文件</string>
</property>
<addaction name="action_4"/>
<addaction name="action_3"/>
</widget>
<widget class="QMenu" name="menu_2">
<property name="title">
<string>帮助</string>
</property>
<addaction name="action_2"/>
</widget>
<widget class="QMenu" name="menu_3">
<property name="title">
<string>日志</string>
</property>
</widget>
<addaction name="menu"/>
<addaction name="menu_3"/>
<addaction name="menu_2"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
<action name="action">
<property name="text">
<string>关于</string>
</property>
</action>
<action name="actionExit_2">
<property name="text">
<string>Exit</string>
</property>
</action>
<action name="action_2">
<property name="text">
<string>关于</string>
</property>
</action>
<action name="action_3">
<property name="text">
<string>退出</string>
</property>
</action>
<action name="action_4">
<property name="text">
<string>设置</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

212
gui/assets/ui/login.ui Normal file
View File

@@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>login</class>
<widget class="QWidget" name="login">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>150</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>450</width>
<height>150</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>450</width>
<height>150</height>
</size>
</property>
<property name="windowTitle">
<string>登录</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="lb_logo">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>105</width>
<height>105</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="indent">
<number>-1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lb_none">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="labelAlignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="leftMargin">
<number>30</number>
</property>
<property name="topMargin">
<number>15</number>
</property>
<property name="rightMargin">
<number>30</number>
</property>
<property name="bottomMargin">
<number>15</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="lb_username">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="le_username">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lb_password">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="le_password">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="echoMode">
<enum>QLineEdit::EchoMode::Password</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>40</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>40</number>
</property>
<property name="bottomMargin">
<number>20</number>
</property>
<item>
<widget class="QPushButton" name="pb_login">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>登录</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pb_cancel">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>12</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>取消</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

0
gui/codes/__init__.py Normal file
View File

View File

View File

View File

@@ -0,0 +1,6 @@
from pathlib import Path
base_path = Path(__file__).resolve().parent.parent.parent
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]
salt = ""
max_db_number = 10

View File

@@ -0,0 +1,64 @@
import sqlite3
from threading import Lock
import time
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(
"""
create table if not exists logs(
id integer primary key autoincrement,
timestamp DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime')),
level text,
module text,
content text
)
"""
)
cursor.close()
conn.close()
def db_lock(func):
def wrapper(*args, **kwargs):
try:
Lock().acquire(True)
ret = func(*args, **kwargs)
finally:
Lock().release()
return ret
return wrapper
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")]
print(f"db_list: {sorted(db_list)}")
for db in sorted(db_list)[:-clibs.max_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=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")
return conn, cursor

View File

@@ -0,0 +1,37 @@
import base64
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Util.Padding import pad, unpad
class PassCipher:
def __init__(self, salt):
salt = salt.encode("utf-8")
self.key = hashlib.sha256(salt).digest()
def encrypt(self, plaintext):
plaintext = plaintext.encode("utf-8")
iv = Random.new().read(AES.block_size)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))
return base64.b64encode(iv + ciphertext).decode("utf-8")
def decrypt(self, ciphertext):
ciphertext = base64.b64decode(ciphertext)
iv = ciphertext[:AES.block_size]
ciphertext = ciphertext[AES.block_size:]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size)
return plaintext.decode("utf-8")
# if __name__ == "__main__":
# salt = "my_secret_salt_string"
# cipher = PassCipher(salt)
# original_text = "这是一段需要加密的敏感信息"
# encrypted_text = cipher.encrypt(original_text)
# print(f"加密后的文本: {encrypted_text}")
# decrypted_text = cipher.decrypt(encrypted_text)
# print(f"解密后的文本: {decrypted_text}")
# print(f"加解密是否成功: {original_text == decrypted_text}")

26
gui/codes/common/ui2py.py Normal file
View File

@@ -0,0 +1,26 @@
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)
if __name__ == "__main__":
ui_path = clibs.base_path / "assets" / "ui"
py_path = clibs.base_path / "codes" / "ui"
single_uic(str(ui_path), str(py_path))

View File

@@ -0,0 +1,40 @@
from PySide6.QtCore import QThread, Signal, QRunnable, QThreadPool, QMetaObject, Q_ARG, QMetaType, Qt
from typing import Callable, Any
class Worker(QThread):
result = Signal(dict)
error = Signal(dict)
def __init__(self, func, *args, **kwargs):
super().__init__()
self.func = func
self.args = args
self.kwargs = kwargs
def run(self):
try:
result = self.func(*self.args, **self.kwargs)
self.result.emit({"result": result})
except Exception as error:
self.error.emit({"error": str(error)})
# launch函数必须在主进程中定义调用
# def launch(self, func, on_anything: Callable[..., Any] = print, *args, **kwargs):
# self.thread = Worker(func, *args, **kwargs)
# self.thread.started.connect(lambda: on_anything({"started": True}))
# self.thread.result.connect(on_anything)
# self.thread.error.connect(on_anything)
# self.thread.finished.connect(lambda: on_anything({"finished": True}))
# self.thread.start()
#
#
# def on_anything(results):
# if "started" in results:
# print("运行开始:", results["started"])
# if "result" in results:
# print("正常结束:", results["result"])
# if "error" in results:
# print(f"有异常发生:", results["error"])
# if "finished" in results:
# print("运行结束:", results["finished"])

0
gui/codes/ui/__init__.py Normal file
View File

85
gui/codes/ui/app.py Normal file
View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'app.ui'
##
## Created by: Qt User Interface Compiler version 6.9.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
QCursor, QFont, QFontDatabase, QGradient,
QIcon, QImage, QKeySequence, QLinearGradient,
QPainter, QPalette, QPixmap, QRadialGradient,
QTransform)
from PySide6.QtWidgets import (QApplication, QMainWindow, QMenu, QMenuBar,
QSizePolicy, QStatusBar, QWidget)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(1100, 550)
MainWindow.setMinimumSize(QSize(1100, 550))
font = QFont()
font.setFamilies([u"Consolas"])
font.setPointSize(12)
MainWindow.setFont(font)
self.actionExit = QAction(MainWindow)
self.actionExit.setObjectName(u"actionExit")
self.action = QAction(MainWindow)
self.action.setObjectName(u"action")
self.actionExit_2 = QAction(MainWindow)
self.actionExit_2.setObjectName(u"actionExit_2")
self.action_2 = QAction(MainWindow)
self.action_2.setObjectName(u"action_2")
self.action_3 = QAction(MainWindow)
self.action_3.setObjectName(u"action_3")
self.action_4 = QAction(MainWindow)
self.action_4.setObjectName(u"action_4")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0, 0, 1100, 33))
self.menu = QMenu(self.menubar)
self.menu.setObjectName(u"menu")
self.menu_2 = QMenu(self.menubar)
self.menu_2.setObjectName(u"menu_2")
self.menu_3 = QMenu(self.menubar)
self.menu_3.setObjectName(u"menu_3")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menubar.addAction(self.menu.menuAction())
self.menubar.addAction(self.menu_3.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menu.addAction(self.action_4)
self.menu.addAction(self.action_3)
self.menu_2.addAction(self.action_2)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Toolbox", None))
self.actionExit.setText(QCoreApplication.translate("MainWindow", u"Exit", None))
self.action.setText(QCoreApplication.translate("MainWindow", u"\u5173\u4e8e", None))
self.actionExit_2.setText(QCoreApplication.translate("MainWindow", u"Exit", None))
self.action_2.setText(QCoreApplication.translate("MainWindow", u"\u5173\u4e8e", None))
self.action_3.setText(QCoreApplication.translate("MainWindow", u"\u9000\u51fa", None))
self.action_4.setText(QCoreApplication.translate("MainWindow", u"\u8bbe\u7f6e", None))
self.menu.setTitle(QCoreApplication.translate("MainWindow", u"\u6587\u4ef6", None))
self.menu_2.setTitle(QCoreApplication.translate("MainWindow", u"\u5e2e\u52a9", None))
self.menu_3.setTitle(QCoreApplication.translate("MainWindow", u"\u65e5\u5fd7", None))
# retranslateUi

145
gui/codes/ui/login.py Normal file
View File

@@ -0,0 +1,145 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'login.ui'
##
## Created by: Qt User Interface Compiler version 6.9.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QFormLayout, QHBoxLayout, QLabel,
QLineEdit, QPushButton, QSizePolicy, QVBoxLayout,
QWidget)
class Ui_login(object):
def setupUi(self, login):
if not login.objectName():
login.setObjectName(u"login")
login.resize(450, 150)
sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(login.sizePolicy().hasHeightForWidth())
login.setSizePolicy(sizePolicy)
login.setMinimumSize(QSize(450, 150))
login.setMaximumSize(QSize(450, 150))
self.verticalLayout_3 = QVBoxLayout(login)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.verticalLayout_2 = QVBoxLayout()
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.lb_logo = QLabel(login)
self.lb_logo.setObjectName(u"lb_logo")
self.lb_logo.setMinimumSize(QSize(100, 100))
self.lb_logo.setMaximumSize(QSize(105, 105))
self.lb_logo.setScaledContents(True)
self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.lb_logo.setMargin(0)
self.lb_logo.setIndent(-1)
self.verticalLayout_2.addWidget(self.lb_logo)
self.lb_none = QLabel(login)
self.lb_none.setObjectName(u"lb_none")
self.lb_none.setMinimumSize(QSize(0, 40))
self.verticalLayout_2.addWidget(self.lb_none)
self.horizontalLayout_2.addLayout(self.verticalLayout_2)
self.verticalLayout = QVBoxLayout()
self.verticalLayout.setObjectName(u"verticalLayout")
self.formLayout = QFormLayout()
self.formLayout.setObjectName(u"formLayout")
self.formLayout.setLabelAlignment(Qt.AlignmentFlag.AlignCenter)
self.formLayout.setFormAlignment(Qt.AlignmentFlag.AlignCenter)
self.formLayout.setContentsMargins(30, 15, 30, 15)
self.lb_username = QLabel(login)
self.lb_username.setObjectName(u"lb_username")
font = QFont()
font.setFamilies([u"Consolas"])
font.setPointSize(12)
font.setItalic(True)
self.lb_username.setFont(font)
self.formLayout.setWidget(0, QFormLayout.ItemRole.LabelRole, self.lb_username)
self.le_username = QLineEdit(login)
self.le_username.setObjectName(u"le_username")
font1 = QFont()
font1.setFamilies([u"Consolas"])
font1.setPointSize(12)
self.le_username.setFont(font1)
self.formLayout.setWidget(0, QFormLayout.ItemRole.FieldRole, self.le_username)
self.lb_password = QLabel(login)
self.lb_password.setObjectName(u"lb_password")
self.lb_password.setFont(font)
self.formLayout.setWidget(1, QFormLayout.ItemRole.LabelRole, self.lb_password)
self.le_password = QLineEdit(login)
self.le_password.setObjectName(u"le_password")
self.le_password.setFont(font1)
self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
self.formLayout.setWidget(1, QFormLayout.ItemRole.FieldRole, self.le_password)
self.verticalLayout.addLayout(self.formLayout)
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.horizontalLayout.setContentsMargins(40, 0, 40, 20)
self.pb_login = QPushButton(login)
self.pb_login.setObjectName(u"pb_login")
font2 = QFont()
font2.setFamilies([u"Consolas"])
font2.setPointSize(12)
font2.setBold(True)
self.pb_login.setFont(font2)
self.horizontalLayout.addWidget(self.pb_login)
self.pb_cancel = QPushButton(login)
self.pb_cancel.setObjectName(u"pb_cancel")
self.pb_cancel.setFont(font2)
self.horizontalLayout.addWidget(self.pb_cancel)
self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_2.addLayout(self.verticalLayout)
self.verticalLayout_3.addLayout(self.horizontalLayout_2)
self.retranslateUi(login)
QMetaObject.connectSlotsByName(login)
# setupUi
def retranslateUi(self, login):
login.setWindowTitle(QCoreApplication.translate("login", u"\u767b\u5f55", None))
self.lb_logo.setText("")
self.lb_none.setText("")
self.lb_username.setText(QCoreApplication.translate("login", u"Username", None))
self.lb_password.setText(QCoreApplication.translate("login", u"Password", None))
self.pb_login.setText(QCoreApplication.translate("login", u"\u767b\u5f55", None))
self.pb_cancel.setText(QCoreApplication.translate("login", u"\u53d6\u6d88", None))
# retranslateUi

104
gui/main.py Normal file
View File

@@ -0,0 +1,104 @@
import json
import sys
import base64
import time
from typing import Callable, Any
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QMainWindow
from PySide6.QtGui import QIcon, QPixmap, QShortcut
from PySide6.QtCore import Qt
from codes.ui.login import Ui_login
from codes.ui.app import Ui_MainWindow
from codes.common.worker import Worker
from codes.common import clibs
from codes.common.secure_encrypt import PassCipher
from codes.common import db_operation
class LoginWindow(QWidget, Ui_login):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pre_dos()
def pre_dos(self):
self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
self.lb_logo.setPixmap(QPixmap(f"{clibs.base_path}/assets/media/avatar.png"))
self.lb_logo.setScaledContents(True)
# bindings
QShortcut("Esc", self).activated.connect(self.close)
self.pb_login.clicked.connect(self.login)
self.pb_cancel.clicked.connect(self.close)
self.le_password.returnPressed.connect(self.login)
def login(self):
def login_failed():
QMessageBox.warning(self, "告警", "\n用户名或密码不正确,请重新输入!")
self.le_username.setText("")
self.le_password.setText("")
def gen_salt():
clibs.salt = ""
key = ""
passwd = {idx: char for idx, char in enumerate(self.le_password.text() * 4)}
for idx in range(32):
char_i = 0 if ord(passwd[idx]) - clibs.code_dict[idx] < 0 else ord(passwd[idx]) - clibs.code_dict[idx]
key += chr(char_i)
clibs.salt = base64.urlsafe_b64encode(key.encode()).decode()
def validate_login():
# with open(f"{clibs.base_path}/assets/conf/config.json", mode="rt", encoding="utf-8") as f_conf:
# accounts = json.load(f_conf)["account"]
# username = self.le_username.text()
# if username not in accounts or len(self.le_password.text()) < 8:
# login_failed()
# return False
#
# gen_salt()
# cipher = PassCipher(clibs.salt)
# try:
# password = cipher.decrypt(accounts[username])
# except ValueError:
# login_failed()
# return False
#
# if password != self.le_password.text():
# login_failed()
# return False
self.mainWindow = MainWindow()
self.mainWindow.show()
self.close()
self.deleteLater()
return True
validate_login()
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.conn = None
self.cursor = None
self.thread = None
self.setupUi(self)
self.pre_dos()
def pre_dos(self):
self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
db_operation.db_backup()
self.conn, self.cursor = db_operation.db_conn()
def launch(self, func, on_anything: Callable[..., Any] = print, *args, **kwargs):
self.thread = Worker(func, *args, **kwargs)
self.thread.started.connect(lambda: on_anything({"started": True}))
self.thread.result.connect(on_anything)
self.thread.error.connect(on_anything)
self.thread.finished.connect(lambda: on_anything({"finished": True}))
self.thread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
login = LoginWindow()
login.show()
sys.exit(app.exec())