mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-08-02 06:09:36 +08:00
Compare commits
8 Commits
ed8dec70a6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 88393f53e4 | |||
| e4d838a9d0 | |||
| 70f78c2a6f | |||
| e40e7767c7 | |||
| 1b6c170d6c | |||
| 30a7a8e996 | |||
| d59ecc3090 | |||
| 7685f6a616 |
@@ -104,6 +104,7 @@ class _DateInputContainer(QWidget):
|
|||||||
):
|
):
|
||||||
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self.setupUi()
|
self.setupUi()
|
||||||
|
|
||||||
def setupUi(
|
def setupUi(
|
||||||
@@ -153,10 +154,16 @@ class _TimeInputContainer(QWidget):
|
|||||||
):
|
):
|
||||||
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.setupUi()
|
||||||
|
|
||||||
|
def setupUi(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
self.TimeEdit = QTimeEdit(self)
|
self.TimeEdit = QTimeEdit(self)
|
||||||
self.TimeEdit.setDisplayFormat("HH:mm")
|
self.TimeEdit.setDisplayFormat("HH:mm")
|
||||||
self.TimeEdit.setFixedHeight(25)
|
self.TimeEdit.setFixedHeight(25)
|
||||||
|
|
||||||
Layout = QHBoxLayout(self)
|
Layout = QHBoxLayout(self)
|
||||||
Layout.setContentsMargins(0, 0, 0, 0)
|
Layout.setContentsMargins(0, 0, 0, 0)
|
||||||
Layout.addWidget(self.TimeEdit)
|
Layout.addWidget(self.TimeEdit)
|
||||||
@@ -176,6 +183,13 @@ class _DateOffsetContainer(QWidget):
|
|||||||
):
|
):
|
||||||
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.setupUi()
|
||||||
|
|
||||||
|
def setupUi(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
self.SpinBox = QSpinBox(self)
|
self.SpinBox = QSpinBox(self)
|
||||||
self.SpinBox.setRange(0, 99999)
|
self.SpinBox.setRange(0, 99999)
|
||||||
self.SpinBox.setFixedHeight(25)
|
self.SpinBox.setFixedHeight(25)
|
||||||
@@ -183,7 +197,6 @@ class _DateOffsetContainer(QWidget):
|
|||||||
for display, data in DATE_OFFSET_OPTIONS:
|
for display, data in DATE_OFFSET_OPTIONS:
|
||||||
self.UnitCombo.addItem(display, data)
|
self.UnitCombo.addItem(display, data)
|
||||||
self.UnitCombo.setFixedHeight(25)
|
self.UnitCombo.setFixedHeight(25)
|
||||||
|
|
||||||
Layout = QHBoxLayout(self)
|
Layout = QHBoxLayout(self)
|
||||||
Layout.setContentsMargins(0, 0, 0, 0)
|
Layout.setContentsMargins(0, 0, 0, 0)
|
||||||
Layout.setSpacing(4)
|
Layout.setSpacing(4)
|
||||||
@@ -220,11 +233,17 @@ class _TimeOffsetContainer(QWidget):
|
|||||||
):
|
):
|
||||||
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.setupUi()
|
||||||
|
|
||||||
|
def setupUi(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
self.SpinBox = QSpinBox(self)
|
self.SpinBox = QSpinBox(self)
|
||||||
self.SpinBox.setRange(0, 99999)
|
self.SpinBox.setRange(0, 99999)
|
||||||
self.SpinBox.setSuffix(" 小时")
|
self.SpinBox.setSuffix(" 小时")
|
||||||
self.SpinBox.setFixedHeight(25)
|
self.SpinBox.setFixedHeight(25)
|
||||||
|
|
||||||
Layout = QHBoxLayout(self)
|
Layout = QHBoxLayout(self)
|
||||||
Layout.setContentsMargins(0, 0, 0, 0)
|
Layout.setContentsMargins(0, 0, 0, 0)
|
||||||
Layout.addWidget(self.SpinBox)
|
Layout.addWidget(self.SpinBox)
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Copyright (c) 2026 KenanZhu.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
This software is provided "as is", without any warranty of any kind.
|
||||||
|
You may use, modify, and distribute this file under the terms of the MIT License.
|
||||||
|
See the LICENSE file for details.
|
||||||
|
"""
|
||||||
|
from PySide6.QtCore import Qt
|
||||||
|
from PySide6.QtGui import QDesktopServices
|
||||||
|
from PySide6.QtCore import QUrl
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QDialog,
|
||||||
|
QDialogButtonBox,
|
||||||
|
QLabel,
|
||||||
|
QVBoxLayout
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ALCheckUpdateDialog(QDialog):
|
||||||
|
"""
|
||||||
|
Dialog for showing update check result.
|
||||||
|
|
||||||
|
Supports two layouts:
|
||||||
|
- has_update=True : version comparison with green text + action buttons
|
||||||
|
- has_update=False: "already up-to-date" message + close button
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent=None,
|
||||||
|
has_update: bool = False,
|
||||||
|
current_version: str = "",
|
||||||
|
latest_version: str = "",
|
||||||
|
tag_name: str = "",
|
||||||
|
html_url: str = ""
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(parent)
|
||||||
|
self.__has_update = has_update
|
||||||
|
self.__html_url = html_url
|
||||||
|
self.__current_version = current_version
|
||||||
|
self.__latest_version = latest_version
|
||||||
|
self.__tag_name = tag_name
|
||||||
|
|
||||||
|
self.modifyUi()
|
||||||
|
self.connectSignals()
|
||||||
|
|
||||||
|
def modifyUi(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.setWindowTitle("检查更新 - AutoLibrary")
|
||||||
|
self.setMinimumWidth(360)
|
||||||
|
Layout = QVBoxLayout(self)
|
||||||
|
Layout.setSpacing(12)
|
||||||
|
Layout.setContentsMargins(20, 20, 20, 20)
|
||||||
|
if self.__has_update:
|
||||||
|
self.buildUpdateAvailableUi(Layout)
|
||||||
|
else:
|
||||||
|
self.buildUpToDateUi(Layout)
|
||||||
|
|
||||||
|
def buildUpdateAvailableUi(
|
||||||
|
self,
|
||||||
|
layout: QVBoxLayout
|
||||||
|
):
|
||||||
|
|
||||||
|
TitleLabel = QLabel()
|
||||||
|
TitleLabel.setStyleSheet(
|
||||||
|
"font-size: 14px;"
|
||||||
|
"font-weight: bold;"
|
||||||
|
)
|
||||||
|
TitleLabel.setTextFormat(Qt.TextFormat.RichText)
|
||||||
|
TitleLabel.setText(
|
||||||
|
f"检测到新版本: "
|
||||||
|
f"<span>{self.__current_version}</span> "
|
||||||
|
f"<span>></span> "
|
||||||
|
f"<span style='color: green; font-weight: bold;'>{self.__latest_version}</span>"
|
||||||
|
)
|
||||||
|
layout.addWidget(TitleLabel)
|
||||||
|
InfoLabel = QLabel()
|
||||||
|
InfoLabel.setTextFormat(Qt.TextFormat.RichText)
|
||||||
|
InfoLabel.setWordWrap(True)
|
||||||
|
InfoLabel.setText(
|
||||||
|
f"最新版本: <b>{self.__tag_name}</b><br>"
|
||||||
|
)
|
||||||
|
InfoLabel.setOpenExternalLinks(True)
|
||||||
|
layout.addWidget(InfoLabel)
|
||||||
|
layout.addSpacing(8)
|
||||||
|
self.__button_box = QDialogButtonBox()
|
||||||
|
self.__btn_github = self.__button_box.addButton(
|
||||||
|
"前往 GitHub",
|
||||||
|
QDialogButtonBox.ButtonRole.AcceptRole
|
||||||
|
)
|
||||||
|
self.__btn_github.setMinimumWidth(100)
|
||||||
|
self.__btn_github.setMaximumWidth(100)
|
||||||
|
self.__btn_github.setMinimumHeight(25)
|
||||||
|
self.__btn_github.setMaximumHeight(25)
|
||||||
|
self.__btn_download = self.__button_box.addButton(
|
||||||
|
"官网下载",
|
||||||
|
QDialogButtonBox.ButtonRole.ActionRole
|
||||||
|
)
|
||||||
|
self.__btn_download.setMinimumWidth(80)
|
||||||
|
self.__btn_download.setMaximumWidth(80)
|
||||||
|
self.__btn_download.setMinimumHeight(25)
|
||||||
|
self.__btn_download.setMaximumHeight(25)
|
||||||
|
self.__btn_cancel = self.__button_box.addButton(
|
||||||
|
"取消",
|
||||||
|
QDialogButtonBox.ButtonRole.RejectRole
|
||||||
|
)
|
||||||
|
self.__btn_cancel.setMinimumWidth(80)
|
||||||
|
self.__btn_cancel.setMaximumWidth(80)
|
||||||
|
self.__btn_cancel.setMinimumHeight(25)
|
||||||
|
self.__btn_cancel.setMaximumHeight(25)
|
||||||
|
layout.addWidget(self.__button_box)
|
||||||
|
|
||||||
|
def buildUpToDateUi(
|
||||||
|
self,
|
||||||
|
layout: QVBoxLayout
|
||||||
|
):
|
||||||
|
|
||||||
|
TitleLabel = QLabel()
|
||||||
|
TitleLabel.setStyleSheet(
|
||||||
|
"font-size: 14px;"
|
||||||
|
"font-weight: bold;"
|
||||||
|
)
|
||||||
|
TitleLabel.setText(f"已是最新版本 !")
|
||||||
|
layout.addWidget(TitleLabel)
|
||||||
|
InfoLabel = QLabel()
|
||||||
|
InfoLabel.setText(
|
||||||
|
f"当前版本: <b>{self.__current_version}</b><br>"
|
||||||
|
)
|
||||||
|
layout.addWidget(InfoLabel)
|
||||||
|
layout.addStretch()
|
||||||
|
self.__button_box = QDialogButtonBox()
|
||||||
|
self.__btn_close = self.__button_box.addButton(
|
||||||
|
"确定",
|
||||||
|
QDialogButtonBox.ButtonRole.AcceptRole
|
||||||
|
)
|
||||||
|
self.__btn_close.setMinimumWidth(80)
|
||||||
|
self.__btn_close.setMaximumWidth(80)
|
||||||
|
self.__btn_close.setMinimumHeight(25)
|
||||||
|
self.__btn_close.setMaximumHeight(25)
|
||||||
|
layout.addWidget(self.__button_box)
|
||||||
|
|
||||||
|
def connectSignals(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
if self.__has_update:
|
||||||
|
self.__btn_github.clicked.connect(self.onGoToGitHub)
|
||||||
|
self.__btn_download.clicked.connect(self.onGoToDownload)
|
||||||
|
self.__btn_cancel.clicked.connect(self.reject)
|
||||||
|
else:
|
||||||
|
self.__btn_close.clicked.connect(self.accept)
|
||||||
|
|
||||||
|
def onGoToGitHub(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
QDesktopServices.openUrl(QUrl(self.__html_url))
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
def onGoToDownload(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
QDesktopServices.openUrl(
|
||||||
|
QUrl("https://www.autolibrary.kenanzhu.com/downloads")
|
||||||
|
)
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def showResult(
|
||||||
|
parent,
|
||||||
|
has_update: bool,
|
||||||
|
current_version: str,
|
||||||
|
latest_version: str = "",
|
||||||
|
tag_name: str = "",
|
||||||
|
html_url: str = ""
|
||||||
|
):
|
||||||
|
|
||||||
|
dialog = ALCheckUpdateDialog(
|
||||||
|
parent,
|
||||||
|
has_update=has_update,
|
||||||
|
current_version=current_version,
|
||||||
|
latest_version=latest_version,
|
||||||
|
tag_name=tag_name,
|
||||||
|
html_url=html_url
|
||||||
|
)
|
||||||
|
dialog.exec()
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Copyright (c) 2026 KenanZhu.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
This software is provided "as is", without any warranty of any kind.
|
||||||
|
You may use, modify, and distribute this file under the terms of the MIT License.
|
||||||
|
See the LICENSE file for details.
|
||||||
|
"""
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from PySide6.QtCore import (
|
||||||
|
QThread,
|
||||||
|
Signal
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ALCheckUpdateWorker(QThread):
|
||||||
|
"""
|
||||||
|
Worker thread for checking latest release from GitHub API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
checkUpdateWorkerIsFinished = Signal(dict)
|
||||||
|
checkUpdateWorkerFinishedWithError = Signal(str)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent=None
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(parent)
|
||||||
|
self.__api_url = "https://api.github.com/repos/KenanZhu/AutoLibrary/releases/latest"
|
||||||
|
|
||||||
|
def run(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(self.__api_url, timeout=10)
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
self.checkUpdateWorkerIsFinished.emit({
|
||||||
|
"tag_name": data.get("tag_name", ""),
|
||||||
|
"name": data.get("name", ""),
|
||||||
|
"html_url": data.get("html_url", ""),
|
||||||
|
"body": data.get("body", ""),
|
||||||
|
})
|
||||||
|
except requests.RequestException as e:
|
||||||
|
self.checkUpdateWorkerFinishedWithError.emit(f"网络请求失败: \n{e}")
|
||||||
|
except Exception as e:
|
||||||
|
self.checkUpdateWorkerFinishedWithError.emit(f"检查更新时发生未知错误: \n{e}")
|
||||||
+115
-33
@@ -9,6 +9,8 @@ See the LICENSE file for details.
|
|||||||
"""
|
"""
|
||||||
import queue
|
import queue
|
||||||
|
|
||||||
|
import packaging.version as ver
|
||||||
|
|
||||||
from PySide6.QtCore import (
|
from PySide6.QtCore import (
|
||||||
QTimer,
|
QTimer,
|
||||||
QUrl,
|
QUrl,
|
||||||
@@ -32,12 +34,15 @@ from PySide6.QtWidgets import (
|
|||||||
from base.MsgBase import MsgBase
|
from base.MsgBase import MsgBase
|
||||||
from gui.ALAboutDialog import ALAboutDialog
|
from gui.ALAboutDialog import ALAboutDialog
|
||||||
from gui.ALBulletinDialog import ALBulletinDialog
|
from gui.ALBulletinDialog import ALBulletinDialog
|
||||||
|
from gui.ALCheckUpdateWorker import ALCheckUpdateWorker
|
||||||
|
from gui.ALCheckUpdateDialog import ALCheckUpdateDialog
|
||||||
from gui.ALConfigWidget import ALConfigWidget
|
from gui.ALConfigWidget import ALConfigWidget
|
||||||
from gui.ALSettingsWidget import ALSettingsWidget
|
from gui.ALSettingsWidget import ALSettingsWidget
|
||||||
from gui.ALTimerTaskManageWidget import ALTimerTaskManageWidget
|
from gui.ALTimerTaskManageWidget import ALTimerTaskManageWidget
|
||||||
from gui.ALMainWorker import AutoLibWorker
|
from gui.ALMainWorker import AutoLibWorker
|
||||||
from gui.ALBulletinPoller import ALBulletinPoller
|
from gui.ALBulletinPoller import ALBulletinPoller
|
||||||
from gui.ALTimerTaskPoller import ALTimerTaskPoller
|
from gui.ALTimerTaskPoller import ALTimerTaskPoller
|
||||||
|
from gui.ALVersionInfo import AL_VERSION
|
||||||
from gui.resources import ALResource
|
from gui.resources import ALResource
|
||||||
from gui.resources.ui.Ui_ALMainWindow import Ui_ALMainWindow
|
from gui.resources.ui.Ui_ALMainWindow import Ui_ALMainWindow
|
||||||
from managers.bulletin.BulletinManager import instance as bulletinInstance
|
from managers.bulletin.BulletinManager import instance as bulletinInstance
|
||||||
@@ -86,10 +91,10 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
|||||||
self.setWindowIcon(self.Icon)
|
self.setWindowIcon(self.Icon)
|
||||||
self.MessageIOTextEdit.setFont(QFont("Courier New", 10))
|
self.MessageIOTextEdit.setFont(QFont("Courier New", 10))
|
||||||
self.ManualAction.triggered.connect(self.onManualActionTriggered)
|
self.ManualAction.triggered.connect(self.onManualActionTriggered)
|
||||||
|
self.CheckUpdateAction.triggered.connect(self.onCheckUpdateActionTriggered)
|
||||||
self.AboutAction.triggered.connect(self.onAboutActionTriggered)
|
self.AboutAction.triggered.connect(self.onAboutActionTriggered)
|
||||||
self.SettingsAction.triggered.connect(self.onSettingsActionTriggered)
|
self.SettingsAction.triggered.connect(self.onSettingsActionTriggered)
|
||||||
if hasattr(self, 'BulletinAction'):
|
self.BulletinAction.triggered.connect(self.onBulletinActionTriggered)
|
||||||
self.BulletinAction.triggered.connect(self.onBulletinActionTriggered)
|
|
||||||
# initialize timer task widget, but not show it
|
# initialize timer task widget, but not show it
|
||||||
try:
|
try:
|
||||||
self.__ALTimerTaskManageWidget = ALTimerTaskManageWidget(self)
|
self.__ALTimerTaskManageWidget = ALTimerTaskManageWidget(self)
|
||||||
@@ -112,20 +117,6 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
|||||||
self.__ALTimerTaskManageWidget.timerTaskManageWidgetIsClosed.connect(self.onTimerTaskManageWidgetClosed)
|
self.__ALTimerTaskManageWidget.timerTaskManageWidgetIsClosed.connect(self.onTimerTaskManageWidgetClosed)
|
||||||
self.__ALTimerTaskManageWidget.setWindowFlags(Qt.WindowType.Window|Qt.WindowType.WindowCloseButtonHint)
|
self.__ALTimerTaskManageWidget.setWindowFlags(Qt.WindowType.Window|Qt.WindowType.WindowCloseButtonHint)
|
||||||
|
|
||||||
def onAboutActionTriggered(
|
|
||||||
self
|
|
||||||
):
|
|
||||||
|
|
||||||
AboutDialog = ALAboutDialog(self)
|
|
||||||
AboutDialog.exec()
|
|
||||||
|
|
||||||
def onManualActionTriggered(
|
|
||||||
self
|
|
||||||
):
|
|
||||||
|
|
||||||
url = QUrl("https://manuals.autolibrary.kenanzhu.com")
|
|
||||||
QDesktopServices.openUrl(url)
|
|
||||||
|
|
||||||
def setupTray(
|
def setupTray(
|
||||||
self
|
self
|
||||||
):
|
):
|
||||||
@@ -161,14 +152,6 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
|||||||
2000
|
2000
|
||||||
)
|
)
|
||||||
|
|
||||||
def onTrayIconActivated(
|
|
||||||
self,
|
|
||||||
reason: QSystemTrayIcon.ActivationReason
|
|
||||||
):
|
|
||||||
|
|
||||||
if reason == QSystemTrayIcon.DoubleClick:
|
|
||||||
self.showNormal()
|
|
||||||
|
|
||||||
def connectSignals(
|
def connectSignals(
|
||||||
self
|
self
|
||||||
):
|
):
|
||||||
@@ -315,6 +298,67 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
|||||||
f"定时任务 {timer_task['name']} 执行{'失败' if is_error else '完成'}, uuid: {timer_task['uuid']}"
|
f"定时任务 {timer_task['name']} 执行{'失败' if is_error else '完成'}, uuid: {timer_task['uuid']}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Slot(dict)
|
||||||
|
def onCheckUpdateIsFinished(
|
||||||
|
self,
|
||||||
|
data: dict
|
||||||
|
):
|
||||||
|
|
||||||
|
worker = self.sender()
|
||||||
|
if worker is not self.__check_update_worker:
|
||||||
|
return
|
||||||
|
worker.checkUpdateWorkerIsFinished.disconnect(self.onCheckUpdateIsFinished)
|
||||||
|
worker.checkUpdateWorkerFinishedWithError.disconnect(self.onCheckUpdateFinishedWithError)
|
||||||
|
worker.wait(3000)
|
||||||
|
worker.deleteLater()
|
||||||
|
self.__check_update_worker = None
|
||||||
|
tag_name = data.get("tag_name", "")
|
||||||
|
html_url = data.get("html_url", "")
|
||||||
|
latest_version = tag_name.lstrip("v")
|
||||||
|
try:
|
||||||
|
local_ver = ver.Version(AL_VERSION)
|
||||||
|
remote_ver = ver.Version(latest_version)
|
||||||
|
except ver.InvalidVersion:
|
||||||
|
self._showTrace("版本号解析失败, 无法比较版本", self.TraceLevel.WARNING)
|
||||||
|
return
|
||||||
|
if remote_ver > local_ver:
|
||||||
|
ALCheckUpdateDialog.showResult(
|
||||||
|
self,
|
||||||
|
has_update=True,
|
||||||
|
current_version=AL_VERSION,
|
||||||
|
latest_version=latest_version,
|
||||||
|
tag_name=tag_name,
|
||||||
|
html_url=html_url
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ALCheckUpdateDialog.showResult(
|
||||||
|
self,
|
||||||
|
has_update=False,
|
||||||
|
current_version=AL_VERSION
|
||||||
|
)
|
||||||
|
self._showLog("检查更新完成")
|
||||||
|
|
||||||
|
@Slot(str)
|
||||||
|
def onCheckUpdateFinishedWithError(
|
||||||
|
self,
|
||||||
|
error_message: str
|
||||||
|
):
|
||||||
|
|
||||||
|
worker = self.sender()
|
||||||
|
if worker is not self.__check_update_worker:
|
||||||
|
return
|
||||||
|
worker.checkUpdateWorkerIsFinished.disconnect(self.onCheckUpdateIsFinished)
|
||||||
|
worker.checkUpdateWorkerFinishedWithError.disconnect(self.onCheckUpdateFinishedWithError)
|
||||||
|
worker.wait(3000)
|
||||||
|
worker.deleteLater()
|
||||||
|
self.__check_update_worker = None
|
||||||
|
QMessageBox.warning(
|
||||||
|
self,
|
||||||
|
"检查更新 - AutoLibrary",
|
||||||
|
f"检查更新失败: \n{error_message}",
|
||||||
|
)
|
||||||
|
self._showLog("检查更新失败")
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def onBulletinDialogClosed(
|
def onBulletinDialogClosed(
|
||||||
self
|
self
|
||||||
@@ -358,15 +402,6 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
|||||||
self.setControlButtons(True, None, None)
|
self.setControlButtons(True, None, None)
|
||||||
self._showLog("配置窗口已关闭,配置文件路径已更新")
|
self._showLog("配置窗口已关闭,配置文件路径已更新")
|
||||||
|
|
||||||
@Slot()
|
|
||||||
def onTrayMessageClicked(
|
|
||||||
self
|
|
||||||
):
|
|
||||||
|
|
||||||
if self.__notification_type == "bulletin":
|
|
||||||
self.__notification_type = ""
|
|
||||||
self.onBulletinActionTriggered()
|
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def onBulletinActionTriggered(
|
def onBulletinActionTriggered(
|
||||||
self
|
self
|
||||||
@@ -396,6 +431,53 @@ class ALMainWindow(MsgBase, QMainWindow, Ui_ALMainWindow):
|
|||||||
self.SettingsAction.setEnabled(False)
|
self.SettingsAction.setEnabled(False)
|
||||||
self._showLog("打开全局设置窗口")
|
self._showLog("打开全局设置窗口")
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onAboutActionTriggered(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
AboutDialog = ALAboutDialog(self)
|
||||||
|
AboutDialog.exec()
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onManualActionTriggered(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
url = QUrl("https://manuals.autolibrary.kenanzhu.com")
|
||||||
|
QDesktopServices.openUrl(url)
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onCheckUpdateActionTriggered(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
if hasattr(self, '__check_update_worker') and self.__check_update_worker is not None:
|
||||||
|
return
|
||||||
|
self.__check_update_worker = ALCheckUpdateWorker(self)
|
||||||
|
self.__check_update_worker.checkUpdateWorkerIsFinished.connect(self.onCheckUpdateIsFinished)
|
||||||
|
self.__check_update_worker.checkUpdateWorkerFinishedWithError.connect(self.onCheckUpdateFinishedWithError)
|
||||||
|
self.__check_update_worker.start()
|
||||||
|
self._showLog("正在检查更新...")
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onTrayMessageClicked(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
if self.__notification_type == "bulletin":
|
||||||
|
self.__notification_type = ""
|
||||||
|
self.onBulletinActionTriggered()
|
||||||
|
|
||||||
|
@Slot(QSystemTrayIcon.ActivationReason)
|
||||||
|
def onTrayIconActivated(
|
||||||
|
self,
|
||||||
|
reason: QSystemTrayIcon.ActivationReason
|
||||||
|
):
|
||||||
|
|
||||||
|
if reason == QSystemTrayIcon.DoubleClick:
|
||||||
|
self.showNormal()
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def onTimerTaskManageWidgetButtonClicked(
|
def onTimerTaskManageWidgetButtonClicked(
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
|||||||
event: QCloseEvent
|
event: QCloseEvent
|
||||||
):
|
):
|
||||||
|
|
||||||
|
if hasattr(self, '__bulletin_test_worker') and self.__bulletin_test_worker is not None:
|
||||||
|
self.__bulletin_test_worker.wait(3000)
|
||||||
self.settingsWidgetIsClosed.emit()
|
self.settingsWidgetIsClosed.emit()
|
||||||
super().closeEvent(event)
|
super().closeEvent(event)
|
||||||
|
|
||||||
@@ -386,7 +388,6 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
|||||||
idx = self.CustomThemeComboBox.findData(file_id)
|
idx = self.CustomThemeComboBox.findData(file_id)
|
||||||
if idx >= 0:
|
if idx >= 0:
|
||||||
self.CustomThemeComboBox.setCurrentIndex(idx)
|
self.CustomThemeComboBox.setCurrentIndex(idx)
|
||||||
self.updateCustomThemeStatus()
|
|
||||||
self.updateCustomThemeInfo()
|
self.updateCustomThemeInfo()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(
|
||||||
@@ -485,25 +486,26 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
|||||||
self, api_url, {"date": "", "time": "", "range_hour": "1"}
|
self, api_url, {"date": "", "time": "", "range_hour": "1"}
|
||||||
)
|
)
|
||||||
self.__bulletin_test_worker.fetchWorkerIsFinished.connect(
|
self.__bulletin_test_worker.fetchWorkerIsFinished.connect(
|
||||||
self.onBulletinTestFetched
|
self.onBulletinTestIsFinished
|
||||||
)
|
)
|
||||||
self.__bulletin_test_worker.fetchWorkerFinishedWithError.connect(
|
self.__bulletin_test_worker.fetchWorkerFinishedWithError.connect(
|
||||||
self.onBulletinTestError
|
self.onBulletinTestFinishedWithError
|
||||||
)
|
)
|
||||||
self.__bulletin_test_worker.start()
|
self.__bulletin_test_worker.start()
|
||||||
|
|
||||||
@Slot(dict)
|
@Slot(dict)
|
||||||
def onBulletinTestFetched(
|
def onBulletinTestIsFinished(
|
||||||
self,
|
self,
|
||||||
data: dict
|
data: dict
|
||||||
):
|
):
|
||||||
|
|
||||||
self.__bulletin_test_worker.fetchWorkerIsFinished.disconnect(
|
self.__bulletin_test_worker.fetchWorkerIsFinished.disconnect(
|
||||||
self.onBulletinTestFetched
|
self.onBulletinTestIsFinished
|
||||||
)
|
)
|
||||||
self.__bulletin_test_worker.fetchWorkerFinishedWithError.disconnect(
|
self.__bulletin_test_worker.fetchWorkerFinishedWithError.disconnect(
|
||||||
self.onBulletinTestError
|
self.onBulletinTestFinishedWithError
|
||||||
)
|
)
|
||||||
|
self.__bulletin_test_worker.wait(3000)
|
||||||
self.__bulletin_test_worker.deleteLater()
|
self.__bulletin_test_worker.deleteLater()
|
||||||
self.__bulletin_test_worker = None
|
self.__bulletin_test_worker = None
|
||||||
elapsed_ms = (time.monotonic() - self.__bulletin_test_t0) * 1000
|
elapsed_ms = (time.monotonic() - self.__bulletin_test_t0) * 1000
|
||||||
@@ -515,17 +517,18 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
|||||||
QTimer.singleShot(3000, self, self.clearBulletinTestStatus)
|
QTimer.singleShot(3000, self, self.clearBulletinTestStatus)
|
||||||
|
|
||||||
@Slot(str)
|
@Slot(str)
|
||||||
def onBulletinTestError(
|
def onBulletinTestFinishedWithError(
|
||||||
self,
|
self,
|
||||||
error_message: str
|
error_message: str
|
||||||
):
|
):
|
||||||
|
|
||||||
self.__bulletin_test_worker.fetchWorkerIsFinished.disconnect(
|
self.__bulletin_test_worker.fetchWorkerIsFinished.disconnect(
|
||||||
self.onBulletinTestFetched
|
self.onBulletinTestIsFinished
|
||||||
)
|
)
|
||||||
self.__bulletin_test_worker.fetchWorkerFinishedWithError.disconnect(
|
self.__bulletin_test_worker.fetchWorkerFinishedWithError.disconnect(
|
||||||
self.onBulletinTestError
|
self.onBulletinTestFinishedWithError
|
||||||
)
|
)
|
||||||
|
self.__bulletin_test_worker.wait(3000)
|
||||||
self.__bulletin_test_worker.deleteLater()
|
self.__bulletin_test_worker.deleteLater()
|
||||||
self.__bulletin_test_worker = None
|
self.__bulletin_test_worker = None
|
||||||
self.BulletinTestStatusLabel.setText(f"连接失败:{error_message}")
|
self.BulletinTestStatusLabel.setText(f"连接失败:{error_message}")
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
workflow process. Do not edit manually.
|
workflow process. Do not edit manually.
|
||||||
|
|
||||||
This file is auto-generated during the workflow process.
|
This file is auto-generated during the workflow process.
|
||||||
Last updated: 2026-05-09 06:05:13 UTC
|
Last updated: 2026-07-14 02:19:31 UTC
|
||||||
"""
|
"""
|
||||||
|
|
||||||
AL_VERSION = "1.3.0"
|
AL_VERSION = "1.4.0"
|
||||||
AL_TAG = "v1.3.0"
|
AL_TAG = "v1.4.0"
|
||||||
AL_COMMIT_SHA = "local"
|
AL_COMMIT_SHA = "local"
|
||||||
AL_COMMIT_DATE = "null" # time zone : UTC
|
AL_COMMIT_DATE = "null" # time zone : UTC
|
||||||
AL_BUILD_DATE = "null" # time zone : UTC
|
AL_BUILD_DATE = "null" # time zone : UTC
|
||||||
|
|||||||
@@ -286,6 +286,7 @@ font: 700 9pt;</string>
|
|||||||
<string>工具</string>
|
<string>工具</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="SettingsAction"/>
|
<addaction name="SettingsAction"/>
|
||||||
|
<addaction name="BulletinAction"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="HelpMenu">
|
<widget class="QMenu" name="HelpMenu">
|
||||||
<property name="mouseTracking">
|
<property name="mouseTracking">
|
||||||
@@ -295,6 +296,7 @@ font: 700 9pt;</string>
|
|||||||
<string>帮助</string>
|
<string>帮助</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="ManualAction"/>
|
<addaction name="ManualAction"/>
|
||||||
|
<addaction name="CheckUpdateAction"/>
|
||||||
<addaction name="AboutAction"/>
|
<addaction name="AboutAction"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="ToolsMenu"/>
|
<addaction name="ToolsMenu"/>
|
||||||
@@ -310,6 +312,11 @@ font: 700 9pt;</string>
|
|||||||
<string>在线手册</string>
|
<string>在线手册</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="CheckUpdateAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>检查更新</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
<action name="AboutAction">
|
<action name="AboutAction">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>关于</string>
|
<string>关于</string>
|
||||||
@@ -320,6 +327,11 @@ font: 700 9pt;</string>
|
|||||||
<string>全局设置</string>
|
<string>全局设置</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="BulletinAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>公告栏</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|||||||
@@ -113,6 +113,9 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="PageStack">
|
<widget class="QStackedWidget" name="PageStack">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<widget class="QScrollArea" name="AppearanceScrollArea">
|
<widget class="QScrollArea" name="AppearanceScrollArea">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::Shape::NoFrame</enum>
|
<enum>QFrame::Shape::NoFrame</enum>
|
||||||
@@ -458,8 +461,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>397</width>
|
<width>409</width>
|
||||||
<height>434</height>
|
<height>383</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="BulletinPageLayout">
|
<layout class="QVBoxLayout" name="BulletinPageLayout">
|
||||||
@@ -577,15 +580,15 @@
|
|||||||
<height>25</height>
|
<height>25</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> 分钟</string>
|
||||||
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>1440</number>
|
<number>1440</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="suffix">
|
|
||||||
<string> 分钟</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -624,6 +627,18 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="BulletinTestStatusLabel">
|
<widget class="QLabel" name="BulletinTestStatusLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from pages.strategies.TimeSelectMaker import TimeSelectMaker
|
|||||||
from pages.ReserveView import ReserveView
|
from pages.ReserveView import ReserveView
|
||||||
from pages.components.ReserveResultDialog import ReserveResultDialog
|
from pages.components.ReserveResultDialog import ReserveResultDialog
|
||||||
from pages.components.TimeSelectDialog import TimeSelectDialog
|
from pages.components.TimeSelectDialog import TimeSelectDialog
|
||||||
|
from pages.components.SeatMapDialog import SeatMapDialog
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -150,7 +151,7 @@ class ReserveFlow(MsgBase):
|
|||||||
def _selectSeatAndSubmit(
|
def _selectSeatAndSubmit(
|
||||||
self,
|
self,
|
||||||
view: ReserveView,
|
view: ReserveView,
|
||||||
seat_map,
|
seat_map: SeatMapDialog,
|
||||||
ctx: ReserveContext,
|
ctx: ReserveContext,
|
||||||
) -> tuple[bool, bool]:
|
) -> tuple[bool, bool]:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user