优化了部分代码
This commit is contained in:
parent
555ca73bba
commit
ed5b11fbc8
@ -5,7 +5,7 @@ from src.core.util import resource_path
|
||||
|
||||
# logger.remove()
|
||||
# logger.add(sys.stderr, level="INFO")
|
||||
logger.add("{time:YYYY-MM}/{time:YYYY-MM-DD}.log", rotation="00:00", level="DEBUG", retention='1 day',
|
||||
logger.add("/{time:YYYY-MM}/{time:YYYY-MM-DD}.log", rotation="00:00", level="DEBUG", retention='1 day',
|
||||
encoding='utf-8')
|
||||
|
||||
QtCore.QDir.addSearchPath('icons', resource_path('ui/icon/'))
|
||||
|
@ -1,4 +1,4 @@
|
||||
import qdarkstyle
|
||||
import qdarkstyle, sys
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
|
||||
from src.ui.app import Application
|
||||
@ -9,4 +9,4 @@ if __name__ == '__main__':
|
||||
app.setStyleSheet(qdarkstyle.load_stylesheet(qt_api='pyqt6'))
|
||||
main_win = Application()
|
||||
main_win.show()
|
||||
app.exec()
|
||||
sys.exit(app.exec())
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import time
|
||||
import schedule
|
||||
from loguru import logger
|
||||
@ -9,45 +10,49 @@ from src.entity.pay_record import get_pay_failed_by_user
|
||||
from src.entity.user import get_user_by_username_and_password
|
||||
from src.entity.visual_list import text_count_by_user
|
||||
|
||||
# 日志配置
|
||||
logger.add("debug.log", format="{time} {level} {message}", level="DEBUG", rotation="1 week", compression="zip")
|
||||
|
||||
def job_count(username, password):
|
||||
|
||||
def execute_task(task_func, username, password):
|
||||
try:
|
||||
logger.info(f'Running job_count for username: {username}')
|
||||
logger.info(f'Running {task_func.__name__} for username: {username}')
|
||||
user = get_user_by_username_and_password(username, password)
|
||||
send_message(user.bot_token, user.count_group_id, text_count_by_user(user, get_curr_day()))
|
||||
logger.info(f'Finished job_count for username: {username}')
|
||||
except Exception as e:
|
||||
logger.error(f'Error running job_count for username: {username}, Error: {e}')
|
||||
message = task_func(user, get_curr_day()) # Assuming all tasks take a 'user' and 'date'
|
||||
send_message(user.bot_token, user.count_group_id, message)
|
||||
logger.info(f'Finished {task_func.__name__} for username: {username}')
|
||||
except Exception as e: # Consider catching more specific exceptions if possible
|
||||
logger.error(f'Error running {task_func.__name__} for username: {username}, Error: {e}')
|
||||
logger.exception(e) # This will log the full stack trace
|
||||
|
||||
|
||||
def query_failed_deposit(username, password):
|
||||
try:
|
||||
logger.info(f'Running query_failed_deposit for username: {username}')
|
||||
user = get_user_by_username_and_password(username, password)
|
||||
send_message(user.bot_token, user.count_group_id, get_pay_failed_by_user(user, get_curr_day()))
|
||||
logger.info(f'Finished query_failed_deposit for username: {username}')
|
||||
except Exception as e:
|
||||
logger.error(f'Error running query_failed_deposit for username: {username}, Error: {e}')
|
||||
def job_count(user, date):
|
||||
return text_count_by_user(user, date)
|
||||
|
||||
|
||||
def query_net_win(username, password):
|
||||
try:
|
||||
logger.info(f'Running query_net_win for username: {username}')
|
||||
user = get_user_by_username_and_password(username, password)
|
||||
send_message(user.bot_token, user.count_group_id, get_net_win_by_user(user, date=get_curr_day()))
|
||||
logger.info(f'Finished query_net_win for username: {username}')
|
||||
except Exception as e:
|
||||
logger.error(f'Error running query_net_win for username: {username}, Error: {e}')
|
||||
def query_failed_deposit(user, date):
|
||||
return get_pay_failed_by_user(user, date)
|
||||
|
||||
|
||||
def query_net_win(user, date):
|
||||
return get_net_win_by_user(user, date)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger.info('Starting scheduled tasks')
|
||||
|
||||
# Get credentials from environment variables
|
||||
username = os.getenv('MY_APP_USERNAME', 'default_username')
|
||||
password = os.getenv('MY_APP_PASSWORD', 'default_password')
|
||||
|
||||
times = ['10:50', '14:40', '17:40', '20:40', '21:40', '23:59']
|
||||
|
||||
for time_str in times:
|
||||
schedule.every().day.at(time_str).do(job_count, 'zayac', '123456')
|
||||
schedule.every().day.at(time_str).do(query_net_win, 'zayac', '123456')
|
||||
schedule.every().day.at('23:59').do(query_failed_deposit, 'zayac', '123456')
|
||||
schedule.every().day.at(time_str).do(execute_task, job_count, username, password)
|
||||
schedule.every().day.at(time_str).do(execute_task, query_net_win, username, password)
|
||||
|
||||
schedule.every().day.at('23:59').do(execute_task, query_failed_deposit, username, password)
|
||||
|
||||
while True:
|
||||
schedule.run_pending()
|
||||
time.sleep(1)
|
||||
# logger.info('Running scheduled tasks') # This line is commented out to reduce log verbosity
|
||||
time.sleep(10)
|
@ -46,7 +46,6 @@ def query_banner_info(account: Account):
|
||||
last_banner_info = get_banner_info(account)
|
||||
while True:
|
||||
try:
|
||||
date = get_curr_day()
|
||||
banner_info = get_banner_info(account)
|
||||
logger.debug(f'{account.name}请求成功:{banner_info}')
|
||||
logger.info(
|
||||
|
@ -1,7 +1,5 @@
|
||||
import asyncio
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
from src import logger
|
||||
|
208
src/ui/app.py
208
src/ui/app.py
@ -1,6 +1,5 @@
|
||||
import configparser
|
||||
import os
|
||||
import time
|
||||
from enum import Enum
|
||||
|
||||
from loguru import logger
|
||||
from PyQt6.QtCore import QDate, QDateTime, Qt, QThreadPool, QTime, QTimer
|
||||
@ -11,6 +10,7 @@ from PyQt6.QtWidgets import (QApplication, QCheckBox, QDateEdit, QHBoxLayout,
|
||||
QTableWidget, QTableWidgetItem, QTabWidget,
|
||||
QTextEdit, QVBoxLayout, QWidget)
|
||||
|
||||
from src.ui.config import ConfigManager
|
||||
from src.core.message_client import send_message
|
||||
from src.core.util import convert_data, resource_path
|
||||
from src.entity.member import get_today_new_member_list
|
||||
@ -24,6 +24,15 @@ from src.ui.title_bar import CustomTitleBar
|
||||
class Application(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.config_manager = ConfigManager()
|
||||
self.thread_pool = QThreadPool()
|
||||
self.report_timer = None
|
||||
self.date_update_timer = None
|
||||
self.username = None
|
||||
self.password = None
|
||||
self.minimum = False
|
||||
self.customTitleBar = None
|
||||
self.tray_icon = None
|
||||
self.tables = {}
|
||||
self.is_dragging = False
|
||||
self.drag_position = None
|
||||
@ -37,10 +46,7 @@ class Application(QMainWindow):
|
||||
# 1. 加载配置文件
|
||||
self.load_config()
|
||||
|
||||
# 2. 设置线程池
|
||||
self.thread_pool = QThreadPool()
|
||||
|
||||
# 3. 设置 UI
|
||||
# 2. 设置 UI
|
||||
self.setup_ui()
|
||||
|
||||
# 4. 初始化系统托盘图标
|
||||
@ -49,13 +55,9 @@ class Application(QMainWindow):
|
||||
# 5. 初始化表格数据
|
||||
self.init_table_data()
|
||||
|
||||
# 6. 设置日期更新和报告定时器
|
||||
self.setup_date_update_timer()
|
||||
self.setup_report_timer()
|
||||
# 7. 全局信号处理,更新用户信息
|
||||
global_signals.user_data_updated.connect(self.refresh_user_data)
|
||||
# 8. 消息通知对象
|
||||
self.chat_id = self.user.group_id if self.user.group_id else self.user.chat_id
|
||||
self.setup_timers()
|
||||
|
||||
self.connect_signals()
|
||||
|
||||
def setup_ui(self):
|
||||
self.apply_stylesheet()
|
||||
@ -63,6 +65,14 @@ class Application(QMainWindow):
|
||||
self.create_central_widget()
|
||||
self.setup_layouts()
|
||||
|
||||
def setup_timers(self):
|
||||
self.setup_date_update_timer()
|
||||
self.setup_report_timer()
|
||||
|
||||
def connect_signals(self):
|
||||
self.tray_icon.activated.connect(self.tray_icon_clicked)
|
||||
global_signals.user_data_updated.connect(self.refresh_user_data)
|
||||
|
||||
def set_window_properties(self):
|
||||
self.resize(600, 400)
|
||||
self.setWindowTitle("zayac的小工具")
|
||||
@ -82,40 +92,20 @@ class Application(QMainWindow):
|
||||
self.setMenuWidget(self.customTitleBar)
|
||||
|
||||
def init_tray_icon(self):
|
||||
self.tray_icon = QSystemTrayIcon(QIcon("icons:icon.png"), self)
|
||||
tray_menu = QMenu()
|
||||
exit_action = QAction("退出", self)
|
||||
exit_action.triggered.connect(self.exit_application)
|
||||
tray_menu.addAction(exit_action)
|
||||
self.tray_icon.setContextMenu(tray_menu)
|
||||
self.tray_icon.activated.connect(self.tray_icon_clicked)
|
||||
self.tray_icon = SystemTrayIcon(QIcon("icons:icon.png"), self) # 替换为正确的图标路径
|
||||
self.tray_icon.show()
|
||||
|
||||
def init_data_and_timers(self):
|
||||
# 初始化数据
|
||||
self.init_table_data()
|
||||
|
||||
# 设置定时器
|
||||
self.setup_date_update_timer()
|
||||
self.setup_report_timer()
|
||||
|
||||
def load_config(self):
|
||||
config = configparser.ConfigParser()
|
||||
config_file = 'config.ini'
|
||||
|
||||
if not os.path.exists(config_file):
|
||||
QMessageBox.warning(None, "警告", "用户信息获取失败!")
|
||||
# 使用
|
||||
try:
|
||||
self.username = self.config_manager.get('Credentials', 'username')
|
||||
self.password = self.config_manager.get('Credentials', 'password')
|
||||
self.minimum = self.config_manager.get('Minimum', 'minimum')
|
||||
self.user = get_user_by_username_and_password(self.username, self.password)
|
||||
except FileNotFoundError as e:
|
||||
QMessageBox.warning(None, "警告", "配置文件信息加载失败!请检查文件是否存在")
|
||||
return None, None
|
||||
|
||||
config.read(config_file)
|
||||
username = config.get('Credentials', 'username')
|
||||
password = config.get('Credentials', 'password')
|
||||
minimum = config.get('Minimum', 'minimum')
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.user = get_user_by_username_and_password(username, password)
|
||||
self.minimum = minimum
|
||||
|
||||
def init_table_data(self):
|
||||
# 初始化表格数据
|
||||
data = self.query_initial_data(self.user)
|
||||
@ -124,14 +114,13 @@ class Application(QMainWindow):
|
||||
self.update_table(row.agentCode, [time_str, row.registerMembers, row.firstDepositNum, row.netWinLose,
|
||||
row.effectiveNew, row.activeMembers])
|
||||
|
||||
def query_initial_data(self, account):
|
||||
# 实际实现应该根据您的业务逻辑来定义
|
||||
return ReportTask.query_data_for_user(account)
|
||||
def query_initial_data(self, user):
|
||||
return ReportTask.get_banner_info_by_user(user)
|
||||
|
||||
def setup_report_timer(self):
|
||||
self.report_timer = QTimer(self)
|
||||
self.report_timer.timeout.connect(self.update_reports)
|
||||
self.report_timer.start(60000) # 每60秒触发一次
|
||||
self.report_timer.start(60000)
|
||||
|
||||
def update_reports(self):
|
||||
for account in self.user.accounts:
|
||||
@ -194,13 +183,12 @@ class Application(QMainWindow):
|
||||
|
||||
def start_date_update_timer(self):
|
||||
now = QDateTime.currentDateTime()
|
||||
next_midnight = QDateTime(now.date().addDays(1), QTime(0, 0))
|
||||
next_midnight = QDateTime(now.date().addDays(1), QTime(0, 0)) # 设置为次日的午夜 00:00
|
||||
interval = now.msecsTo(next_midnight)
|
||||
self.date_update_timer.start(interval if interval > 0 else 86400000) # 86400000ms = 24小时
|
||||
|
||||
def update_date_edit(self):
|
||||
self.dateEdit.setDate(QDate.currentDate())
|
||||
self.dateEdit.update()
|
||||
self.dateEdit.setDate(QDate.currentDate()) # 设置 QDateEdit 控件的日期为当前日期
|
||||
self.update_date_range()
|
||||
self.start_date_update_timer()
|
||||
|
||||
@ -287,7 +275,7 @@ class Application(QMainWindow):
|
||||
if self.toaster_notify_enabled:
|
||||
self.tray_icon.showMessage(f"{title}通知", msg, QSystemTrayIcon.MessageIcon.Information, 2000)
|
||||
if self.telegram_notify_enabled:
|
||||
send_message(self.user.bot_token, self.chat_id, msg)
|
||||
send_message(self.user.bot_token, self.user.group_id, msg)
|
||||
|
||||
def on_report_clicked(self):
|
||||
try:
|
||||
@ -323,35 +311,42 @@ class Application(QMainWindow):
|
||||
# 获取当前的行数
|
||||
row_count = table.rowCount()
|
||||
table.insertRow(row_count)
|
||||
notifications = []
|
||||
|
||||
notifications = []
|
||||
for col, cell_data in enumerate(data):
|
||||
cell = self.create_table_cell(cell_data, table, col)
|
||||
# 使用 row_count 而不是 0l
|
||||
table.setItem(row_count, col, cell)
|
||||
self.handle_data_change(table, cell_data, col, account_username, notifications)
|
||||
self.set_table_item(table, row_count, col, cell_data)
|
||||
self.check_data_change_for_notifications(table, row_count, col, cell_data, account_username, notifications)
|
||||
|
||||
self.send_all_notifications(notifications)
|
||||
|
||||
def create_table_cell(self, cell_data, table, col):
|
||||
def send_all_notifications(self, notifications):
|
||||
"""发送所有通知"""
|
||||
for notification in notifications:
|
||||
self.send_notification(*notification)
|
||||
|
||||
def set_table_item(self, table, row, col, cell_data):
|
||||
"""在表格指定行列设置单元格数据"""
|
||||
cell = QTableWidgetItem(str(cell_data))
|
||||
cell.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
return cell
|
||||
table.setItem(row, col, cell)
|
||||
|
||||
def handle_data_change(self, table, cell_data, col, account_username, notifications):
|
||||
if table.rowCount() > 1 and col != 0:
|
||||
old_data_str = table.item(table.rowCount() - 2, col).text()
|
||||
def check_data_change_for_notifications(self, table, row, col, new_data, account_username, notifications):
|
||||
"""检查数据变更并准备通知"""
|
||||
if row > 0 and col != 0: # 忽略第一列,通常是时间戳
|
||||
old_data_str = table.item(row - 1, col).text()
|
||||
old_data = convert_data(old_data_str)
|
||||
new_data = convert_data(cell_data)
|
||||
|
||||
new_data = convert_data(new_data)
|
||||
if old_data != new_data:
|
||||
count_change = new_data - old_data
|
||||
self.update_cell_color(table, col, count_change)
|
||||
self.generate_notifications(account_username, col, cell_data, count_change, notifications)
|
||||
self.handle_data_change(table, col, new_data - old_data, account_username, notifications)
|
||||
|
||||
def update_cell_color(self, table, col, count_change):
|
||||
# 更新单元格颜色
|
||||
cell = table.item(table.rowCount() - 1, col)
|
||||
def handle_data_change(self, table, col, count_change, account_username, notifications):
|
||||
"""处理表格数据变更,更新单元格颜色,并生成通知"""
|
||||
self.update_cell_color(table, table.rowCount() - 1, col, count_change)
|
||||
self.generate_notifications(account_username, col, col, count_change, notifications)
|
||||
|
||||
def update_cell_color(self, table, row, col, count_change):
|
||||
"""更新单元格颜色"""
|
||||
cell = table.item(row, col)
|
||||
if count_change > 0:
|
||||
cell.setForeground(QColor(Qt.GlobalColor.green))
|
||||
elif count_change < 0:
|
||||
@ -373,10 +368,6 @@ class Application(QMainWindow):
|
||||
notifications.append(
|
||||
('🎉', account.name, '首存', count_change, deposit_results, str(cell_data)))
|
||||
|
||||
def send_all_notifications(self, notifications):
|
||||
for notification in notifications:
|
||||
self.send_notification(*notification)
|
||||
|
||||
def addToggleButton(self, text, style):
|
||||
toggleButton = QPushButton(text)
|
||||
toggleButton.setCheckable(True)
|
||||
@ -399,39 +390,29 @@ class Application(QMainWindow):
|
||||
self.main_layout.addLayout(self.middle_panel)
|
||||
|
||||
def add_tabs(self, notebook):
|
||||
column_headers = ["时间", "注册", "首存", "负盈利", "有效", "活跃"]
|
||||
column_headers = ColumnHeaders.list()
|
||||
for account in self.user.accounts:
|
||||
# 创建 Tab 和布局
|
||||
tab = QWidget()
|
||||
tab_layout = QVBoxLayout(tab)
|
||||
notebook.addTab(tab, account.name)
|
||||
|
||||
# 创建表格并设置列数和列标题
|
||||
table = QTableWidget()
|
||||
table.setColumnCount(len(column_headers))
|
||||
table.setHorizontalHeaderLabels(column_headers)
|
||||
|
||||
# 禁用表格的编辑功能
|
||||
table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
|
||||
|
||||
# 设置列宽
|
||||
header = table.horizontalHeader()
|
||||
|
||||
# 设置所有列为自适应宽度
|
||||
for i in range(len(column_headers)):
|
||||
header.setSectionResizeMode(i, QHeaderView.ResizeMode.Stretch)
|
||||
|
||||
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
|
||||
|
||||
# 将表格的大小调整策略设置为填充整个 Tab
|
||||
table.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding))
|
||||
|
||||
# 将表格添加到布局中
|
||||
table = self.create_table_for_tab(column_headers)
|
||||
tab_layout.addWidget(table)
|
||||
|
||||
# 保存表格引用以便稍后更新
|
||||
self.tables[account.username] = table
|
||||
|
||||
def create_table_for_tab(self, column_headers):
|
||||
table = QTableWidget()
|
||||
table.setColumnCount(len(column_headers))
|
||||
table.setHorizontalHeaderLabels(column_headers)
|
||||
table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
|
||||
|
||||
header = table.horizontalHeader()
|
||||
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
||||
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
|
||||
|
||||
table.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding))
|
||||
return table
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
self.drag_position = event.globalPosition().toPoint()
|
||||
@ -540,13 +521,40 @@ class Application(QMainWindow):
|
||||
|
||||
def tray_icon_clicked(self, reason):
|
||||
if reason == QSystemTrayIcon.ActivationReason.Trigger:
|
||||
if self.isVisible():
|
||||
self.hide()
|
||||
if self.isMinimized() or not self.isVisible():
|
||||
self.showNormal() # 恢复窗口大小
|
||||
self.activateWindow() # 激活窗口
|
||||
else:
|
||||
self.showNormal()
|
||||
self.hide() # 点击托盘图标再次隐藏窗口
|
||||
|
||||
|
||||
def copy_to_clipboard(text):
|
||||
clipboard = QApplication.clipboard()
|
||||
clipboard.setText(text)
|
||||
|
||||
|
||||
class SystemTrayIcon(QSystemTrayIcon):
|
||||
def __init__(self, icon, parent=None):
|
||||
super().__init__(icon, parent)
|
||||
self.menu = QMenu(parent)
|
||||
self.setContextMenu(self.menu)
|
||||
self.create_actions(parent)
|
||||
|
||||
def create_actions(self, parent):
|
||||
exit_action = QAction("Exit", parent)
|
||||
exit_action.triggered.connect(parent.exit_application)
|
||||
self.menu.addAction(exit_action)
|
||||
|
||||
|
||||
class ColumnHeaders(Enum):
|
||||
TIME = "时间"
|
||||
REGISTER = "注册"
|
||||
FIRST_DEPOSIT = "首存"
|
||||
NET_PROFIT = "负盈利"
|
||||
EFFECTIVE = "有效"
|
||||
ACTIVE = "活跃"
|
||||
|
||||
@classmethod
|
||||
def list(cls):
|
||||
return [cls.TIME.value, cls.REGISTER.value, cls.FIRST_DEPOSIT.value,
|
||||
cls.NET_PROFIT.value, cls.EFFECTIVE.value, cls.ACTIVE.value]
|
||||
|
14
src/ui/config.py
Normal file
14
src/ui/config.py
Normal file
@ -0,0 +1,14 @@
|
||||
import configparser
|
||||
import os
|
||||
from loguru import logger
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
def __init__(self, config_path='config.ini'):
|
||||
self.config = configparser.ConfigParser()
|
||||
if not os.path.exists(config_path):
|
||||
raise FileNotFoundError(f"配置文件 {config_path} 不存在。")
|
||||
self.config.read(config_path, encoding='utf-8')
|
||||
|
||||
def get(self, section, option, fallback=None):
|
||||
return self.config.get(section, option, fallback=fallback)
|
@ -5,7 +5,7 @@ from PyQt6.QtCore import QObject, QRunnable, pyqtSignal
|
||||
from src.entity.banner_info import get_banner_info, get_banner_info_by_user
|
||||
from src.entity.finance import get_adjusted_salary, get_net_win_by_user
|
||||
from src.entity.pay_record import get_pay_failed_by_user
|
||||
from src.entity.visual_list import text_count_by_user
|
||||
from src.entity.visual_list import text_count_by_user, get_statics
|
||||
|
||||
|
||||
class TaskSignals(QObject):
|
||||
@ -31,8 +31,9 @@ class ReportTask(QRunnable):
|
||||
return [time_str, banner_info.registerMembers, banner_info.firstDepositNum, banner_info.netWinLose,
|
||||
banner_info.effectiveNew, banner_info.activeMembers]
|
||||
|
||||
|
||||
@staticmethod
|
||||
def query_data_for_user(user):
|
||||
def get_banner_info_by_user(user):
|
||||
banner_info_res = get_banner_info_by_user(user)
|
||||
return banner_info_res
|
||||
|
||||
|
15
src/ui/system_tray_icon.py
Normal file
15
src/ui/system_tray_icon.py
Normal file
@ -0,0 +1,15 @@
|
||||
from PyQt6.QtWidgets import QSystemTrayIcon, QMenu
|
||||
from PyQt6.QtGui import QIcon, QAction
|
||||
|
||||
|
||||
class SystemTrayIcon(QSystemTrayIcon):
|
||||
def __init__(self, icon, parent=None):
|
||||
super().__init__(icon, parent)
|
||||
self.menu = QMenu(parent)
|
||||
self.setContextMenu(self.menu)
|
||||
self.create_actions(parent)
|
||||
|
||||
def create_actions(self, parent):
|
||||
exit_action = QAction("Exit", parent)
|
||||
exit_action.triggered.connect(parent.exit_application)
|
||||
self.menu.addAction(exit_action)
|
@ -2,69 +2,58 @@ from PyQt6.QtCore import Qt
|
||||
from PyQt6.QtGui import QFont, QIcon, QPixmap
|
||||
from PyQt6.QtWidgets import QHBoxLayout, QLabel, QToolButton, QWidget
|
||||
|
||||
|
||||
class CustomTitleBar(QWidget):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
self.setup_ui()
|
||||
self.mousePressed = False
|
||||
self.setup_ui()
|
||||
|
||||
def setup_ui(self):
|
||||
self.layout = QHBoxLayout()
|
||||
self.layout.setContentsMargins(0, 0, 0, 0) # 设置布局的边距为0
|
||||
self.layout.setSpacing(0) # 设置按钮之间的间距为0
|
||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.layout.setSpacing(0)
|
||||
|
||||
# 创建图标 QLabel
|
||||
self.setup_icon_label()
|
||||
self.setup_title_label()
|
||||
self.setup_buttons()
|
||||
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def setup_icon_label(self):
|
||||
self.iconLabel = QLabel(self)
|
||||
self.iconLabel.setFixedSize(32, 32) # 设置图标大小
|
||||
self.iconLabel.setFixedSize(32, 32)
|
||||
iconPixmap = QPixmap('icons:icon.png').scaled(24, 24, Qt.AspectRatioMode.KeepAspectRatio)
|
||||
self.iconLabel.setPixmap(iconPixmap)
|
||||
self.layout.addWidget(self.iconLabel) # 添加图标到布局
|
||||
self.layout.addWidget(self.iconLabel)
|
||||
|
||||
# 创建标题 QLabel
|
||||
def setup_title_label(self):
|
||||
font = QFont()
|
||||
font.setPointSize(11)
|
||||
self.titleLabel = QLabel("zayac的小工具")
|
||||
self.titleLabel = QLabel("zayac’s Toolkit")
|
||||
self.titleLabel.setFont(font)
|
||||
self.titleLabel.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
|
||||
self.layout.addWidget(self.titleLabel, 1)
|
||||
|
||||
# 使用图标按钮并应用样式
|
||||
self.stayOnTopButton = QToolButton()
|
||||
self.stayOnTopButton.setIcon(QIcon('icons:top.svg'))
|
||||
self.stayOnTopButton.setFixedSize(32, 32) # 设置按钮的固定大小
|
||||
self.stayOnTopButton.setCheckable(True)
|
||||
self.stayOnTopButton.clicked.connect(self.toggle_stay_on_top)
|
||||
self.layout.addWidget(self.stayOnTopButton)
|
||||
|
||||
# 设置其他按钮
|
||||
self.minimizeButton = QToolButton()
|
||||
self.minimizeButton.setIcon(QIcon('icons:min.svg'))
|
||||
self.minimizeButton.setFixedSize(32, 32)
|
||||
self.minimizeButton.clicked.connect(self.parent.showMinimized)
|
||||
self.layout.addWidget(self.minimizeButton)
|
||||
|
||||
self.maximizeButton = QToolButton()
|
||||
self.maximizeButton.setIcon(QIcon('icons:max.svg'))
|
||||
self.maximizeButton.setFixedSize(32, 32)
|
||||
self.maximizeButton.clicked.connect(self.toggle_maximize)
|
||||
self.layout.addWidget(self.maximizeButton)
|
||||
|
||||
self.closeButton = QToolButton()
|
||||
self.closeButton.setIcon(QIcon('icons:close.svg'))
|
||||
self.closeButton.setFixedSize(32, 32)
|
||||
self.closeButton.clicked.connect(self.parent.close)
|
||||
def setup_buttons(self):
|
||||
self.stayOnTopButton = self.create_tool_button('icons:top.svg', self.toggle_stay_on_top)
|
||||
self.minimizeButton = self.create_tool_button('icons:min.svg', self.parent.showMinimized)
|
||||
self.maximizeButton = self.create_tool_button('icons:max.svg', self.toggle_maximize)
|
||||
self.closeButton = self.create_tool_button('icons:close.svg', self.parent.close)
|
||||
self.closeButton.setObjectName("closeButton")
|
||||
self.layout.addWidget(self.closeButton)
|
||||
|
||||
# 在创建按钮后立即设置样式表
|
||||
|
||||
self.setLayout(self.layout)
|
||||
def create_tool_button(self, icon_path, callback):
|
||||
button = QToolButton()
|
||||
button.setIcon(QIcon(icon_path))
|
||||
button.setFixedSize(32, 32)
|
||||
button.clicked.connect(callback)
|
||||
self.layout.addWidget(button)
|
||||
return button
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
self.mousePressed = True
|
||||
self.mousePos = event.globalPosition().toPoint()
|
||||
if event.buttons() == Qt.MouseButton.LeftButton:
|
||||
self.mousePressed = True
|
||||
self.mousePos = event.globalPosition().toPoint()
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
if self.mousePressed:
|
||||
@ -75,20 +64,17 @@ class CustomTitleBar(QWidget):
|
||||
self.mousePressed = False
|
||||
|
||||
def toggle_stay_on_top(self):
|
||||
current_flags = self.parent.windowFlags()
|
||||
if self.stayOnTopButton.isChecked():
|
||||
self.parent.setWindowFlags(self.parent.windowFlags() | Qt.WindowType.WindowStaysOnTopHint)
|
||||
self.parent.setWindowFlags(current_flags | Qt.WindowType.WindowStaysOnTopHint)
|
||||
else:
|
||||
self.parent.setWindowFlags(self.parent.windowFlags() & ~Qt.WindowType.WindowStaysOnTopHint)
|
||||
self.parent.show() # 重新显示窗口以应用新的窗口标志
|
||||
|
||||
def enterEvent(self, event):
|
||||
self.parent.reset_cursor_style() # 通知主窗口重置鼠标样式
|
||||
|
||||
def leaveEvent(self, event):
|
||||
self.parent.reset_cursor_style() # 通知主窗口重置鼠标样式
|
||||
self.parent.setWindowFlags(current_flags & ~Qt.WindowType.WindowStaysOnTopHint)
|
||||
self.parent.show() # Re-show the window to apply new window flags
|
||||
|
||||
def toggle_maximize(self):
|
||||
if self.parent.isMaximized():
|
||||
self.parent.showNormal()
|
||||
self.maximizeButton.setIcon(QIcon('icons:max.svg')) # Update icon if needed
|
||||
else:
|
||||
self.parent.showMaximized()
|
||||
self.maximizeButton.setIcon(QIcon('icons:restore.svg')) # Update icon if needed
|
Loading…
Reference in New Issue
Block a user