mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-06-18 07:23:03 +08:00
feat(gui): breaking changes - Timer Task Management
1. we add menu actions 'manual' and 'about', so you can click actions to open manual and about dialog. 2. we introduce timer task management feature, so you can add, delete timer tasks to auto run task. 3. other style improvement in gui...
This commit is contained in:
@@ -14,4 +14,8 @@ src/gui/AutoLibraryResources.py
|
|||||||
src/gui/AutoLibraryResource.py
|
src/gui/AutoLibraryResource.py
|
||||||
src/gui/Ui_ALMainWindow.py
|
src/gui/Ui_ALMainWindow.py
|
||||||
src/gui/Ui_ALConfigWidget.py
|
src/gui/Ui_ALConfigWidget.py
|
||||||
|
src/gui/Ui_ALTimerTaskWidget.py
|
||||||
|
src/gui/Ui_ALAddTimerTaskDialog.py
|
||||||
|
src/gui/Ui_ALAboutDialog.py
|
||||||
|
|
||||||
Main.spec
|
Main.spec
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Copyright (c) 2025 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 sys
|
||||||
|
import platform
|
||||||
|
|
||||||
|
from PySide6.QtGui import (
|
||||||
|
QIcon
|
||||||
|
)
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QDialog, QApplication
|
||||||
|
)
|
||||||
|
from PySide6.QtCore import (
|
||||||
|
QTimer, Qt
|
||||||
|
)
|
||||||
|
|
||||||
|
from gui.AppInfo import AL_VERSION
|
||||||
|
from gui.Ui_ALAboutDialog import Ui_ALAboutDialog
|
||||||
|
|
||||||
|
from gui import AutoLibraryResource
|
||||||
|
|
||||||
|
|
||||||
|
class ALAboutDialog(QDialog, Ui_ALAboutDialog):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent=None
|
||||||
|
):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.setupUi(self)
|
||||||
|
self.modifyUi()
|
||||||
|
self.connectSignals()
|
||||||
|
|
||||||
|
|
||||||
|
def modifyUi(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.LogoIconLabel.setPixmap(QIcon(":/res/icon/icons/AutoLibrary.ico").pixmap(48, 48))
|
||||||
|
info_text = self.generateAboutText()
|
||||||
|
self.AboutInfoEdit.setHtml(info_text)
|
||||||
|
self.AboutInfoEdit.setTextInteractionFlags(Qt.TextBrowserInteraction)
|
||||||
|
|
||||||
|
|
||||||
|
def connectSignals(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.CopyButton.clicked.connect(self.copyAboutInfo)
|
||||||
|
|
||||||
|
|
||||||
|
def generateAboutText(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
os_info = self.getOSInfo()
|
||||||
|
about_text = f"""
|
||||||
|
<h4>Version Information:</h4>
|
||||||
|
Version: {AL_VERSION}<br>
|
||||||
|
Python version: {platform.python_version()}<br>
|
||||||
|
Qt version: {self.getQtVersion()}<br>
|
||||||
|
|
||||||
|
<h4>Author Information:</h4>
|
||||||
|
Developer: KenanZhu<br>
|
||||||
|
Contact: nanoki_zh@163.com<br>
|
||||||
|
GitHub: <a href="https://www.github.com/KenanZhu" style="text-decoration: none;">https://www.github.com/KenanZhu</a><br>
|
||||||
|
|
||||||
|
<h4>Project Information:</h4>
|
||||||
|
License: MIT License<br>
|
||||||
|
Project repository: <a href="https://www.github.com/KenanZhu/AutoLibrary" style="text-decoration: none;">https://www.github.com/KenanZhu/AutoLibrary</a><br>
|
||||||
|
Project website: <a href="https://www.autolibrary.cv/" style="text-decoration: none;">https://www.autolibrary.cv/</a><br>
|
||||||
|
|
||||||
|
<h4>System Information:</h4>
|
||||||
|
Processor: {platform.processor()}<br>
|
||||||
|
Operating system: {os_info['system']}<br>
|
||||||
|
System version: {os_info['version']}<br>
|
||||||
|
System architecture: {os_info['architecture']}<br>
|
||||||
|
"""
|
||||||
|
return about_text
|
||||||
|
|
||||||
|
|
||||||
|
def getOSInfo(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
system = platform.system()
|
||||||
|
version = platform.version()
|
||||||
|
architecture = platform.architecture()[0]
|
||||||
|
|
||||||
|
if system == "Windows":
|
||||||
|
try:
|
||||||
|
version = platform.win32_ver()[1]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
elif system == "Darwin":
|
||||||
|
try:
|
||||||
|
version = platform.mac_ver()[0]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
elif system == "Linux":
|
||||||
|
try:
|
||||||
|
import distro # try to get Linux distro info
|
||||||
|
version = f"{distro.name()} {distro.version()}"
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {
|
||||||
|
'system': system,
|
||||||
|
'version': version,
|
||||||
|
'architecture': architecture
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def getQtVersion(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
try:
|
||||||
|
from PySide6.QtCore import qVersion
|
||||||
|
return qVersion()
|
||||||
|
except:
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
|
||||||
|
def copyAboutInfo(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
about_text = self.AboutInfoEdit.toPlainText()
|
||||||
|
clipboard = QApplication.clipboard()
|
||||||
|
clipboard.setText(about_text)
|
||||||
|
original_text = self.CopyButton.text()
|
||||||
|
self.CopyButton.setText("已复制")
|
||||||
|
QTimer.singleShot(2000, lambda: self.CopyButton.setText(original_text))
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ALAboutDialog</class>
|
||||||
|
<widget class="QDialog" name="ALAboutDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>300</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>300</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>800</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>关于 - AutoLibrary</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="ALAboutDialogLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="LogoLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="LogoIconLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>56</width>
|
||||||
|
<height>56</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>56</width>
|
||||||
|
<height>56</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="indent">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="LogoTextLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>24</pointsize>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>AutoLibrary</string>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="indent">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="AboutInfoEdit">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Courier New</family>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="lineWrapMode">
|
||||||
|
<enum>QTextEdit::LineWrapMode::NoWrap</enum>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="CopyButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>复制</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Copyright (c) 2025 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 os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import uuid
|
||||||
|
import queue
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from PySide6.QtCore import (
|
||||||
|
Qt, Signal, Slot, QDateTime
|
||||||
|
)
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QLabel, QDialog, QWidget, QSpinBox, QVBoxLayout,
|
||||||
|
QHBoxLayout, QGridLayout, QDateTimeEdit
|
||||||
|
)
|
||||||
|
from PySide6.QtGui import (
|
||||||
|
QCloseEvent
|
||||||
|
)
|
||||||
|
|
||||||
|
from gui.Ui_ALAddTimerTaskDialog import Ui_ALAddTimerTaskDialog
|
||||||
|
|
||||||
|
|
||||||
|
class TimerTaskStatus(Enum):
|
||||||
|
PENDING = "等待中"
|
||||||
|
READY = "已就绪"
|
||||||
|
RUNNING = "执行中"
|
||||||
|
EXECUTED = "已执行"
|
||||||
|
OUTDATED = "已过期"
|
||||||
|
|
||||||
|
|
||||||
|
class ALAddTimerTaskWidget(QDialog, Ui_ALAddTimerTaskDialog):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent = None
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.setupUi(self)
|
||||||
|
self.connectSignals()
|
||||||
|
self.modifyUi()
|
||||||
|
|
||||||
|
|
||||||
|
def modifyUi(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.TimerTypeComboBox.setCurrentIndex(0)
|
||||||
|
self.SpecificTimerWidget = QWidget()
|
||||||
|
self.SpecificTimerLayout = QHBoxLayout(self.SpecificTimerWidget)
|
||||||
|
self.SpecificTimerLayout.addWidget(QLabel("定时时间:"))
|
||||||
|
self.SpecificDateTimeEdit = QDateTimeEdit()
|
||||||
|
self.SpecificDateTimeEdit.setCalendarPopup(True)
|
||||||
|
self.SpecificDateTimeEdit.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
|
||||||
|
self.SpecificDateTimeEdit.setMinimumDateTime(QDateTime.currentDateTime())
|
||||||
|
self.SpecificDateTimeEdit.setDateTime(QDateTime.currentDateTime().addSecs(60))
|
||||||
|
self.SpecificTimerLayout.addWidget(self.SpecificDateTimeEdit)
|
||||||
|
self.TimerConfigLayout.addWidget(self.SpecificTimerWidget)
|
||||||
|
|
||||||
|
self.RelativeTimerWidget = QWidget()
|
||||||
|
self.RelativeTimerLayout = QGridLayout(self.RelativeTimerWidget)
|
||||||
|
self.RelativeTimerLayout.addWidget(QLabel("相对时间:"), 0, 0)
|
||||||
|
self.RelativeDaySpinBox = QSpinBox()
|
||||||
|
self.RelativeDaySpinBox.setMinimum(0)
|
||||||
|
self.RelativeDaySpinBox.setMaximum(365)
|
||||||
|
self.RelativeDaySpinBox.setSuffix("天")
|
||||||
|
self.RelativeTimerLayout.addWidget(self.RelativeDaySpinBox, 1, 0)
|
||||||
|
self.RelativeHourSpinBox = QSpinBox()
|
||||||
|
self.RelativeHourSpinBox.setMinimum(0)
|
||||||
|
self.RelativeHourSpinBox.setMaximum(23)
|
||||||
|
self.RelativeHourSpinBox.setSuffix("时")
|
||||||
|
self.RelativeTimerLayout.addWidget(self.RelativeHourSpinBox, 1, 1)
|
||||||
|
self.RelativeMinuteSpinBox = QSpinBox()
|
||||||
|
self.RelativeMinuteSpinBox.setMinimum(0)
|
||||||
|
self.RelativeMinuteSpinBox.setMaximum(59)
|
||||||
|
self.RelativeMinuteSpinBox.setSuffix("分")
|
||||||
|
self.RelativeTimerLayout.addWidget(self.RelativeMinuteSpinBox, 1, 2)
|
||||||
|
self.RelativeSecondSpinBox = QSpinBox()
|
||||||
|
self.RelativeSecondSpinBox.setMinimum(0)
|
||||||
|
self.RelativeSecondSpinBox.setMaximum(59)
|
||||||
|
self.RelativeSecondSpinBox.setSuffix("秒")
|
||||||
|
self.RelativeTimerLayout.addWidget(self.RelativeSecondSpinBox, 1, 3)
|
||||||
|
self.TimerConfigLayout.addWidget(self.RelativeTimerWidget)
|
||||||
|
self.RelativeTimerWidget.setVisible(False)
|
||||||
|
|
||||||
|
|
||||||
|
def connectSignals(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.CancelButton.clicked.connect(self.reject)
|
||||||
|
self.ConfirmButton.clicked.connect(self.accept)
|
||||||
|
self.TimerTypeComboBox.currentIndexChanged.connect(self.onTimerTypeComboBoxIndexChanged)
|
||||||
|
|
||||||
|
|
||||||
|
def getTimerTask(
|
||||||
|
self
|
||||||
|
) -> dict:
|
||||||
|
|
||||||
|
added_time = datetime.now()
|
||||||
|
if not self.TaskNameLineEdit.text():
|
||||||
|
name = f"未命名任务-{added_time.strftime("%Y%m%d%H%M%S")}"
|
||||||
|
else:
|
||||||
|
name = self.TaskNameLineEdit.text()
|
||||||
|
timer_type_index = self.TimerTypeComboBox.currentIndex()
|
||||||
|
silent = not self.ShowBeforeRunRadioButton.isChecked()
|
||||||
|
if timer_type_index == 0:
|
||||||
|
execute_time = self.SpecificDateTimeEdit.dateTime()
|
||||||
|
tmp_time_str = execute_time.toString("yyyy-MM-dd HH:mm:ss")
|
||||||
|
execute_time = datetime.strptime(tmp_time_str, "%Y-%m-%d %H:%M:%S")
|
||||||
|
else:
|
||||||
|
execute_time = datetime.now() + timedelta(
|
||||||
|
days = self.RelativeDaySpinBox.value(),
|
||||||
|
hours = self.RelativeHourSpinBox.value(),
|
||||||
|
minutes = self.RelativeMinuteSpinBox.value(),
|
||||||
|
seconds = self.RelativeSecondSpinBox.value()
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"task_uuid": uuid.uuid4().hex.upper() + f"-{added_time.strftime("%Y%m%d%H%M%S")}",
|
||||||
|
"time_type": self.TimerTypeComboBox.currentText(),
|
||||||
|
"execute_time": execute_time,
|
||||||
|
"silent": silent,
|
||||||
|
"add_time": added_time,
|
||||||
|
"status": TimerTaskStatus.PENDING,
|
||||||
|
"executed": False
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Slot(int)
|
||||||
|
def onTimerTypeComboBoxIndexChanged(
|
||||||
|
self,
|
||||||
|
index: int
|
||||||
|
):
|
||||||
|
|
||||||
|
self.SpecificTimerWidget.setVisible(index == 0)
|
||||||
|
self.RelativeTimerWidget.setVisible(index == 1)
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ALAddTimerTaskDialog</class>
|
||||||
|
<widget class="QDialog" name="ALAddTimerTaskDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>300</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>500</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>添加定时任务 - AutoLibrary</string>
|
||||||
|
</property>
|
||||||
|
<property name="sizeGripEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="ALAddTimerTaskLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="TaskNameLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="TaskNameLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>任务名称:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="TaskNameLineEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="TimerConfigGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>定时设置</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="TimerConfigLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="TimerTypeSelectLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="TimerTypeLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>定时类型:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="TimerTypeComboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>特定时间</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>相对时间</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="TaskConfigGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>运行设置</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="TaskConfigLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="SilentlyRunRadioButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>静默运行</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoRepeat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoExclusive">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="ShowBeforeRunRadioButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>运行前提示</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="ControLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="ControlSpaceFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Shape::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Shadow::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="CancelButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>取消</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="ConfirmButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>添加</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -1829,6 +1829,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>导出配置文件</string>
|
<string>导出配置文件</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-save"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -1924,6 +1927,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>新建配置</string>
|
<string>新建配置</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-new"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -1943,6 +1949,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>加载配置</string>
|
<string>加载配置</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-open"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
+231
-14
@@ -13,19 +13,21 @@ import time
|
|||||||
import queue
|
import queue
|
||||||
|
|
||||||
from PySide6.QtCore import (
|
from PySide6.QtCore import (
|
||||||
Qt, Signal, Slot, QDir, QFileInfo, QTimer, QThread
|
Qt, Signal, Slot, QDir, QFileInfo, QTimer, QThread, QUrl,
|
||||||
)
|
)
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QMainWindow, QMenu
|
QMainWindow, QMenu, QSystemTrayIcon
|
||||||
)
|
)
|
||||||
from PySide6.QtGui import (
|
from PySide6.QtGui import (
|
||||||
QTextCursor, QCloseEvent, QFont, QIcon
|
QTextCursor, QCloseEvent, QFont, QIcon, QDesktopServices
|
||||||
)
|
)
|
||||||
|
|
||||||
from .Ui_ALMainWindow import Ui_ALMainWindow
|
from gui.Ui_ALMainWindow import Ui_ALMainWindow
|
||||||
from .ALConfigWidget import ALConfigWidget
|
from gui.ALConfigWidget import ALConfigWidget
|
||||||
|
from gui.ALTimerTaskWidget import ALTimerTaskWidget
|
||||||
|
from gui.ALAboutDialog import ALAboutDialog
|
||||||
|
|
||||||
from . import AutoLibraryResource
|
from gui import AutoLibraryResource
|
||||||
|
|
||||||
from operators.AutoLib import AutoLib
|
from operators.AutoLib import AutoLib
|
||||||
from utils.ConfigReader import ConfigReader
|
from utils.ConfigReader import ConfigReader
|
||||||
@@ -49,7 +51,6 @@ class AutoLibWorker(QThread):
|
|||||||
self.__input_queue = input_queue
|
self.__input_queue = input_queue
|
||||||
self.__output_queue = output_queue
|
self.__output_queue = output_queue
|
||||||
self.__config_paths = config_paths
|
self.__config_paths = config_paths
|
||||||
self.__stopped = False
|
|
||||||
|
|
||||||
|
|
||||||
def checkTimeAvailable(
|
def checkTimeAvailable(
|
||||||
@@ -110,15 +111,46 @@ class AutoLibWorker(QThread):
|
|||||||
self.finishedSignal.emit()
|
self.finishedSignal.emit()
|
||||||
|
|
||||||
|
|
||||||
def stop(
|
class TimerTaskWorker(AutoLibWorker):
|
||||||
|
|
||||||
|
finishedSignal_TimerWorker = Signal(dict)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
timer_task: dict,
|
||||||
|
input_queue: queue.Queue,
|
||||||
|
output_queue: queue.Queue,
|
||||||
|
config_paths: dict
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
input_queue,
|
||||||
|
output_queue,
|
||||||
|
config_paths,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.__timer_task = timer_task
|
||||||
|
self.__stopped = False
|
||||||
|
|
||||||
|
def run(
|
||||||
self
|
self
|
||||||
):
|
):
|
||||||
|
|
||||||
self.__stopped = True
|
self.showTraceSignal.emit(
|
||||||
|
f"定时任务 {self.__timer_task['name']} 开始运行"
|
||||||
|
)
|
||||||
|
super().run()
|
||||||
|
self.showTraceSignal.emit(
|
||||||
|
f"定时任务 {self.__timer_task['name']} 运行结束"
|
||||||
|
)
|
||||||
|
self.finishedSignal_TimerWorker.emit(self.__timer_task)
|
||||||
|
|
||||||
|
|
||||||
class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
||||||
|
|
||||||
|
timerTaskIsRunning = Signal(dict)
|
||||||
|
timerTaskIsExecuted = Signal(dict)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self
|
self
|
||||||
):
|
):
|
||||||
@@ -129,27 +161,100 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.__input_queue = queue.Queue()
|
self.__input_queue = queue.Queue()
|
||||||
self.__output_queue = queue.Queue()
|
self.__output_queue = queue.Queue()
|
||||||
|
self.__timer_task_queue = queue.Queue()
|
||||||
script_path = sys.executable
|
script_path = sys.executable
|
||||||
script_dir = QFileInfo(script_path).absoluteDir()
|
script_dir = QFileInfo(script_path).absoluteDir()
|
||||||
self.__config_paths = {
|
self.__config_paths = {
|
||||||
"system": QDir.toNativeSeparators(script_dir.absoluteFilePath("system.json")),
|
"system": QDir.toNativeSeparators(script_dir.absoluteFilePath("system.json")),
|
||||||
"users": QDir.toNativeSeparators(script_dir.absoluteFilePath("users.json")),
|
"users": QDir.toNativeSeparators(script_dir.absoluteFilePath("users.json")),
|
||||||
}
|
}
|
||||||
|
self.__alTimerTaskWidget = None
|
||||||
self.__alConfigWidget = None
|
self.__alConfigWidget = None
|
||||||
|
self.__alAboutDialog = None
|
||||||
self.__auto_lib_thread = None
|
self.__auto_lib_thread = None
|
||||||
|
self.__current_timer_task_thread = None
|
||||||
|
self.__is_running_timer_task = False
|
||||||
|
|
||||||
self.modifyUi()
|
self.modifyUi()
|
||||||
|
self.setupTray()
|
||||||
self.connectSignals()
|
self.connectSignals()
|
||||||
self.startMsgPolling()
|
self.startMsgPolling()
|
||||||
|
self.startTimerTaskPolling()
|
||||||
|
|
||||||
|
|
||||||
def modifyUi(
|
def modifyUi(
|
||||||
self
|
self
|
||||||
):
|
):
|
||||||
|
|
||||||
icon = QIcon(":/res/icon/icons/AutoLibrary.ico")
|
self.icon = QIcon(":/res/icon/icons/AutoLibrary.ico")
|
||||||
self.setWindowIcon(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.AboutAction.triggered.connect(self.onAboutActionTriggered)
|
||||||
|
|
||||||
|
|
||||||
|
def onAboutActionTriggered(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
if self.__alAboutDialog is None:
|
||||||
|
self.__alAboutDialog = ALAboutDialog(self)
|
||||||
|
self.__alAboutDialog.show()
|
||||||
|
|
||||||
|
|
||||||
|
def onManualActionTriggered(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
url = QUrl("https://www.autolibrary.cv/docs/manual_lists.html")
|
||||||
|
QDesktopServices.openUrl(url)
|
||||||
|
|
||||||
|
|
||||||
|
def setupTray(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
if not QSystemTrayIcon.isSystemTrayAvailable():
|
||||||
|
self.showTraceSignal.emit(
|
||||||
|
"系统不支持系统托盘功能, 无法创建系统托盘图标。"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
self.TrayIcon = QSystemTrayIcon(self.icon, self)
|
||||||
|
self.TrayIcon.setToolTip("AutoLibrary")
|
||||||
|
|
||||||
|
self.TrayMenu = QMenu()
|
||||||
|
self.TrayMenu.addAction("显示主窗口", self.showNormal)
|
||||||
|
self.TrayMenu.addAction("显示定时窗口", self.onTimerTaskWidgetButtonClicked)
|
||||||
|
self.TrayMenu.addAction("最小化到托盘", self.hideToTray)
|
||||||
|
self.TrayMenu.addSeparator()
|
||||||
|
self.TrayMenu.addAction("退出", self.close)
|
||||||
|
self.TrayIcon.setContextMenu(self.TrayMenu)
|
||||||
|
|
||||||
|
self.TrayIcon.setContextMenu(self.TrayMenu)
|
||||||
|
self.TrayIcon.activated.connect(self.onTrayIconActivated)
|
||||||
|
self.TrayIcon.show()
|
||||||
|
|
||||||
|
|
||||||
|
def hideToTray(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.hide()
|
||||||
|
self.TrayIcon.showMessage(
|
||||||
|
"AutoLibrary",
|
||||||
|
"\n已最小化到托盘",
|
||||||
|
QSystemTrayIcon.MessageIcon.Information,
|
||||||
|
2000
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def onTrayIconActivated(
|
||||||
|
self,
|
||||||
|
reason: QSystemTrayIcon.ActivationReason
|
||||||
|
):
|
||||||
|
|
||||||
|
if reason == QSystemTrayIcon.DoubleClick:
|
||||||
|
self.showNormal()
|
||||||
|
|
||||||
|
|
||||||
def connectSignals(
|
def connectSignals(
|
||||||
@@ -157,6 +262,7 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
):
|
):
|
||||||
|
|
||||||
self.ConfigButton.clicked.connect(self.onConfigButtonClicked)
|
self.ConfigButton.clicked.connect(self.onConfigButtonClicked)
|
||||||
|
self.TimerTaskWidgetButton.clicked.connect(self.onTimerTaskWidgetButtonClicked)
|
||||||
self.StartButton.clicked.connect(self.onStartButtonClicked)
|
self.StartButton.clicked.connect(self.onStartButtonClicked)
|
||||||
self.StopButton.clicked.connect(self.onStopButtonClicked)
|
self.StopButton.clicked.connect(self.onStopButtonClicked)
|
||||||
self.SendButton.clicked.connect(self.onSendButtonClicked)
|
self.SendButton.clicked.connect(self.onSendButtonClicked)
|
||||||
@@ -170,8 +276,17 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
|
|
||||||
if self.__timer and self.__timer.isActive():
|
if self.__timer and self.__timer.isActive():
|
||||||
self.__timer.stop()
|
self.__timer.stop()
|
||||||
|
if self.__timer_task_timer and self.__timer_task_timer.isActive():
|
||||||
|
self.__timer_task_timer.stop()
|
||||||
|
if self.__is_running_timer_task:
|
||||||
|
self.__current_timer_task_thread.wait(2000)
|
||||||
|
self.__current_timer_task_thread.deleteLater()
|
||||||
|
if self.__alTimerTaskWidget:
|
||||||
|
self.__alTimerTaskWidget.close()
|
||||||
|
self.__alTimerTaskWidget.deleteLater()
|
||||||
if self.__alConfigWidget:
|
if self.__alConfigWidget:
|
||||||
self.__alConfigWidget.close()
|
self.__alConfigWidget.close()
|
||||||
|
self.__alConfigWidget.deleteLater()
|
||||||
super().closeEvent(event)
|
super().closeEvent(event)
|
||||||
|
|
||||||
|
|
||||||
@@ -198,6 +313,51 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
self.__timer.start(100)
|
self.__timer.start(100)
|
||||||
|
|
||||||
|
|
||||||
|
def startTimerTaskPolling(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.__timer_task_timer = QTimer()
|
||||||
|
self.__timer_task_timer.timeout.connect(self.pollTimerTaskQueue)
|
||||||
|
self.__timer_task_timer.start(500)
|
||||||
|
|
||||||
|
|
||||||
|
def pollTimerTaskQueue(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
if self.__is_running_timer_task:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
while not self.__is_running_timer_task:
|
||||||
|
timer_task = self.__timer_task_queue.get_nowait()
|
||||||
|
self.timerTaskIsRunning.emit(timer_task)
|
||||||
|
self.__timer_task_timer.stop()
|
||||||
|
self.__is_running_timer_task = True
|
||||||
|
self.setControlButtons(False, False, True)
|
||||||
|
if not timer_task["silent"]:
|
||||||
|
self.TrayIcon.showMessage(
|
||||||
|
"定时任务 - AutoLibrary",
|
||||||
|
f"\n已开始执行定时任务: \n{timer_task['name']}",
|
||||||
|
QSystemTrayIcon.MessageIcon.Information,
|
||||||
|
1000
|
||||||
|
)
|
||||||
|
self.showNormal()
|
||||||
|
self.__current_timer_task_thread = TimerTaskWorker(
|
||||||
|
timer_task,
|
||||||
|
self.__input_queue,
|
||||||
|
self.__output_queue,
|
||||||
|
self.__config_paths
|
||||||
|
)
|
||||||
|
self.__current_timer_task_thread.finishedSignal_TimerWorker.connect(self.onTimerTaskFinished)
|
||||||
|
self.__current_timer_task_thread.showTraceSignal.connect(self.showTrace)
|
||||||
|
self.__current_timer_task_thread.showMsgSignal.connect(self.showMsg)
|
||||||
|
self.__current_timer_task_thread.start()
|
||||||
|
except queue.Empty:
|
||||||
|
self.__is_running_timer_task = False
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def setControlButtons(
|
def setControlButtons(
|
||||||
self,
|
self,
|
||||||
config_button_enabled: bool,
|
config_button_enabled: bool,
|
||||||
@@ -238,6 +398,15 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onTimerTaskWidgetClosed(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.TimerTaskWidgetButton.setEnabled(True)
|
||||||
|
|
||||||
|
|
||||||
@Slot(dict)
|
@Slot(dict)
|
||||||
def onConfigWidgetClosed(
|
def onConfigWidgetClosed(
|
||||||
self,
|
self,
|
||||||
@@ -253,6 +422,55 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
self.StopButton.setEnabled(False)
|
self.StopButton.setEnabled(False)
|
||||||
self.__config_paths = config_paths
|
self.__config_paths = config_paths
|
||||||
|
|
||||||
|
@Slot(dict)
|
||||||
|
def onTimerTaskReady(
|
||||||
|
self,
|
||||||
|
timer_task: dict
|
||||||
|
):
|
||||||
|
|
||||||
|
self.__timer_task_queue.put(timer_task)
|
||||||
|
|
||||||
|
@Slot(dict)
|
||||||
|
def onTimerTaskFinished(
|
||||||
|
self,
|
||||||
|
timer_task: dict
|
||||||
|
):
|
||||||
|
|
||||||
|
self.__current_timer_task_thread.wait(1000)
|
||||||
|
self.__current_timer_task_thread.finishedSignal_TimerWorker.disconnect(self.onTimerTaskFinished)
|
||||||
|
self.__current_timer_task_thread.showTraceSignal.disconnect(self.showTrace)
|
||||||
|
self.__current_timer_task_thread.showMsgSignal.disconnect(self.showMsg)
|
||||||
|
self.__current_timer_task_thread.deleteLater()
|
||||||
|
self.__current_timer_task_thread = None
|
||||||
|
self.setControlButtons(True, True, False)
|
||||||
|
self.__is_running_timer_task = False
|
||||||
|
self.__timer_task_timer.start(500)
|
||||||
|
timer_task["executed"] = True
|
||||||
|
self.TrayIcon.showMessage(
|
||||||
|
"定时任务 - AutoLibrary",
|
||||||
|
f"\n定时任务 '{timer_task['name']}' 执行完成",
|
||||||
|
QSystemTrayIcon.MessageIcon.Information,
|
||||||
|
1000
|
||||||
|
)
|
||||||
|
self.showTrace(f"定时任务 {timer_task['name']} 执行完成, uuid: {timer_task['task_uuid']}")
|
||||||
|
self.timerTaskIsExecuted.emit(timer_task)
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onTimerTaskWidgetButtonClicked(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
if self.__alTimerTaskWidget is None:
|
||||||
|
self.__alTimerTaskWidget = ALTimerTaskWidget(self)
|
||||||
|
self.timerTaskIsRunning.connect(self.__alTimerTaskWidget.onTimerTaskIsRunning)
|
||||||
|
self.timerTaskIsExecuted.connect(self.__alTimerTaskWidget.onTimerTaskIsExecuted)
|
||||||
|
self.__alTimerTaskWidget.timerTaskReady.connect(self.onTimerTaskReady)
|
||||||
|
self.__alTimerTaskWidget.timerTaskWidgetClosed.connect(self.onTimerTaskWidgetClosed)
|
||||||
|
self.__alTimerTaskWidget.setWindowFlags(Qt.Window)
|
||||||
|
self.__alTimerTaskWidget.show()
|
||||||
|
self.__alTimerTaskWidget.raise_()
|
||||||
|
self.__alTimerTaskWidget.activateWindow()
|
||||||
|
self.TimerTaskWidgetButton.setEnabled(False)
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def onConfigButtonClicked(
|
def onConfigButtonClicked(
|
||||||
self
|
self
|
||||||
@@ -281,7 +499,7 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
self.__auto_lib_thread = AutoLibWorker(
|
self.__auto_lib_thread = AutoLibWorker(
|
||||||
self.__input_queue,
|
self.__input_queue,
|
||||||
self.__output_queue,
|
self.__output_queue,
|
||||||
self.__config_paths,
|
self.__config_paths
|
||||||
)
|
)
|
||||||
self.__auto_lib_thread.finishedSignal.connect(self.onStopButtonClicked)
|
self.__auto_lib_thread.finishedSignal.connect(self.onStopButtonClicked)
|
||||||
self.__auto_lib_thread.showMsgSignal.connect(self.showMsg)
|
self.__auto_lib_thread.showMsgSignal.connect(self.showMsg)
|
||||||
@@ -295,8 +513,7 @@ class ALMainWindow(QMainWindow, Ui_ALMainWindow):
|
|||||||
|
|
||||||
if self.__auto_lib_thread:
|
if self.__auto_lib_thread:
|
||||||
self.showTrace("正在停止操作......")
|
self.showTrace("正在停止操作......")
|
||||||
self.__auto_lib_thread.stop()
|
self.__auto_lib_thread.wait(2000)
|
||||||
self.__auto_lib_thread.wait()
|
|
||||||
self.showTrace("操作已停止")
|
self.showTrace("操作已停止")
|
||||||
self.__auto_lib_thread.showMsgSignal.disconnect(self.showMsg)
|
self.__auto_lib_thread.showMsgSignal.disconnect(self.showMsg)
|
||||||
self.__auto_lib_thread.showTraceSignal.disconnect(self.showTrace)
|
self.__auto_lib_thread.showTraceSignal.disconnect(self.showTrace)
|
||||||
|
|||||||
+38
-2
@@ -50,11 +50,33 @@
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="TimerTaskWidgetButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>25</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>25</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-open-recent"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="ControlSpaceFrame">
|
<widget class="QFrame" name="ControlSpaceFrame">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>1280</width>
|
<width>1000</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@@ -237,6 +259,9 @@ font: 700 9pt "Microsoft YaHei UI";</string>
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>发送</string>
|
<string>发送</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-send"/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -245,7 +270,7 @@ font: 700 9pt "Microsoft YaHei UI";</string>
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="MenuBar">
|
<widget class="QMenuBar" name="MenuBar">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
@@ -258,6 +283,17 @@ font: 700 9pt "Microsoft YaHei UI";</string>
|
|||||||
<property name="nativeMenuBar">
|
<property name="nativeMenuBar">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="HelpMenu">
|
||||||
|
<property name="mouseTracking">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>帮助</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="ManualAction"/>
|
||||||
|
<addaction name="AboutAction"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="HelpMenu"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="StatusBar">
|
<widget class="QStatusBar" name="StatusBar">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
|
|||||||
@@ -0,0 +1,313 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Copyright (c) 2025 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 os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import queue
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from PySide6.QtCore import (
|
||||||
|
Qt, Signal, Slot, QTimer
|
||||||
|
)
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QDialog, QWidget, QListWidgetItem, QMessageBox,
|
||||||
|
QHBoxLayout, QVBoxLayout, QLabel, QPushButton
|
||||||
|
)
|
||||||
|
from PySide6.QtGui import (
|
||||||
|
QCloseEvent
|
||||||
|
)
|
||||||
|
|
||||||
|
from gui.Ui_ALTimerTaskWidget import Ui_ALTimerTaskWidget
|
||||||
|
from gui.ALAddTimerTaskDialog import ALAddTimerTaskWidget, TimerTaskStatus
|
||||||
|
|
||||||
|
|
||||||
|
class TimerTaskItemWidget(QWidget):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent = None,
|
||||||
|
timer_task: dict = None
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.__timer_task = timer_task
|
||||||
|
self.modifyUi()
|
||||||
|
|
||||||
|
|
||||||
|
def modifyUi(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.ItemWidgetLayout = QHBoxLayout(self)
|
||||||
|
self.ItemWidgetLayout.setSpacing(10)
|
||||||
|
self.ItemWidgetLayout.setContentsMargins(10, 5, 10, 5)
|
||||||
|
|
||||||
|
self.TaskInfoLayout = QVBoxLayout()
|
||||||
|
self.TaskInfoLayout.setSpacing(5)
|
||||||
|
TaskNameLabel = QLabel(self.__timer_task["name"])
|
||||||
|
TaskNameLabelFont = TaskNameLabel.font()
|
||||||
|
TaskNameLabelFont.setBold(True)
|
||||||
|
TaskNameLabel.setFont(TaskNameLabelFont)
|
||||||
|
TaskNameLabel.setFixedHeight(25)
|
||||||
|
self.TaskInfoLayout.addWidget(TaskNameLabel)
|
||||||
|
|
||||||
|
ExecuteTimeStr = self.__timer_task["execute_time"].strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
ExecuteTimeLabel = QLabel(f"执行时间: {ExecuteTimeStr}")
|
||||||
|
ExecuteTimeLabel.setStyleSheet("color: gray;")
|
||||||
|
ExecuteTimeLabel.setFixedHeight(20)
|
||||||
|
self.TaskInfoLayout.addWidget(ExecuteTimeLabel)
|
||||||
|
|
||||||
|
self.ItemWidgetLayout.addLayout(self.TaskInfoLayout)
|
||||||
|
self.ItemWidgetLayout.addStretch()
|
||||||
|
|
||||||
|
match self.__timer_task["status"]:
|
||||||
|
case TimerTaskStatus.PENDING:
|
||||||
|
TaskStatusText = "等待中"
|
||||||
|
TaskStatusColor = "#FF9800"
|
||||||
|
case TimerTaskStatus.READY:
|
||||||
|
TaskStatusText = "已就绪"
|
||||||
|
TaskStatusColor = "#316BFF"
|
||||||
|
case TimerTaskStatus.RUNNING:
|
||||||
|
TaskStatusText = "执行中"
|
||||||
|
TaskStatusColor = "#2294FF"
|
||||||
|
case TimerTaskStatus.EXECUTED:
|
||||||
|
TaskStatusText = "已执行"
|
||||||
|
TaskStatusColor = "#4CAF50"
|
||||||
|
case TimerTaskStatus.OUTDATED:
|
||||||
|
TaskStatusText = "已过期"
|
||||||
|
TaskStatusColor = "#FF5722"
|
||||||
|
TaskStatusLabel = QLabel(TaskStatusText)
|
||||||
|
TaskStatusLabel.setStyleSheet(f"""
|
||||||
|
QLabel {{
|
||||||
|
background-color: {TaskStatusColor};
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
TaskStatusLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
TaskStatusLabel.setFixedSize(80, 25)
|
||||||
|
self.ItemWidgetLayout.addWidget(TaskStatusLabel)
|
||||||
|
|
||||||
|
TaskModeText = "静默" if self.__timer_task["silent"] else "显示"
|
||||||
|
TaskModeColor = "#6325FF" if self.__timer_task["silent"] else "#2294FF"
|
||||||
|
TaskModeLabel = QLabel(TaskModeText)
|
||||||
|
TaskModeLabel.setStyleSheet(f"""
|
||||||
|
QLabel {{
|
||||||
|
background-color: {TaskModeColor};
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
TaskModeLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
TaskModeLabel.setFixedSize(60, 25)
|
||||||
|
self.ItemWidgetLayout.addWidget(TaskModeLabel)
|
||||||
|
|
||||||
|
self.DeleteButton = QPushButton("删除")
|
||||||
|
self.DeleteButton.setFixedSize(80, 25)
|
||||||
|
self.ItemWidgetLayout.addWidget(self.DeleteButton)
|
||||||
|
if self.__timer_task["status"] == TimerTaskStatus.READY\
|
||||||
|
or self.__timer_task["status"] == TimerTaskStatus.RUNNING:
|
||||||
|
self.DeleteButton.setEnabled(False)
|
||||||
|
self.setFixedHeight(55)
|
||||||
|
|
||||||
|
|
||||||
|
class ALTimerTaskWidget(QWidget, Ui_ALTimerTaskWidget):
|
||||||
|
|
||||||
|
timerTasksChanged = Signal(list)
|
||||||
|
timerTaskReady = Signal(dict)
|
||||||
|
timerTaskWidgetClosed = Signal()
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent = None
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.__timer_tasks = []
|
||||||
|
self.__check_timer = None
|
||||||
|
self.setupUi(self)
|
||||||
|
self.connectSignals()
|
||||||
|
self.setupTimer()
|
||||||
|
|
||||||
|
|
||||||
|
def setupTimer(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.__check_timer = QTimer(self)
|
||||||
|
self.__check_timer.timeout.connect(self.checkTasks)
|
||||||
|
self.__check_timer.start(500)
|
||||||
|
|
||||||
|
|
||||||
|
def connectSignals(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.AddTimerTaskButton.clicked.connect(self.addTask)
|
||||||
|
self.ClearAllTimerTasksButton.clicked.connect(self.clearAllTasks)
|
||||||
|
|
||||||
|
|
||||||
|
def closeEvent(
|
||||||
|
self,
|
||||||
|
event: QCloseEvent
|
||||||
|
):
|
||||||
|
|
||||||
|
self.hide()
|
||||||
|
self.timerTaskWidgetClosed.emit()
|
||||||
|
event.ignore()
|
||||||
|
|
||||||
|
|
||||||
|
def updateStat(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
pending = 0
|
||||||
|
in_queue = 0
|
||||||
|
executed = 0
|
||||||
|
total = len(self.__timer_tasks)
|
||||||
|
for timer_task in self.__timer_tasks:
|
||||||
|
if timer_task["status"] == TimerTaskStatus.PENDING:
|
||||||
|
pending += 1
|
||||||
|
elif timer_task["status"] == TimerTaskStatus.READY\
|
||||||
|
or timer_task["status"] == TimerTaskStatus.RUNNING:
|
||||||
|
in_queue += 1
|
||||||
|
elif timer_task["status"] == TimerTaskStatus.EXECUTED:
|
||||||
|
executed += 1
|
||||||
|
self.TotalTaskLabel.setText(f"总任务:{total}")
|
||||||
|
self.PendingTaskLabel.setText(f"待执行:{pending}")
|
||||||
|
self.InQueueTaskLabel.setText(f"队列中:{in_queue}")
|
||||||
|
self.ExecutedTaskLabel.setText(f"已执行:{executed}")
|
||||||
|
|
||||||
|
|
||||||
|
def updateTimerTaskList(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
self.TimerTasksListWidget.clear()
|
||||||
|
self.__timer_tasks.sort(
|
||||||
|
key = lambda x: x["execute_time"]
|
||||||
|
)
|
||||||
|
for timer_task in self.__timer_tasks:
|
||||||
|
item = QListWidgetItem()
|
||||||
|
item.setData(Qt.UserRole, timer_task)
|
||||||
|
widget = TimerTaskItemWidget(self, timer_task)
|
||||||
|
widget.DeleteButton.clicked.connect(
|
||||||
|
lambda _, uuid = timer_task["task_uuid"]: self.deleteTask(uuid)
|
||||||
|
)
|
||||||
|
item.setSizeHint(widget.size())
|
||||||
|
self.TimerTasksListWidget.addItem(item)
|
||||||
|
self.TimerTasksListWidget.setItemWidget(item, widget)
|
||||||
|
|
||||||
|
|
||||||
|
def addTask(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
dialog = ALAddTimerTaskWidget(self)
|
||||||
|
if dialog.exec() == QDialog.DialogCode.Accepted:
|
||||||
|
timer_task = dialog.getTimerTask()
|
||||||
|
self.__timer_tasks.append(timer_task)
|
||||||
|
self.updateTimerTaskList()
|
||||||
|
self.updateStat()
|
||||||
|
|
||||||
|
|
||||||
|
def deleteTask(
|
||||||
|
self,
|
||||||
|
task_uuid: str
|
||||||
|
):
|
||||||
|
|
||||||
|
self.__timer_tasks = [
|
||||||
|
x for x in self.__timer_tasks
|
||||||
|
if x["task_uuid"] != task_uuid
|
||||||
|
]
|
||||||
|
self.updateTimerTaskList()
|
||||||
|
self.updateStat()
|
||||||
|
|
||||||
|
|
||||||
|
def clearAllTasks(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
if not self.__timer_tasks:
|
||||||
|
return
|
||||||
|
result = QMessageBox.question(
|
||||||
|
self,
|
||||||
|
"确认 - AutoLibrary",
|
||||||
|
"是否要清除所有定时任务 ?",
|
||||||
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
||||||
|
)
|
||||||
|
if result is QMessageBox.StandardButton.No:
|
||||||
|
return
|
||||||
|
in_queue_tasks = [
|
||||||
|
x for x in self.__timer_tasks
|
||||||
|
if x["status"] == TimerTaskStatus.READY
|
||||||
|
or x["status"] == TimerTaskStatus.RUNNING
|
||||||
|
]
|
||||||
|
in_queue_count = len(in_queue_tasks)
|
||||||
|
if in_queue_count > 0:
|
||||||
|
QMessageBox.warning(
|
||||||
|
self,
|
||||||
|
"警告 - AutoLibrary",
|
||||||
|
"存在正在执行或已就绪的队列任务,无法清除所有定时任务 !"
|
||||||
|
)
|
||||||
|
self.__timer_tasks = in_queue_tasks
|
||||||
|
self.updateTimerTaskList()
|
||||||
|
self.updateStat()
|
||||||
|
|
||||||
|
|
||||||
|
def checkTasks(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
now = datetime.now()
|
||||||
|
for timer_task in self.__timer_tasks:
|
||||||
|
if timer_task["execute_time"] > now:
|
||||||
|
continue
|
||||||
|
if timer_task["status"] is not TimerTaskStatus.PENDING:
|
||||||
|
continue
|
||||||
|
if timer_task["execute_time"] <= now + timedelta(seconds = -5):
|
||||||
|
timer_task["status"] = TimerTaskStatus.OUTDATED
|
||||||
|
else:
|
||||||
|
timer_task["status"] = TimerTaskStatus.READY
|
||||||
|
self.timerTaskReady.emit(timer_task)
|
||||||
|
self.updateTimerTaskList()
|
||||||
|
self.updateStat()
|
||||||
|
|
||||||
|
|
||||||
|
@Slot(dict)
|
||||||
|
def onTimerTaskIsRunning(
|
||||||
|
self,
|
||||||
|
timer_task: dict
|
||||||
|
):
|
||||||
|
|
||||||
|
for task in self.__timer_tasks:
|
||||||
|
if task["task_uuid"] == timer_task["task_uuid"]:
|
||||||
|
task["status"] = TimerTaskStatus.RUNNING
|
||||||
|
self.updateTimerTaskList()
|
||||||
|
self.updateStat()
|
||||||
|
|
||||||
|
|
||||||
|
@Slot(dict)
|
||||||
|
def onTimerTaskIsExecuted(
|
||||||
|
self,
|
||||||
|
timer_task: dict
|
||||||
|
):
|
||||||
|
|
||||||
|
for task in self.__timer_tasks:
|
||||||
|
if task["task_uuid"] == timer_task["task_uuid"]:
|
||||||
|
task["status"] = TimerTaskStatus.EXECUTED
|
||||||
|
self.updateTimerTaskList()
|
||||||
|
self.updateStat()
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ALTimerTaskWidget</class>
|
||||||
|
<widget class="QWidget" name="ALTimerTaskWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>400</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>600</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>定时任务 - AutoLibrary</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="ALTimerTaskWidgetLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="TimerTaskStatusLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="TotalTaskLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>总任务:0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="PendingTaskLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QLabel {
|
||||||
|
color: #FF9800
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>待执行:0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="InQueueTaskLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QLabel {
|
||||||
|
color: #2294FF
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>队列中:0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="ExecutedTaskLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QLabel {
|
||||||
|
color: #4CAF50
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>已执行:0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="TimerTaskSpaceFrame">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>600</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Shape::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Shadow::Plain</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="TimerTasksListWidget">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="TimerTaskEditLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="ClearAllTimerTasksButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>清除全部</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="AddTimerTaskButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>添加任务</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="TimerTaskEditSpaceFrame">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Shape::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Shadow::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
AL_VERSION = "1.0.0-beta"
|
||||||
Reference in New Issue
Block a user