mirror of
https://gitee.com/firemage/mhxyQA_GUI.git
synced 2026-05-07 01:01:05 +08:00
gui refactoring
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
.venv
|
||||
.venv*
|
||||
__pycache__
|
||||
images/shot/*
|
||||
dist
|
||||
|
||||
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python 调试程序: 当前文件",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
import json
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtCore import Qt, QRegExp
|
||||
from PyQt5.QtWidgets import (QWidget, QGroupBox, QPushButton, QHBoxLayout, QLineEdit, QTextEdit, QLabel,
|
||||
QVBoxLayout, QGridLayout, QComboBox, QListWidget, QMessageBox, QListWidgetItem)
|
||||
from PyQt5.QtGui import QIcon, QRegExpValidator
|
||||
from core.maocr import maocr
|
||||
from core.util import is_valid_email
|
||||
from core.log import logger
|
||||
import setting as c
|
||||
|
||||
class SFormSignup(QWidget):
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__()
|
||||
|
||||
self.setWindowIcon(QIcon(c.icon_dir_path))
|
||||
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
|
||||
|
||||
self.initUI()
|
||||
|
||||
# 计算并设置新窗口的位置
|
||||
self.setGeometry(0, 0, 300, 230)
|
||||
self.move(parent.frameGeometry().topLeft() + parent.rect().center() - self.rect().center())
|
||||
|
||||
# 绘制界面
|
||||
def initUI(self):
|
||||
|
||||
self.CreateWindowCommbo()
|
||||
|
||||
gridLayout = QGridLayout()
|
||||
gridLayout.addWidget(self.vWinGroupBox, 0, 0, QtCore.Qt.AlignLeft)
|
||||
|
||||
# 调用方法绘制界面
|
||||
self.setWindowTitle(c.WINTITLE)
|
||||
mainLayout = QHBoxLayout()
|
||||
mainLayout.addLayout(gridLayout)
|
||||
self.setLayout(mainLayout)
|
||||
|
||||
def CreateWindowCommbo(self):
|
||||
layout_outter = QVBoxLayout()
|
||||
|
||||
self.vWinGroupBox = QGroupBox('sign up')
|
||||
self.vWinGroupBox.setMinimumSize(300, 200)
|
||||
|
||||
regex = QRegExp("^[A-Za-z0-9]{0,16}$")
|
||||
validator = QRegExpValidator(regex)
|
||||
layout = QHBoxLayout()
|
||||
self.username_le = QLineEdit(self)
|
||||
self.username_label = QLabel('用户名:', self)
|
||||
self.username_le.setPlaceholderText("输入用户名")
|
||||
self.username_le.setValidator(validator)
|
||||
layout.addWidget(self.username_label, 1)
|
||||
layout.addWidget(self.username_le, 4)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
regex = QRegExp("[A-Za-z0-9@.]{0,32}")
|
||||
validator = QRegExpValidator(regex)
|
||||
layout = QHBoxLayout()
|
||||
self.email_le = QLineEdit(self)
|
||||
self.email_label = QLabel('Email:', self)
|
||||
self.email_le.setPlaceholderText("输入Email")
|
||||
self.email_le.setValidator(validator)
|
||||
layout.addWidget(self.email_label, 1)
|
||||
layout.addWidget(self.email_le, 4)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
regex = QRegExp("[A-Za-z0-9.]{0,16}")
|
||||
validator = QRegExpValidator(regex)
|
||||
layout = QHBoxLayout()
|
||||
self.password_le = QLineEdit(self)
|
||||
self.password_label = QLabel('密码:', self)
|
||||
self.password_le.setPlaceholderText("输入密码")
|
||||
self.password_le.setValidator(validator)
|
||||
self.password_le.setEchoMode(QLineEdit.Password)
|
||||
layout.addWidget(self.password_label, 1)
|
||||
layout.addWidget(self.password_le, 4)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
layout = QHBoxLayout()
|
||||
self.password2_le = QLineEdit(self)
|
||||
self.password2_label = QLabel('确认密码:', self)
|
||||
self.password2_le.setPlaceholderText("再次输入密码")
|
||||
self.password2_le.setValidator(validator)
|
||||
self.password2_le.setEchoMode(QLineEdit.Password)
|
||||
layout.addWidget(self.password2_label, 1)
|
||||
layout.addWidget(self.password2_le, 4)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
|
||||
layout = QHBoxLayout()
|
||||
self.invitated_le = QLineEdit(self)
|
||||
self.invitated_label = QLabel('邀请码:', self)
|
||||
self.invitated_le.setPlaceholderText("可选")
|
||||
self.invitated_le.setMaxLength(16)
|
||||
# self.invitated_le.setValidator(validator)
|
||||
layout.addWidget(self.invitated_label, 1)
|
||||
layout.addWidget(self.invitated_le, 4)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
self.tips_label = QLabel('', self)
|
||||
self.sign_up_btn = QPushButton('完成', self)
|
||||
self.sign_up_btn.clicked.connect(self.onclick_sign_up)
|
||||
layout.addWidget(self.tips_label, 1)
|
||||
layout.addWidget(self.sign_up_btn, 1)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
self.vWinGroupBox.setLayout(layout_outter)
|
||||
|
||||
|
||||
def closeEvent(self, event):
|
||||
|
||||
# 调用父类的closeEvent方法,确保窗口能够正常关闭
|
||||
super().closeEvent(event)
|
||||
|
||||
def Reset(self):
|
||||
self.username_le.clear()
|
||||
self.email_le.clear()
|
||||
self.password_le.clear()
|
||||
self.password2_le.clear()
|
||||
self.invitated_le.clear()
|
||||
self.tips_label.clear()
|
||||
|
||||
def setTips(self, tips):
|
||||
self.tips_label.setText(f"<font color='red'>{tips}</font>")
|
||||
|
||||
|
||||
def onclick_sign_up(self):
|
||||
username = self.username_le.text()
|
||||
email = self.email_le.text()
|
||||
password = self.password_le.text()
|
||||
password2 = self.password2_le.text()
|
||||
|
||||
self.setTips("")
|
||||
if len(username) < 5:
|
||||
tips = "用户名至少需要5个字符"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
if len(email) == 0:
|
||||
tips = "请输入Email"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
if not is_valid_email(email):
|
||||
tips = "Email 格式错误"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
if password != password2:
|
||||
tips = "两次密码不一致"
|
||||
self.setTips(tips)
|
||||
return
|
||||
if len(password) < 8:
|
||||
tips = "密码至少需要8个字符"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
invitated = self.invitated_le.text()
|
||||
|
||||
res, ok = maocr.signup(username, email, password, invitated)
|
||||
if not ok:
|
||||
tips = "网络错误"
|
||||
self.setTips(tips)
|
||||
return
|
||||
try:
|
||||
info = json.loads(res)
|
||||
except json.JSONDecodeError:
|
||||
logger.error(f"wrong json format: {res} ")
|
||||
return
|
||||
logger.info(info)
|
||||
if info['message'] != "":
|
||||
self.setTips(info['message'])
|
||||
return
|
||||
QMessageBox.information(self, "消息", "注册成功")
|
||||
self.close()
|
||||
|
||||
|
||||
|
||||
6
core/model_signin.py
Normal file
6
core/model_signin.py
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
signin_flag = False
|
||||
signin_username = None
|
||||
signin_email = None
|
||||
signin_invatation = None
|
||||
signin_token = None
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import setting as c
|
||||
from PyQt5.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout
|
||||
from PySide6.QtGui import QPixmap
|
||||
|
||||
from core.mhdt import download_image
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ def timer_elapse(func):
|
||||
def delete_file(file_path):
|
||||
try:
|
||||
os.remove(file_path)
|
||||
#logger.info(f"文件 {file_path} 删除成功")
|
||||
logger.info(f"文件 {file_path} 删除成功")
|
||||
except OSError as e:
|
||||
logger.info(f"删除文件 {file_path} 失败: {e}")
|
||||
|
||||
|
||||
0
gui/__init__.py
Normal file
0
gui/__init__.py
Normal file
48
gui/gui_coord.py
Normal file
48
gui/gui_coord.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from PySide6.QtCore import Qt, QSize, QUrl
|
||||
from PySide6.QtGui import QIcon, QFont, QColor
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
|
||||
from qfluentwidgets import SingleDirectionScrollArea, SimpleCardWidget, TitleLabel, BodyLabel
|
||||
|
||||
|
||||
class CoordInfoCard(SimpleCardWidget):
|
||||
""" App information card """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.nameLabel = TitleLabel('CoordInfoCard', self)
|
||||
|
||||
self.hBoxLayout = QHBoxLayout(self)
|
||||
|
||||
self.initLayout()
|
||||
|
||||
def initLayout(self):
|
||||
self.hBoxLayout.setSpacing(30)
|
||||
self.hBoxLayout.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout.addWidget(self.nameLabel)
|
||||
|
||||
|
||||
class CoordInterface(SingleDirectionScrollArea):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=None)
|
||||
|
||||
self.view = QWidget(self)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self.view)
|
||||
self.coordCard = CoordInfoCard(self)
|
||||
|
||||
self.setWidget(self.view)
|
||||
self.setWidgetResizable(True)
|
||||
self.setObjectName('CoordInterface')
|
||||
|
||||
self.vBoxLayout.setSpacing(10)
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 15, 0)
|
||||
self.vBoxLayout.addWidget(self.coordCard, 0, Qt.AlignTop)
|
||||
|
||||
self.setStyleSheet("QScrollArea {border: none; background:transparent}")
|
||||
self.view.setStyleSheet('QWidget {background:transparent}')
|
||||
|
||||
def show(self):
|
||||
print("show CoordInterface")
|
||||
|
||||
246
gui/gui_main.py
Normal file
246
gui/gui_main.py
Normal file
@@ -0,0 +1,246 @@
|
||||
from PySide6.QtCore import Qt, QSize, QUrl
|
||||
from PySide6.QtGui import QIcon, QFont, QColor
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
|
||||
|
||||
from qfluentwidgets import SingleDirectionScrollArea, SimpleCardWidget, PushButton, TitleLabel, CaptionLabel, MSFluentWindow, FluentIcon, NavigationItemPosition, LineEdit
|
||||
|
||||
from gui.gui_qa import QAInterface
|
||||
from gui.gui_subscribe import SubscribeInterface
|
||||
from gui.gui_coord import CoordInterface
|
||||
from gui.gui_setting import SettingInterface
|
||||
from gui.gui_usercenter import UsercenterInterface
|
||||
from gui.gui_signup import SFormSignup
|
||||
from gui.gui_signin import SFormSignin
|
||||
from core.util import loadini_user, loadini_setting, clearini_user
|
||||
from core.log import logger
|
||||
import core.model_signin as u
|
||||
import setting as c
|
||||
|
||||
def clearLayout(layout):
|
||||
# 移除旧布局中的所有小部件
|
||||
while layout.count():
|
||||
item = layout.takeAt(0)
|
||||
widget = item.widget()
|
||||
if widget:
|
||||
widget.setParent(None)
|
||||
l = item.layout()
|
||||
if l:
|
||||
clearLayout(l)
|
||||
|
||||
class MainInfoCard(SimpleCardWidget):
|
||||
""" App information card """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.father = parent
|
||||
self.main_lb = TitleLabel('')
|
||||
|
||||
self.signin_btn = PushButton('登录')
|
||||
self.signin_btn.clicked.connect(self.onclick_signin)
|
||||
self.signup_btn = PushButton('注册')
|
||||
self.signup_btn.clicked.connect(self.onclick_signup)
|
||||
self.tips_label = CaptionLabel('')
|
||||
|
||||
self.sf_signup = SFormSignup(self)
|
||||
self.sf_signin = SFormSignin(self)
|
||||
|
||||
self.username_label = CaptionLabel('用户名: ')
|
||||
self.username_le = LineEdit()
|
||||
self.username_le.setReadOnly(True)
|
||||
self.email_label = CaptionLabel('Email: ')
|
||||
self.email_le = LineEdit()
|
||||
self.email_le.setReadOnly(True)
|
||||
self.invitation_label = CaptionLabel('邀请码: ')
|
||||
self.invitation_le = LineEdit()
|
||||
self.invitation_le.setReadOnly(True)
|
||||
self.logout_btn = PushButton('退出当前用户')
|
||||
self.logout_btn.clicked.connect(self.onclick_logout)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self)
|
||||
|
||||
self.hBoxLayout_sign = QHBoxLayout()
|
||||
self.hBoxLayout_tips = QHBoxLayout()
|
||||
|
||||
self.hBoxLayout_username = QHBoxLayout()
|
||||
self.hBoxLayout_email = QHBoxLayout()
|
||||
self.hBoxLayout_invatation = QHBoxLayout()
|
||||
self.hBoxLayout_logout = QHBoxLayout()
|
||||
|
||||
self.initLayout()
|
||||
|
||||
|
||||
def initLayout(self):
|
||||
|
||||
s, u.signin_flag = loadini_user()
|
||||
if u.signin_flag:
|
||||
logger.info(f"load user: {s}")
|
||||
u.signin_username = s[0]
|
||||
u.signin_email = s[1]
|
||||
u.signin_token = s[2]
|
||||
u.signin_invatation = s[3]
|
||||
|
||||
if u.signin_flag:
|
||||
self.username_le.setText(s[0])
|
||||
self.email_le.setText(s[1])
|
||||
self.invitation_le.setText(s[3])
|
||||
|
||||
self.hBoxLayout_username.setSpacing(30)
|
||||
self.hBoxLayout_username.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout_username.addWidget(self.username_label, 1)
|
||||
self.hBoxLayout_username.addWidget(self.username_le, 4)
|
||||
|
||||
self.hBoxLayout_email.setSpacing(30)
|
||||
self.hBoxLayout_email.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout_email.addWidget(self.email_label, 1)
|
||||
self.hBoxLayout_email.addWidget(self.email_le, 4)
|
||||
|
||||
self.hBoxLayout_invatation.setSpacing(30)
|
||||
self.hBoxLayout_invatation.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout_invatation.addWidget(self.invitation_label, 1)
|
||||
self.hBoxLayout_invatation.addWidget(self.invitation_le, 4)
|
||||
|
||||
self.hBoxLayout_logout.setSpacing(30)
|
||||
self.hBoxLayout_logout.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout_logout.addWidget(self.logout_btn)
|
||||
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_username)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_email)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_invatation)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_logout)
|
||||
else:
|
||||
self.hBoxLayout_sign.setSpacing(30)
|
||||
self.hBoxLayout_sign.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout_sign.addWidget(self.signin_btn)
|
||||
self.hBoxLayout_sign.addWidget(self.signup_btn)
|
||||
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_sign, Qt.AlignCenter)
|
||||
|
||||
|
||||
|
||||
def onclick_signup(self):
|
||||
# 计算主窗口中心位置
|
||||
main_window_center = self.LocateCenter()
|
||||
new_window_geometry = self.sf_signup.frameGeometry()
|
||||
new_window_geometry.moveCenter(main_window_center)
|
||||
|
||||
# 移动新窗口到主窗口中心位置并显示
|
||||
self.sf_signup.move(new_window_geometry.topLeft())
|
||||
self.sf_signup.Reset()
|
||||
self.sf_signup.show()
|
||||
|
||||
def onclick_signin(self):
|
||||
# 计算主窗口中心位置
|
||||
main_window_center = self.LocateCenter()
|
||||
new_window_geometry = self.sf_signin.frameGeometry()
|
||||
new_window_geometry.moveCenter(main_window_center)
|
||||
|
||||
# 移动新窗口到主窗口中心位置并显示
|
||||
self.sf_signin.move(new_window_geometry.topLeft())
|
||||
self.sf_signin.Reset()
|
||||
self.sf_signin.show()
|
||||
|
||||
def LocateCenter(self):
|
||||
return self.father.LocateCenter()
|
||||
|
||||
def onclick_logout(self):
|
||||
u.signin_flag = False
|
||||
u.signin_username = None
|
||||
u.signin_email = None
|
||||
u.signin_token = None
|
||||
u.signin_invatation = None
|
||||
|
||||
self.username_le.setText("")
|
||||
self.email_le.setText("")
|
||||
self.invitation_le.setText("")
|
||||
clearini_user()
|
||||
self.ResetSignin()
|
||||
|
||||
|
||||
def ResetSignin(self):
|
||||
clearLayout(self.vBoxLayout)
|
||||
self.initLayout()
|
||||
|
||||
|
||||
class MainInterface(SingleDirectionScrollArea):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=None)
|
||||
self.father = parent
|
||||
self.view = QWidget(self)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self.view)
|
||||
self.mainCard = MainInfoCard(self)
|
||||
|
||||
self.setWidget(self.view)
|
||||
self.setWidgetResizable(True)
|
||||
self.setObjectName('MainInterface')
|
||||
|
||||
self.vBoxLayout.setSpacing(10)
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 15, 0)
|
||||
self.vBoxLayout.addWidget(self.mainCard, 0, Qt.AlignTop)
|
||||
|
||||
self.setStyleSheet("QScrollArea {border: none; background:transparent}")
|
||||
self.view.setStyleSheet('QWidget {background:transparent}')
|
||||
|
||||
def show(self):
|
||||
print("show MainInterface")
|
||||
|
||||
def LocateCenter(self):
|
||||
return self.father.LocateCenter()
|
||||
|
||||
class MainWindow(MSFluentWindow):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.arInterface =[
|
||||
MainInterface(self),
|
||||
QAInterface(self),
|
||||
SubscribeInterface(self),
|
||||
CoordInterface(self),
|
||||
SettingInterface(self),
|
||||
UsercenterInterface(self),
|
||||
]
|
||||
|
||||
self.resize(c.win_width, c.win_height)
|
||||
self.setWindowTitle(c.WINTITLE)
|
||||
self.setWindowIcon(QIcon(c.icon_dir_path))
|
||||
|
||||
res, ok = loadini_setting()
|
||||
if ok:
|
||||
c.URL_QA = f"http://{res[0]}:{res[1]}"
|
||||
logger.info(c.URL_QA)
|
||||
logger.info(c.URL_QA_OCR())
|
||||
self.addSubInterface(self.arInterface[0], FluentIcon.HOME,
|
||||
'主页', selectedIcon=FluentIcon.HOME_FILL)
|
||||
|
||||
self.addSubInterface(self.arInterface[1], FluentIcon.SEARCH,
|
||||
'答题', selectedIcon=FluentIcon.SEARCH)
|
||||
|
||||
self.addSubInterface(self.arInterface[2], FluentIcon.CLOUD_DOWNLOAD,
|
||||
'订阅', selectedIcon=FluentIcon.CLOUD_DOWNLOAD)
|
||||
|
||||
self.addSubInterface(self.arInterface[3], FluentIcon.ACCEPT_MEDIUM,
|
||||
'坐标', selectedIcon=FluentIcon.ACCEPT_MEDIUM)
|
||||
|
||||
self.addSubInterface(self.arInterface[4], FluentIcon.SETTING,
|
||||
'设置', selectedIcon=FluentIcon.SETTING,
|
||||
position=NavigationItemPosition.BOTTOM)
|
||||
|
||||
self.stackedWidget.setStyleSheet('QWidget{background: transparent}')
|
||||
|
||||
self.stackedWidget.currentChanged.connect(self.on_current_changed)
|
||||
|
||||
# 定义槽函数
|
||||
def on_current_changed(self, value):
|
||||
# print(f"Current changed to {value}")
|
||||
self.arInterface[value].show()
|
||||
|
||||
def LocateCenter(self):
|
||||
return self.frameGeometry().center()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
293
gui/gui_qa.py
Normal file
293
gui/gui_qa.py
Normal file
@@ -0,0 +1,293 @@
|
||||
import os
|
||||
import cv2
|
||||
import win32gui
|
||||
import Levenshtein
|
||||
from PIL import Image
|
||||
from PySide6.QtCore import Qt, QSize, QUrl
|
||||
from PySide6.QtGui import QIcon, QFont, QColor
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QListWidgetItem, QTextEdit
|
||||
from qfluentwidgets import SingleDirectionScrollArea, SimpleCardWidget, CaptionLabel, BodyLabel, ListWidget, LineEdit, ComboBox, PushButton
|
||||
|
||||
from core.maocr import maocr
|
||||
from core.log import logger
|
||||
from core.mhdt import dt_nav
|
||||
from core.qalabel import QALabel
|
||||
from core.screenshot import hwnd_title, get_all_hwnd, get_screenshot_image
|
||||
from core.util import time_str, delete_file, loadini_user, loadini_setting
|
||||
import core.model_signin as u
|
||||
import setting as c
|
||||
|
||||
def custom_sort(item, text):
|
||||
return Levenshtein.distance(item[1], text)
|
||||
|
||||
class QaInfoCard(SimpleCardWidget):
|
||||
""" App information card """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.server_annc_lb = BodyLabel(self)
|
||||
self.server_annc_lb.setText(f"{c.TIPS_MAIN_SERVER}")
|
||||
self.server_annc_lb.setOpenExternalLinks(True)
|
||||
self.sponsor_annc_lb = BodyLabel(self)
|
||||
self.sponsor_annc_lb.setText(f"{c.TIPS_MAIN_SPONSOR}")
|
||||
self.sponsor_annc_lb.setOpenExternalLinks(True)
|
||||
|
||||
self.win_nav = ComboBox()
|
||||
self.win_nav_sub = ComboBox()
|
||||
for n in dt_nav:
|
||||
self.win_nav.addItem(n[0])
|
||||
for ns in dt_nav[0][1]:
|
||||
self.win_nav_sub.addItem(ns[0])
|
||||
self.win_nav.currentIndexChanged.connect(self.on_win_nav_changed)
|
||||
|
||||
self.win_combo = ComboBox()
|
||||
self.update_win_combo()
|
||||
self.recognize_btn = PushButton('RE')
|
||||
self.recognize_btn.clicked.connect(lambda checked=False: self.onclick_recogize())
|
||||
|
||||
self.loc_ocr_te = QTextEdit(self)
|
||||
self.loc_ocr_te.setPlaceholderText("auto ocr")
|
||||
self.loc_ocr_te.setReadOnly(True)
|
||||
self.loc_ocr_te.setMaximumHeight(60)
|
||||
|
||||
self.kw_le = LineEdit()
|
||||
self.kw_le.setPlaceholderText("输入关键字")
|
||||
self.kw_le.returnPressed.connect(self.onclick_search)
|
||||
self.search_btn = PushButton('Search')
|
||||
self.search_btn.clicked.connect(lambda checked=False: self.onclick_search())
|
||||
|
||||
self.qa_lw = ListWidget(self)
|
||||
self.qa_lw.setMinimumHeight(350)
|
||||
self.label_qa = [QALabel() for i in range(c.DT_QA_LIST_NUM)]
|
||||
li_height = 80
|
||||
for i in range(c.DT_QA_LIST_NUM):
|
||||
listItem = QListWidgetItem(self.qa_lw)
|
||||
# self.label_qa[i].label_q.setText(f"{i}")
|
||||
self.label_qa[i].setMaximumHeight(li_height)
|
||||
qsize = QSize(400, li_height)
|
||||
listItem.setSizeHint(qsize)
|
||||
self.qa_lw.setItemWidget(listItem, self.label_qa[i])
|
||||
|
||||
self.tips_label = CaptionLabel('123')
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self)
|
||||
self.vBoxLayout_annc= QVBoxLayout()
|
||||
self.hBoxLayout_nav = QHBoxLayout()
|
||||
self.hBoxLayout_re = QHBoxLayout()
|
||||
self.hBoxLayout_ocr = QHBoxLayout()
|
||||
self.hBoxLayout_search = QHBoxLayout()
|
||||
self.vBoxLayout_qa = QVBoxLayout()
|
||||
|
||||
self.initLayout()
|
||||
|
||||
def initLayout(self):
|
||||
|
||||
self.vBoxLayout_annc.setSpacing(10)
|
||||
self.vBoxLayout_annc.setContentsMargins(5, 5, 3, 3)
|
||||
self.vBoxLayout_annc.addWidget(self.server_annc_lb)
|
||||
self.vBoxLayout_annc.addWidget(self.sponsor_annc_lb)
|
||||
|
||||
self.hBoxLayout_nav.setSpacing(10)
|
||||
self.hBoxLayout_nav.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_nav.addWidget(self.win_nav)
|
||||
self.hBoxLayout_nav.addWidget(self.win_nav_sub)
|
||||
|
||||
self.hBoxLayout_re.setSpacing(10)
|
||||
self.hBoxLayout_re.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_re.addWidget(self.win_combo, 4)
|
||||
self.hBoxLayout_re.addWidget(self.recognize_btn, 1)
|
||||
|
||||
self.hBoxLayout_ocr.setSpacing(10)
|
||||
self.hBoxLayout_ocr.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_ocr.addWidget(self.loc_ocr_te)
|
||||
|
||||
self.hBoxLayout_search.setSpacing(10)
|
||||
self.hBoxLayout_search.setContentsMargins(5, 5, 3, 5)
|
||||
self.hBoxLayout_search.addWidget(self.kw_le, 4)
|
||||
self.hBoxLayout_search.addWidget(self.search_btn, 1)
|
||||
|
||||
self.vBoxLayout_qa.setSpacing(10)
|
||||
self.vBoxLayout_qa.setContentsMargins(5, 5, 3, 5)
|
||||
self.vBoxLayout_qa.addWidget(self.qa_lw, 4)
|
||||
self.vBoxLayout_qa.addWidget(self.tips_label, 1)
|
||||
|
||||
self.vBoxLayout.addLayout(self.vBoxLayout_annc)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_nav)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_re)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_ocr)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_search)
|
||||
self.vBoxLayout.addLayout(self.vBoxLayout_qa)
|
||||
|
||||
def on_win_nav_changed(self, index):
|
||||
# logger.info("Selected:", index)
|
||||
self.win_nav_sub.clear()
|
||||
for ns in dt_nav[index][1]:
|
||||
self.win_nav_sub.addItem(ns[0])
|
||||
|
||||
def update_win_combo(self):
|
||||
self.win_combo.clear()
|
||||
hwnd_title.clear()
|
||||
win32gui.EnumWindows(get_all_hwnd, 0)
|
||||
for h, t in hwnd_title.items():
|
||||
# if t.startswith('梦幻西游 ONLINE'):
|
||||
if t.startswith('计算器'):
|
||||
self.win_combo.addItem(str(h)+":"+t)
|
||||
|
||||
def clear_qalist(self) :
|
||||
self.qa_lw.scrollToTop()
|
||||
for i in range(c.DT_QA_LIST_NUM):
|
||||
self.label_qa[i].clear()
|
||||
|
||||
def setTips(self, tips):
|
||||
self.tips_label.setText(f"<font color='red'>{tips}</font>")
|
||||
|
||||
@logger.catch
|
||||
def onclick_search(self, checked=False) :
|
||||
self.setTips("")
|
||||
n = self.win_nav.currentIndex()
|
||||
nsub = self.win_nav_sub.currentIndex()
|
||||
id = dt_nav[n][1][nsub][1]
|
||||
logger.info(f"{n}-{nsub} id: {id}")
|
||||
|
||||
kw = self.kw_le.text()
|
||||
if kw == "":
|
||||
msg = "请输入查询关键字!"
|
||||
logger.warning(msg)
|
||||
self.setTips(msg)
|
||||
return
|
||||
logger.info(f"{n} {nsub} {id} {kw}")
|
||||
qs, ok = maocr.search(id, kw)
|
||||
if not ok:
|
||||
msg = "查找失败"
|
||||
logger.warning(msg)
|
||||
self.setTips(msg)
|
||||
return
|
||||
|
||||
|
||||
self.server_annc_lb.setText(qs[1])
|
||||
self.sponsor_annc_lb.setText(qs[2])
|
||||
self.clear_qalist()
|
||||
if qs[0] == None:
|
||||
msg = "查找失败"
|
||||
self.setTips(msg)
|
||||
logger.warning(msg)
|
||||
return
|
||||
for i, q in enumerate(qs[0]):
|
||||
logger.info(f"{i} {q}")
|
||||
self.label_qa[i].setText(q)
|
||||
|
||||
@logger.catch
|
||||
def onclick_recogize(self):
|
||||
self.setTips("")
|
||||
if not u.signin_flag:
|
||||
msg = "仅登录用户可用"
|
||||
self.setTips(msg)
|
||||
logger.warning(msg)
|
||||
return
|
||||
|
||||
win_text = self.win_combo.currentText()
|
||||
if win_text == "":
|
||||
msg = "没有可用窗口"
|
||||
logger.warning(msg)
|
||||
self.setTips(msg)
|
||||
self.update_win_combo()
|
||||
return
|
||||
h = win_text.split(':')[0]
|
||||
t = win_text.split(':')[1]
|
||||
logger.info(f"{h} {t}")
|
||||
|
||||
if not win32gui.IsWindowEnabled(h):
|
||||
msg = "无效窗口, 请重新选择窗口!"
|
||||
logger.warning(msg)
|
||||
self.setTips(msg)
|
||||
self.update_win_combo()
|
||||
return
|
||||
|
||||
n = self.win_nav.currentIndex()
|
||||
nsub = self.win_nav_sub.currentIndex()
|
||||
id = dt_nav[n][1][nsub][1]
|
||||
ri = dt_nav[n][1][nsub][2]
|
||||
logger.info(f"{n}-{nsub} id: {id} ri: {ri}")
|
||||
|
||||
img_hwnd = get_screenshot_image(int(h))
|
||||
opencv_image = cv2.imread(os.path.join(c.shot_dir_path, r'q3.png'))
|
||||
if opencv_image is None:
|
||||
self.setTips("文件查找失败,避免中文路径")
|
||||
return
|
||||
rgb_image = cv2.cvtColor(opencv_image, cv2.COLOR_BGR2RGB)
|
||||
img_hwnd = Image.fromarray(rgb_image)
|
||||
logger.info(f"shot size {img_hwnd.size}")
|
||||
|
||||
rect = c.shot_rect[ri]
|
||||
crop_box = (rect[0], rect[1], rect[2], rect[3])
|
||||
img_hwnd = img_hwnd.crop(crop_box)
|
||||
|
||||
ts = time_str()
|
||||
file_img = f"{c.shot_dir_path}/{h}_{t}_{ts}.png"
|
||||
img_hwnd.save(file_img, 'PNG')
|
||||
logger.info(f'img_desktop save to -> {os.path.abspath(file_img)}')
|
||||
ok = True
|
||||
re, ok = maocr.recognize(id, file_img, u.signin_token)
|
||||
if not ok:
|
||||
msg = "识别失败"
|
||||
logger.warning(msg)
|
||||
self.setTips(msg)
|
||||
return
|
||||
text = re[0]
|
||||
res = re[1]
|
||||
ocrleftcount = re[2]
|
||||
message = re[3]
|
||||
annc_server = re[4]
|
||||
annc_sponsor = re[5]
|
||||
|
||||
if message != "":
|
||||
self.setTips(message)
|
||||
|
||||
self.server_annc_lb.setText(annc_server)
|
||||
self.sponsor_annc_lb.setText(annc_sponsor)
|
||||
|
||||
# logger.info(text)
|
||||
# logger.info(res)
|
||||
self.recognize_btn.setText(f"RE({ocrleftcount})")
|
||||
delete_file(file_img)
|
||||
if text == "":
|
||||
self.setTips("识别失败")
|
||||
return
|
||||
|
||||
if ok:
|
||||
self.loc_ocr_te.setText(text)
|
||||
sorted_list = sorted(res, key=lambda x: custom_sort(x['Q'], text))
|
||||
self.clear_qalist()
|
||||
for i, q in enumerate(sorted_list):
|
||||
if i > 4:
|
||||
break
|
||||
logger.info(f"{i}: {q}")
|
||||
self.label_qa[i].setText(q)
|
||||
|
||||
|
||||
class QAInterface(SingleDirectionScrollArea):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=None)
|
||||
|
||||
self.view = QWidget(self)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self.view)
|
||||
self.qaCard = QaInfoCard(self)
|
||||
|
||||
self.setWidget(self.view)
|
||||
self.setWidgetResizable(True)
|
||||
self.setObjectName('QAInterface')
|
||||
|
||||
self.vBoxLayout.setSpacing(10)
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 5, 0)
|
||||
self.vBoxLayout.addWidget(self.qaCard, 0, Qt.AlignTop)
|
||||
|
||||
self.setStyleSheet("QScrollArea {border: none; background:transparent}")
|
||||
self.view.setStyleSheet('QWidget {background:transparent}')
|
||||
|
||||
def show(self):
|
||||
print("show QAInterface")
|
||||
|
||||
|
||||
47
gui/gui_setting.py
Normal file
47
gui/gui_setting.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from PySide6.QtCore import Qt, QSize, QUrl
|
||||
from PySide6.QtGui import QIcon, QFont, QColor
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
|
||||
from qfluentwidgets import SingleDirectionScrollArea, SimpleCardWidget, TitleLabel, BodyLabel
|
||||
|
||||
|
||||
class SettingInfoCard(SimpleCardWidget):
|
||||
""" App information card """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.nameLabel = TitleLabel('SettingInfoCard', self)
|
||||
|
||||
self.hBoxLayout = QHBoxLayout(self)
|
||||
|
||||
self.initLayout()
|
||||
|
||||
def initLayout(self):
|
||||
self.hBoxLayout.setSpacing(30)
|
||||
self.hBoxLayout.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout.addWidget(self.nameLabel)
|
||||
|
||||
|
||||
class SettingInterface(SingleDirectionScrollArea):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=None)
|
||||
|
||||
self.view = QWidget(self)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self.view)
|
||||
self.settingCard = SettingInfoCard(self)
|
||||
|
||||
self.setWidget(self.view)
|
||||
self.setWidgetResizable(True)
|
||||
self.setObjectName('SettingInterface')
|
||||
|
||||
self.vBoxLayout.setSpacing(10)
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 15, 0)
|
||||
self.vBoxLayout.addWidget(self.settingCard, 0, Qt.AlignTop)
|
||||
|
||||
self.setStyleSheet("QScrollArea {border: none; background:transparent}")
|
||||
self.view.setStyleSheet('QWidget {background:transparent}')
|
||||
|
||||
def show(self):
|
||||
print("show SettingInterface")
|
||||
@@ -1,9 +1,10 @@
|
||||
import json
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtCore import Qt, QRegExp
|
||||
from PyQt5.QtWidgets import (QWidget, QGroupBox, QPushButton, QHBoxLayout, QLineEdit, QTextEdit, QLabel,
|
||||
QVBoxLayout, QGridLayout, QComboBox, QListWidget, QMessageBox, QListWidgetItem)
|
||||
from PyQt5.QtGui import QIcon, QRegExpValidator
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtCore import Qt, QRegularExpression
|
||||
from PySide6.QtWidgets import (QWidget, QGroupBox, QHBoxLayout,
|
||||
QVBoxLayout, QGridLayout)
|
||||
from qfluentwidgets import CaptionLabel, LineEdit, PushButton
|
||||
from PySide6.QtGui import QIcon, QRegularExpressionValidator
|
||||
from core.maocr import maocr
|
||||
from core.util import is_valid_email, dumpini_user
|
||||
import setting as c
|
||||
@@ -20,7 +21,7 @@ class SFormSignin(QWidget):
|
||||
self.initUI()
|
||||
|
||||
# 计算并设置新窗口的位置
|
||||
self.setGeometry(0, 0, 300, 130)
|
||||
self.setGeometry(0, 0, 300, 150)
|
||||
self.move(father.frameGeometry().topLeft() + father.rect().center() - self.rect().center())
|
||||
|
||||
# 绘制界面
|
||||
@@ -38,45 +39,60 @@ class SFormSignin(QWidget):
|
||||
self.setLayout(mainLayout)
|
||||
|
||||
def CreateWindowCommbo(self):
|
||||
layout_outter = QVBoxLayout()
|
||||
|
||||
|
||||
self.vWinGroupBox = QGroupBox('sign in')
|
||||
self.vWinGroupBox.setMinimumSize(300, 130)
|
||||
self.vWinGroupBox.setMinimumSize(300, 220)
|
||||
|
||||
|
||||
regex = QRegExp("[A-Za-z0-9@.]{0,32}")
|
||||
validator = QRegExpValidator(regex)
|
||||
layout = QHBoxLayout()
|
||||
self.email_le = QLineEdit(self)
|
||||
self.email_label = QLabel('Email:', self)
|
||||
regex = QRegularExpression("[A-Za-z0-9@.]{0,32}")
|
||||
validator = QRegularExpressionValidator(regex)
|
||||
self.email_le = LineEdit()
|
||||
self.email_label = CaptionLabel('Email:')
|
||||
self.email_le.setPlaceholderText("输入Email")
|
||||
self.email_le.setValidator(validator)
|
||||
layout.addWidget(self.email_label, 1)
|
||||
layout.addWidget(self.email_le, 4)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
regex = QRegExp("[A-Za-z0-9.]{0,16}")
|
||||
validator = QRegExpValidator(regex)
|
||||
layout = QHBoxLayout()
|
||||
self.password_le = QLineEdit(self)
|
||||
self.password_label = QLabel('密码:', self)
|
||||
regex = QRegularExpression("[A-Za-z0-9.]{0,16}")
|
||||
validator = QRegularExpressionValidator(regex)
|
||||
self.password_le = LineEdit()
|
||||
self.password_label = CaptionLabel('密码:')
|
||||
self.password_le.setPlaceholderText("输入密码")
|
||||
self.password_le.setValidator(validator)
|
||||
self.password_le.setEchoMode(QLineEdit.Password)
|
||||
layout.addWidget(self.password_label, 1)
|
||||
layout.addWidget(self.password_le, 4)
|
||||
layout_outter.addLayout(layout)
|
||||
self.password_le.setEchoMode(LineEdit.Password)
|
||||
|
||||
|
||||
layout = QVBoxLayout()
|
||||
self.tips_label = QLabel('', self)
|
||||
self.sign_in_btn = QPushButton('登录', self)
|
||||
self.tips_label = CaptionLabel('')
|
||||
self.sign_in_btn = PushButton('登录')
|
||||
self.sign_in_btn.clicked.connect(self.onclick_sign_in)
|
||||
layout.addWidget(self.tips_label, 1)
|
||||
layout.addWidget(self.sign_in_btn, 1)
|
||||
layout_outter.addLayout(layout)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self)
|
||||
|
||||
self.hBoxLayout_email = QHBoxLayout()
|
||||
self.hBoxLayout_password = QHBoxLayout()
|
||||
self.vBoxLayout_signin = QVBoxLayout()
|
||||
|
||||
self.vWinGroupBox.setLayout(layout_outter)
|
||||
self.initLayout()
|
||||
|
||||
self.vWinGroupBox.setLayout(self.vBoxLayout)
|
||||
|
||||
def initLayout(self):
|
||||
self.hBoxLayout_email.setSpacing(10)
|
||||
self.hBoxLayout_email.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_email.addWidget(self.email_label, 1)
|
||||
self.hBoxLayout_email.addWidget(self.email_le, 4)
|
||||
|
||||
self.hBoxLayout_password.setSpacing(10)
|
||||
self.hBoxLayout_password.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_password.addWidget(self.password_label, 1)
|
||||
self.hBoxLayout_password.addWidget(self.password_le, 4)
|
||||
|
||||
self.vBoxLayout_signin.setSpacing(10)
|
||||
self.vBoxLayout_signin.setContentsMargins(5, 5, 3, 3)
|
||||
self.vBoxLayout_signin.addWidget(self.sign_in_btn)
|
||||
self.vBoxLayout_signin.addWidget(self.tips_label)
|
||||
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_email)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_password)
|
||||
self.vBoxLayout.addLayout(self.vBoxLayout_signin)
|
||||
|
||||
|
||||
def closeEvent(self, event):
|
||||
@@ -125,5 +141,5 @@ class SFormSignin(QWidget):
|
||||
return
|
||||
# QMessageBox.information(self, "消息", "登录成功")
|
||||
dumpini_user(info['username'], info['email'], info['token'], info['invitation'])
|
||||
self.father.ResetSignin(True)
|
||||
self.father.ResetSignin()
|
||||
self.close()
|
||||
205
gui/gui_signup.py
Normal file
205
gui/gui_signup.py
Normal file
@@ -0,0 +1,205 @@
|
||||
import json
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtCore import Qt, QRegularExpression
|
||||
from PySide6.QtWidgets import (QWidget, QGroupBox, QHBoxLayout, QMessageBox,
|
||||
QVBoxLayout, QGridLayout)
|
||||
from PySide6.QtGui import QIcon, QRegularExpressionValidator
|
||||
|
||||
from qfluentwidgets import CaptionLabel, LineEdit, PushButton
|
||||
from core.maocr import maocr
|
||||
from core.util import is_valid_email
|
||||
from core.log import logger
|
||||
import setting as c
|
||||
|
||||
class SFormSignup(QWidget):
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__()
|
||||
|
||||
self.setWindowIcon(QIcon(c.icon_dir_path))
|
||||
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
|
||||
|
||||
self.initUI()
|
||||
|
||||
# 计算并设置新窗口的位置
|
||||
self.setGeometry(0, 0, 300, 230)
|
||||
self.move(parent.frameGeometry().topLeft() + parent.rect().center() - self.rect().center())
|
||||
|
||||
# 绘制界面
|
||||
def initUI(self):
|
||||
|
||||
self.CreateWindowCommbo()
|
||||
|
||||
gridLayout = QGridLayout()
|
||||
gridLayout.addWidget(self.vWinGroupBox, 0, 0, QtCore.Qt.AlignLeft)
|
||||
|
||||
# 调用方法绘制界面
|
||||
self.setWindowTitle(c.WINTITLE)
|
||||
mainLayout = QHBoxLayout()
|
||||
mainLayout.addLayout(gridLayout)
|
||||
self.setLayout(mainLayout)
|
||||
|
||||
def CreateWindowCommbo(self):
|
||||
|
||||
self.vWinGroupBox = QGroupBox('sign up')
|
||||
self.vWinGroupBox.setMinimumSize(300, 340)
|
||||
|
||||
regex = QRegularExpression("^[A-Za-z0-9]{0,16}$")
|
||||
validator = QRegularExpressionValidator(regex)
|
||||
self.username_le = LineEdit(self)
|
||||
self.username_label = CaptionLabel('用户名:', self)
|
||||
self.username_le.setPlaceholderText("输入用户名")
|
||||
self.username_le.setValidator(validator)
|
||||
|
||||
regex = QRegularExpression("[A-Za-z0-9@.]{0,32}")
|
||||
validator = QRegularExpressionValidator(regex)
|
||||
self.email_le = LineEdit(self)
|
||||
self.email_label = CaptionLabel('Email:', self)
|
||||
self.email_le.setPlaceholderText("输入Email")
|
||||
self.email_le.setValidator(validator)
|
||||
|
||||
regex = QRegularExpression("[A-Za-z0-9.]{0,16}")
|
||||
validator = QRegularExpressionValidator(regex)
|
||||
self.password_le = LineEdit(self)
|
||||
self.password_label = CaptionLabel('密码:', self)
|
||||
self.password_le.setPlaceholderText("输入密码")
|
||||
self.password_le.setValidator(validator)
|
||||
self.password_le.setEchoMode(LineEdit.Password)
|
||||
|
||||
self.password2_le = LineEdit(self)
|
||||
self.password2_label = CaptionLabel('确认密码:', self)
|
||||
self.password2_le.setPlaceholderText("再次输入密码")
|
||||
self.password2_le.setValidator(validator)
|
||||
self.password2_le.setEchoMode(LineEdit.Password)
|
||||
|
||||
self.invitated_le = LineEdit(self)
|
||||
self.invitated_label = CaptionLabel('邀请码:', self)
|
||||
self.invitated_le.setPlaceholderText("可选")
|
||||
self.invitated_le.setMaxLength(16)
|
||||
|
||||
self.tips_label = CaptionLabel('', self)
|
||||
self.sign_up_btn = PushButton('完成', self)
|
||||
self.sign_up_btn.clicked.connect(self.onclick_sign_up)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self)
|
||||
|
||||
self.hBoxLayout_username = QHBoxLayout()
|
||||
self.hBoxLayout_email = QHBoxLayout()
|
||||
self.hBoxLayout_password = QHBoxLayout()
|
||||
self.hBoxLayout_password2 = QHBoxLayout()
|
||||
self.hBoxLayout_invatation = QHBoxLayout()
|
||||
self.vBoxLayout_signup = QVBoxLayout()
|
||||
|
||||
self.initLayout()
|
||||
|
||||
self.vWinGroupBox.setLayout(self.vBoxLayout)
|
||||
|
||||
def initLayout(self):
|
||||
|
||||
self.hBoxLayout_username.setSpacing(10)
|
||||
self.hBoxLayout_username.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_username.addWidget(self.username_label, 1)
|
||||
self.hBoxLayout_username.addWidget(self.username_le, 4)
|
||||
|
||||
self.hBoxLayout_email.setSpacing(10)
|
||||
self.hBoxLayout_email.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_email.addWidget(self.email_label, 1)
|
||||
self.hBoxLayout_email.addWidget(self.email_le, 4)
|
||||
|
||||
self.hBoxLayout_password.setSpacing(10)
|
||||
self.hBoxLayout_password.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_password.addWidget(self.password_label, 1)
|
||||
self.hBoxLayout_password.addWidget(self.password_le, 4)
|
||||
|
||||
self.hBoxLayout_password2.setSpacing(10)
|
||||
self.hBoxLayout_password2.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_password2.addWidget(self.password2_label, 1)
|
||||
self.hBoxLayout_password2.addWidget(self.password2_le, 4)
|
||||
|
||||
self.hBoxLayout_invatation.setSpacing(10)
|
||||
self.hBoxLayout_invatation.setContentsMargins(5, 5, 3, 3)
|
||||
self.hBoxLayout_invatation.addWidget(self.invitated_label, 1)
|
||||
self.hBoxLayout_invatation.addWidget(self.invitated_le, 4)
|
||||
|
||||
self.vBoxLayout_signup.setSpacing(10)
|
||||
self.vBoxLayout_signup.setContentsMargins(5, 5, 3, 3)
|
||||
self.vBoxLayout_signup.addWidget(self.sign_up_btn)
|
||||
self.vBoxLayout_signup.addWidget(self.tips_label)
|
||||
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_username)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_email)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_password)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_password2)
|
||||
self.vBoxLayout.addLayout(self.hBoxLayout_invatation)
|
||||
self.vBoxLayout.addLayout(self.vBoxLayout_signup)
|
||||
|
||||
|
||||
def closeEvent(self, event):
|
||||
|
||||
# 调用父类的closeEvent方法,确保窗口能够正常关闭
|
||||
super().closeEvent(event)
|
||||
|
||||
def Reset(self):
|
||||
self.username_le.clear()
|
||||
self.email_le.clear()
|
||||
self.password_le.clear()
|
||||
self.password2_le.clear()
|
||||
self.invitated_le.clear()
|
||||
self.tips_label.clear()
|
||||
|
||||
def setTips(self, tips):
|
||||
self.tips_label.setText(f"<font color='red'>{tips}</font>")
|
||||
|
||||
|
||||
def onclick_sign_up(self):
|
||||
username = self.username_le.text()
|
||||
email = self.email_le.text()
|
||||
password = self.password_le.text()
|
||||
password2 = self.password2_le.text()
|
||||
|
||||
self.setTips("")
|
||||
if len(username) < 5:
|
||||
tips = "用户名至少需要5个字符"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
if len(email) == 0:
|
||||
tips = "请输入Email"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
if not is_valid_email(email):
|
||||
tips = "Email 格式错误"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
if password != password2:
|
||||
tips = "两次密码不一致"
|
||||
self.setTips(tips)
|
||||
return
|
||||
if len(password) < 8:
|
||||
tips = "密码至少需要8个字符"
|
||||
self.setTips(tips)
|
||||
return
|
||||
|
||||
invitated = self.invitated_le.text()
|
||||
|
||||
res, ok = maocr.signup(username, email, password, invitated)
|
||||
if not ok:
|
||||
tips = "网络错误"
|
||||
self.setTips(tips)
|
||||
return
|
||||
try:
|
||||
info = json.loads(res)
|
||||
except json.JSONDecodeError:
|
||||
logger.error(f"wrong json format: {res} ")
|
||||
return
|
||||
logger.info(info)
|
||||
if info['message'] != "":
|
||||
self.setTips(info['message'])
|
||||
return
|
||||
QMessageBox.information(self, "消息", "注册成功")
|
||||
self.close()
|
||||
|
||||
|
||||
|
||||
47
gui/gui_subscribe.py
Normal file
47
gui/gui_subscribe.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from PySide6.QtCore import Qt, QSize, QUrl
|
||||
from PySide6.QtGui import QIcon, QFont, QColor
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
|
||||
from qfluentwidgets import SingleDirectionScrollArea, SimpleCardWidget, TitleLabel, BodyLabel
|
||||
|
||||
|
||||
class SubscribeInfoCard(SimpleCardWidget):
|
||||
""" App information card """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.nameLabel = TitleLabel('SubscribeInfoCard', self)
|
||||
|
||||
self.hBoxLayout = QHBoxLayout(self)
|
||||
|
||||
self.initLayout()
|
||||
|
||||
def initLayout(self):
|
||||
self.hBoxLayout.setSpacing(30)
|
||||
self.hBoxLayout.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout.addWidget(self.nameLabel)
|
||||
|
||||
|
||||
class SubscribeInterface(SingleDirectionScrollArea):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=None)
|
||||
|
||||
self.view = QWidget(self)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self.view)
|
||||
self.subscribeCard = SubscribeInfoCard(self)
|
||||
|
||||
self.setWidget(self.view)
|
||||
self.setWidgetResizable(True)
|
||||
self.setObjectName('SubscribeInterface')
|
||||
|
||||
self.vBoxLayout.setSpacing(10)
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 15, 0)
|
||||
self.vBoxLayout.addWidget(self.subscribeCard, 0, Qt.AlignTop)
|
||||
|
||||
self.setStyleSheet("QScrollArea {border: none; background:transparent}")
|
||||
self.view.setStyleSheet('QWidget {background:transparent}')
|
||||
|
||||
def show(self):
|
||||
print("show SubscribeInterface")
|
||||
44
gui/gui_usercenter.py
Normal file
44
gui/gui_usercenter.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from PySide6.QtCore import Qt, QSize, QUrl
|
||||
from PySide6.QtGui import QIcon, QFont, QColor
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
|
||||
from qfluentwidgets import SingleDirectionScrollArea, SimpleCardWidget, TitleLabel, BodyLabel
|
||||
|
||||
|
||||
class UsercenterInfoCard(SimpleCardWidget):
|
||||
""" App information card """
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.nameLabel = TitleLabel('UsercenterInfoCard', self)
|
||||
|
||||
self.hBoxLayout = QHBoxLayout(self)
|
||||
|
||||
self.initLayout()
|
||||
|
||||
def initLayout(self):
|
||||
self.hBoxLayout.setSpacing(30)
|
||||
self.hBoxLayout.setContentsMargins(34, 24, 24, 24)
|
||||
self.hBoxLayout.addWidget(self.nameLabel)
|
||||
|
||||
|
||||
class UsercenterInterface(SingleDirectionScrollArea):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=None)
|
||||
|
||||
self.view = QWidget(self)
|
||||
|
||||
self.vBoxLayout = QVBoxLayout(self.view)
|
||||
self.usercenterCard = UsercenterInfoCard(self)
|
||||
|
||||
self.setWidget(self.view)
|
||||
self.setWidgetResizable(True)
|
||||
self.setObjectName('UsercenterInterface')
|
||||
|
||||
self.vBoxLayout.setSpacing(10)
|
||||
self.vBoxLayout.setContentsMargins(0, 0, 15, 0)
|
||||
self.vBoxLayout.addWidget(self.usercenterCard, 0, Qt.AlignTop)
|
||||
|
||||
self.setStyleSheet("QScrollArea {border: none; background:transparent}")
|
||||
self.view.setStyleSheet('QWidget {background:transparent}')
|
||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
28
run_gui.py
28
run_gui.py
@@ -1,25 +1,17 @@
|
||||
import sys
|
||||
from core.sform import SForm
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtCore import Qt
|
||||
from core.util import dir_check
|
||||
from core.log import logger
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from gui.gui_main import MainWindow
|
||||
import setting as c
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# 程序启动
|
||||
if __name__ == '__main__':
|
||||
logger.info("gui start")
|
||||
dir_check()
|
||||
#app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) # 美化界面
|
||||
sf = SForm()
|
||||
sf.resize(c.win_width, c.win_height)
|
||||
sf.setWindowFlags(sf.windowFlags() | Qt.WindowStaysOnTopHint)
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
screen = app.primaryScreen().size()
|
||||
x = screen.width() - sf.width() # 窗口右对齐
|
||||
x = screen.width() - c.win_width # 窗口右对齐
|
||||
y = 100 # 窗口顶对齐
|
||||
sf.move(x, y)
|
||||
sf.show()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
w = MainWindow()
|
||||
w.move(x, y)
|
||||
w.show()
|
||||
app.exec()
|
||||
@@ -15,12 +15,12 @@ def resource_path(relative_path):
|
||||
|
||||
screen_width, screen_height = pyautogui.size()
|
||||
|
||||
win_width = 480
|
||||
win_height = 700
|
||||
win_width = 530
|
||||
win_height = 750
|
||||
|
||||
# version
|
||||
VERSION = "0.0.2"
|
||||
WINTITLE = f"mhxy QA {VERSION}"
|
||||
WINTITLE = f"mhbby {VERSION}"
|
||||
|
||||
# 截图存档目录
|
||||
appdata_path = os.path.join(os.getenv('APPDATA'), r'mhxyQA')
|
||||
|
||||
Reference in New Issue
Block a user