mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-06-17 23:13:03 +08:00
feat(gui): 新增 ALStatusLabel 状态标签组件和浏览器驱动下载对话框
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from PySide6.QtWidgets import (
|
||||
QLabel
|
||||
)
|
||||
from PySide6.QtCore import (
|
||||
Qt, Property, QPropertyAnimation, QEasingCurve
|
||||
)
|
||||
from PySide6.QtGui import (
|
||||
QPainter, QColor, QConicalGradient, QPalette
|
||||
)
|
||||
|
||||
|
||||
class ALStatusLabel(QLabel):
|
||||
|
||||
class Status(Enum):
|
||||
"""
|
||||
Enum class for representing the status of ALStatusLabel.
|
||||
"""
|
||||
|
||||
WAITING = 0
|
||||
RUNNING = 1
|
||||
SUCCESS = 2
|
||||
WARNING = 3
|
||||
FAILURE = 4
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent = None
|
||||
):
|
||||
|
||||
super().__init__(parent)
|
||||
self.__status = self.Status.WAITING
|
||||
self.__icon_angle = 0
|
||||
|
||||
self.setupUi()
|
||||
|
||||
|
||||
def setupUi(
|
||||
self
|
||||
):
|
||||
|
||||
self.setFixedSize(36, 36)
|
||||
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.RunningAnimation = QPropertyAnimation(self, b"iconAngle")
|
||||
self.RunningAnimation.setDuration(1000)
|
||||
self.RunningAnimation.setStartValue(0)
|
||||
self.RunningAnimation.setEndValue(-360)
|
||||
self.RunningAnimation.setLoopCount(-1)
|
||||
self.RunningAnimation.setEasingCurve(QEasingCurve.Type.Linear)
|
||||
|
||||
|
||||
def isDarkMode(
|
||||
self
|
||||
) -> bool:
|
||||
|
||||
return self.palette().color(QPalette.ColorRole.Window).value() < 128
|
||||
|
||||
|
||||
def getMarkColor(
|
||||
self
|
||||
) -> QColor:
|
||||
|
||||
return QColor("#FFFFFF") if self.isDarkMode() else QColor("#454545")
|
||||
|
||||
@Property(Status)
|
||||
def status(
|
||||
self
|
||||
) -> Status:
|
||||
|
||||
return self.__status
|
||||
|
||||
@Property(int)
|
||||
def iconAngle(
|
||||
self
|
||||
) -> int:
|
||||
|
||||
return self.__icon_angle
|
||||
|
||||
@status.setter
|
||||
def status(
|
||||
self,
|
||||
status: Status
|
||||
):
|
||||
|
||||
if status not in self.Status:
|
||||
raise ValueError(f"Invalid (class)Status[enum.Enum] value: {status}")
|
||||
self.__status = status
|
||||
if self.__status == self.Status.RUNNING:
|
||||
self.RunningAnimation.start()
|
||||
else:
|
||||
self.RunningAnimation.stop()
|
||||
self.update()
|
||||
|
||||
@iconAngle.setter
|
||||
def iconAngle(
|
||||
self,
|
||||
value: int
|
||||
):
|
||||
|
||||
self.__icon_angle = value
|
||||
self.update()
|
||||
|
||||
|
||||
def paintEvent(
|
||||
self,
|
||||
event
|
||||
):
|
||||
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
center_x = self.width()/2
|
||||
center_y = self.height()/2
|
||||
radius = min(center_x, center_y) - 3
|
||||
match self.__status:
|
||||
case self.Status.WAITING:
|
||||
pen = painter.pen()
|
||||
pen.setWidth(2)
|
||||
pen.setBrush(Qt.BrushStyle.NoBrush)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
pen.setColor(QColor("#969696")) # grey
|
||||
painter.setPen(pen)
|
||||
painter.drawEllipse(
|
||||
int(center_x - radius),
|
||||
int(center_y - radius),
|
||||
int(radius*2),
|
||||
int(radius*2)
|
||||
)
|
||||
case self.Status.RUNNING:
|
||||
gradient = QConicalGradient(center_x, center_y, self.__icon_angle)
|
||||
gradient.setColorAt(0.0, QColor("#2294FF" if self.isDarkMode() else "#0094FF"))
|
||||
gradient.setColorAt(1.0, QColor("#2294FF00"))
|
||||
pen = painter.pen()
|
||||
pen.setWidth(3)
|
||||
pen.setBrush(gradient)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
painter.setPen(pen)
|
||||
painter.drawEllipse(
|
||||
int(center_x - radius),
|
||||
int(center_y - radius),
|
||||
int(radius*2),
|
||||
int(radius*2)
|
||||
)
|
||||
case self.Status.SUCCESS:
|
||||
# draw the success green circle
|
||||
pen = painter.pen()
|
||||
pen.setWidth(2)
|
||||
pen.setBrush(Qt.BrushStyle.NoBrush)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
pen.setColor(QColor("#4CAF50" if self.isDarkMode() else "#00AF50")) # green
|
||||
painter.setPen(pen)
|
||||
painter.drawEllipse(
|
||||
int(center_x - radius),
|
||||
int(center_y - radius),
|
||||
int(radius*2),
|
||||
int(radius*2)
|
||||
)
|
||||
# draw the success check mark '✓'
|
||||
painter.setPen(Qt.PenStyle.SolidLine)
|
||||
pen = painter.pen()
|
||||
pen.setWidth(3)
|
||||
pen.setBrush(Qt.BrushStyle.NoBrush)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
# white when dark mode, black when light mode
|
||||
pen.setColor(self.getMarkColor())
|
||||
painter.setPen(pen)
|
||||
mark_size = radius/2
|
||||
mark_path = [
|
||||
(center_x - mark_size, center_y),
|
||||
(center_x - mark_size/3, center_y + mark_size/2),
|
||||
(center_x + mark_size, center_y - mark_size/2)
|
||||
]
|
||||
painter.drawLine(
|
||||
int(mark_path[0][0]),int(mark_path[0][1]),
|
||||
int(mark_path[1][0]),int(mark_path[1][1])
|
||||
)
|
||||
painter.drawLine(
|
||||
int(mark_path[1][0]),int(mark_path[1][1]),
|
||||
int(mark_path[2][0]),int(mark_path[2][1])
|
||||
)
|
||||
case self.Status.WARNING:
|
||||
# draw the warning orange circle
|
||||
pen = painter.pen()
|
||||
pen.setWidth(2)
|
||||
pen.setBrush(Qt.BrushStyle.NoBrush)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
pen.setColor(QColor("#FF9800")) # orange
|
||||
painter.setPen(pen)
|
||||
painter.drawEllipse(
|
||||
int(center_x - radius),
|
||||
int(center_y - radius),
|
||||
int(radius*2),
|
||||
int(radius*2)
|
||||
)
|
||||
# draw the warning exclamation mark '!'
|
||||
painter.setPen(Qt.PenStyle.SolidLine)
|
||||
pen = painter.pen()
|
||||
pen.setWidth(3)
|
||||
pen.setBrush(Qt.BrushStyle.NoBrush)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
# white when dark mode, black when light mode
|
||||
pen.setColor(self.getMarkColor())
|
||||
painter.setPen(pen)
|
||||
painter.drawLine(
|
||||
int(center_x), int(center_y - radius/2),
|
||||
int(center_x), int(center_y + radius/6)
|
||||
)
|
||||
painter.drawPoint(
|
||||
int(center_x), int(center_y + radius/2)
|
||||
)
|
||||
case self.Status.FAILURE:
|
||||
# draw the failure red circle
|
||||
pen = painter.pen()
|
||||
pen.setWidth(2)
|
||||
pen.setBrush(Qt.BrushStyle.NoBrush)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
pen.setColor(QColor("#DC0000")) # red
|
||||
painter.setPen(pen)
|
||||
painter.drawEllipse(
|
||||
int(center_x - radius),
|
||||
int(center_y - radius),
|
||||
int(radius*2),
|
||||
int(radius*2)
|
||||
)
|
||||
# draw the failure cross mark '✗'
|
||||
painter.setPen(Qt.PenStyle.SolidLine)
|
||||
pen = painter.pen()
|
||||
pen.setWidth(3)
|
||||
pen.setBrush(Qt.BrushStyle.NoBrush)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
# white when dark mode, black when light mode
|
||||
pen.setColor(self.getMarkColor())
|
||||
painter.setPen(pen)
|
||||
mark_size = radius/3
|
||||
painter.drawLine(
|
||||
int(center_x - mark_size), int(center_y - mark_size),
|
||||
int(center_x + mark_size), int(center_y + mark_size)
|
||||
)
|
||||
painter.drawLine(
|
||||
int(center_x + mark_size), int(center_y - mark_size),
|
||||
int(center_x - mark_size), int(center_y + mark_size)
|
||||
)
|
||||
painter.end()
|
||||
super().paintEvent(event)
|
||||
@@ -0,0 +1,518 @@
|
||||
# -*- 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 threading
|
||||
from typing import Optional
|
||||
|
||||
from PySide6.QtCore import (
|
||||
Qt, Slot, QThread, Signal
|
||||
)
|
||||
from PySide6.QtWidgets import (
|
||||
QDialog, QLabel, QComboBox, QProgressBar,
|
||||
QPushButton, QVBoxLayout, QHBoxLayout,
|
||||
QMessageBox, QFrame, QLineEdit
|
||||
)
|
||||
from PySide6.QtGui import (
|
||||
QCloseEvent
|
||||
)
|
||||
|
||||
from managers.driver.WebDriverManager import (
|
||||
instance as webdriver_manager_instance,
|
||||
WebDriverManager, WebDriverInfo, WebDriverType
|
||||
)
|
||||
from gui.ALStatusLabel import ALStatusLabel
|
||||
|
||||
|
||||
class DownloadWorker(QThread):
|
||||
"""
|
||||
Worker thread for downloading web drivers.
|
||||
"""
|
||||
|
||||
progress = Signal(float, int, float, str)
|
||||
finished = Signal(object, str)
|
||||
error = Signal(str)
|
||||
cancelled = Signal()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
driver_manager: WebDriverManager,
|
||||
driver_info: WebDriverInfo
|
||||
):
|
||||
super().__init__()
|
||||
self.__driver_manager = driver_manager
|
||||
self.__driver_info = driver_info
|
||||
self.__driver_path = None
|
||||
self.__cancelled = False
|
||||
self.__cancel_event = threading.Event()
|
||||
|
||||
def cancel(
|
||||
self
|
||||
):
|
||||
"""
|
||||
Cancel the download operation.
|
||||
"""
|
||||
|
||||
self.__cancelled = True
|
||||
self.__cancel_event.set()
|
||||
|
||||
def run(
|
||||
self
|
||||
):
|
||||
try:
|
||||
if self.__cancelled:
|
||||
self.cancelled.emit()
|
||||
return
|
||||
self.__driver_path = self.__driver_manager.installDriver(
|
||||
self.__driver_info,
|
||||
progress_callback=self.onProgress,
|
||||
cancel_event=self.__cancel_event
|
||||
)
|
||||
if self.__cancelled:
|
||||
self.cancelled.emit()
|
||||
return
|
||||
if self.__driver_path:
|
||||
self.finished.emit(self.__driver_path, "")
|
||||
else:
|
||||
self.error.emit("下载失败: 未返回有效路径")
|
||||
except Exception as e:
|
||||
if not self.__cancelled:
|
||||
self.error.emit(f"下载失败: {str(e)}")
|
||||
|
||||
def onProgress(
|
||||
self,
|
||||
downloaded: float,
|
||||
total: int,
|
||||
speed: float,
|
||||
message: str
|
||||
):
|
||||
|
||||
if self.__cancel_event.is_set():
|
||||
self.__cancelled = True
|
||||
if not self.__cancelled:
|
||||
self.progress.emit(downloaded, total, speed, message)
|
||||
|
||||
|
||||
class ALWebDriverDownloadDialog(QDialog):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent: Optional[QDialog] = None,
|
||||
driver_dir: str = ""
|
||||
):
|
||||
"""
|
||||
Web driver download dialog.
|
||||
|
||||
Args:
|
||||
parent: Parent widget.
|
||||
driver_dir: Driver directory path.
|
||||
"""
|
||||
|
||||
super().__init__(parent)
|
||||
|
||||
self.__driver_dir = driver_dir
|
||||
self.__driver_manager: Optional[WebDriverManager] = None
|
||||
self.__confirmed = False
|
||||
self.__selected_driver_info: Optional[WebDriverInfo] = None
|
||||
self.__driver_infos: list[WebDriverInfo] = []
|
||||
self.__download_thread: Optional[DownloadWorker] = None
|
||||
|
||||
self.setupUi()
|
||||
self.connectSignals()
|
||||
self.initializeDriverManager()
|
||||
self.refreshDriverList()
|
||||
|
||||
def showEvent(
|
||||
self,
|
||||
event
|
||||
):
|
||||
|
||||
result = super().showEvent(event)
|
||||
if self.parent():
|
||||
screen_rect = self.screen().geometry()
|
||||
target_pos = self.parent().geometry().center()
|
||||
target_pos.setX(target_pos.x() - self.width()//2)
|
||||
target_pos.setY(target_pos.y() - self.height()//2)
|
||||
if target_pos.x() < 0:
|
||||
target_pos.setX(0)
|
||||
if target_pos.x() + self.width() > screen_rect.width():
|
||||
target_pos.setX(screen_rect.width() - self.width())
|
||||
if target_pos.y() < 0:
|
||||
target_pos.setY(0)
|
||||
if target_pos.y() + self.height() > screen_rect.height():
|
||||
target_pos.setY(screen_rect.height() - self.height())
|
||||
self.move(target_pos)
|
||||
return result
|
||||
|
||||
def setupUi(
|
||||
self
|
||||
):
|
||||
|
||||
self.setModal(True)
|
||||
self.setMaximumHeight(240)
|
||||
self.setMinimumHeight(240)
|
||||
self.setWindowTitle("浏览器驱动下载 - AutoLibrary")
|
||||
|
||||
self.MainLayout = QVBoxLayout(self)
|
||||
self.MainLayout.setContentsMargins(5, 5, 5, 5)
|
||||
self.MainLayout.setSpacing(5)
|
||||
|
||||
self.BrowserCountLabel = QLabel("检测到 0 个可用浏览器:")
|
||||
self.MainLayout.addWidget(self.BrowserCountLabel)
|
||||
|
||||
self.DriverInfoLayout = QHBoxLayout()
|
||||
self.DriverInfoLayout.setSpacing(5)
|
||||
self.DriverComboBox = QComboBox()
|
||||
self.DriverInfoLayout.addWidget(self.DriverComboBox)
|
||||
self.StatusLabel = ALStatusLabel()
|
||||
self.StatusLabel.setFixedSize(32, 32)
|
||||
self.DriverInfoLayout.addWidget(self.StatusLabel)
|
||||
self.MainLayout.addLayout(self.DriverInfoLayout)
|
||||
|
||||
self.DetailLayout = QVBoxLayout()
|
||||
self.DetailLayout.setSpacing(5)
|
||||
self.DetailLayout.setContentsMargins(5, 5, 5, 5)
|
||||
self.BrowserTypeLabel = QLabel("类型:")
|
||||
self.DetailLayout.addWidget(self.BrowserTypeLabel)
|
||||
self.VersionLabel = QLabel("版本:")
|
||||
self.DetailLayout.addWidget(self.VersionLabel)
|
||||
self.PathLabel = QLineEdit()
|
||||
self.PathLabel.setReadOnly(True)
|
||||
self.PathLabel.setText("路径:未安装")
|
||||
self.DetailLayout.addWidget(self.PathLabel)
|
||||
self.MainLayout.addLayout(self.DetailLayout)
|
||||
|
||||
self.Line = QFrame()
|
||||
self.Line.setFrameShape(QFrame.Shape.HLine)
|
||||
self.Line.setFrameShadow(QFrame.Shadow.Sunken)
|
||||
self.MainLayout.addWidget(self.Line)
|
||||
self.ProgressBar = QProgressBar()
|
||||
self.ProgressBar.setValue(0)
|
||||
self.ProgressBar.setTextVisible(False)
|
||||
self.MainLayout.addWidget(self.ProgressBar)
|
||||
self.ProgressText = QLabel("")
|
||||
self.ProgressText.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.MainLayout.addWidget(self.ProgressText)
|
||||
self.ControlLayout = QHBoxLayout()
|
||||
self.ControlLayout.setSpacing(8)
|
||||
self.ControlLayout.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
self.RefreshButton = QPushButton("刷新")
|
||||
self.RefreshButton.setFixedSize(80, 25)
|
||||
self.DownloadButton = QPushButton("下载驱动")
|
||||
self.DownloadButton.setFixedSize(80, 25)
|
||||
self.DeleteButton = QPushButton("删除驱动")
|
||||
self.DeleteButton.setFixedSize(80, 25)
|
||||
self.CancelButton = QPushButton("取消")
|
||||
self.CancelButton.setFixedSize(80, 25)
|
||||
self.ConfirmButton = QPushButton("确认")
|
||||
self.ConfirmButton.setFixedSize(80, 25)
|
||||
self.ConfirmButton.setEnabled(False)
|
||||
|
||||
self.ControlLayout.addWidget(self.RefreshButton)
|
||||
self.ControlLayout.addWidget(self.DownloadButton)
|
||||
self.ControlLayout.addWidget(self.DeleteButton)
|
||||
self.ControlLayout.addWidget(self.CancelButton)
|
||||
self.ControlLayout.addWidget(self.ConfirmButton)
|
||||
self.MainLayout.addLayout(self.ControlLayout)
|
||||
|
||||
|
||||
def connectSignals(
|
||||
self
|
||||
):
|
||||
|
||||
self.RefreshButton.clicked.connect(self.onRefreshButtonClicked)
|
||||
self.DownloadButton.clicked.connect(self.onDownloadButtonClicked)
|
||||
self.DeleteButton.clicked.connect(self.onDeleteButtonClicked)
|
||||
self.CancelButton.clicked.connect(self.onCancelButtonClicked)
|
||||
self.ConfirmButton.clicked.connect(self.onConfirmButtonClicked)
|
||||
self.DriverComboBox.currentIndexChanged.connect(self.onDriverComboBoxChanged)
|
||||
|
||||
|
||||
def initializeDriverManager(
|
||||
self
|
||||
):
|
||||
|
||||
try:
|
||||
self.__driver_manager = webdriver_manager_instance(self.__driver_dir)
|
||||
except ValueError as e:
|
||||
QMessageBox.warning(self, "初始化失败", f"WebDriverManager 初始化失败:\n{str(e)}")
|
||||
self.reject()
|
||||
|
||||
|
||||
def refreshDriverList(
|
||||
self
|
||||
):
|
||||
|
||||
if not self.__driver_manager:
|
||||
return
|
||||
self.__driver_manager.refresh()
|
||||
self.__driver_infos = self.__driver_manager.getDriverInfos()
|
||||
self.DriverComboBox.clear()
|
||||
for driver_info in self.__driver_infos:
|
||||
display_text = f"{driver_info.driver_type.value} - {driver_info.browser_version}"
|
||||
self.DriverComboBox.addItem(display_text)
|
||||
count = len(self.__driver_infos)
|
||||
self.BrowserCountLabel.setText(f"检测到 {count} 个可用浏览器:")
|
||||
if self.__driver_infos:
|
||||
self.onDriverComboBoxChanged(0)
|
||||
|
||||
|
||||
def onDriverComboBoxChanged(
|
||||
self,
|
||||
index: int
|
||||
):
|
||||
|
||||
if not self.__driver_infos or index < 0 or index >= len(self.__driver_infos):
|
||||
return
|
||||
driver_info = self.__driver_infos[index]
|
||||
self.updateDriverInfoDisplay(driver_info)
|
||||
self.updateButtonStates(driver_info)
|
||||
|
||||
|
||||
@Slot()
|
||||
def onRefreshButtonClicked(
|
||||
self
|
||||
):
|
||||
|
||||
self.refreshDriverList()
|
||||
|
||||
|
||||
@Slot()
|
||||
def onDeleteButtonClicked(
|
||||
self
|
||||
):
|
||||
|
||||
index = self.DriverComboBox.currentIndex()
|
||||
if index < 0 or index >= len(self.__driver_infos):
|
||||
return
|
||||
driver_info = self.__driver_infos[index]
|
||||
if driver_info.driver_status.name != "INSTALLED":
|
||||
QMessageBox.information(self, "提示 - AutoLibrary", "该驱动未安装, 无需删除")
|
||||
return
|
||||
reply = QMessageBox.question(
|
||||
self,
|
||||
"确认删除 - AutoLibrary",
|
||||
f"确定要删除 {driver_info.driver_type.value} 驱动吗 ?",
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
||||
)
|
||||
if reply == QMessageBox.StandardButton.No:
|
||||
return
|
||||
try:
|
||||
self.__driver_manager.uninstallDriver(driver_info)
|
||||
self.refreshDriverList()
|
||||
QMessageBox.information(self, "删除成功 - AutoLibrary", "驱动已成功删除")
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "删除失败 - AutoLibrary", f"删除驱动时出错:\n{str(e)}")
|
||||
|
||||
@Slot()
|
||||
def onDownloadButtonClicked(
|
||||
self
|
||||
):
|
||||
|
||||
index = self.DriverComboBox.currentIndex()
|
||||
if index < 0 or index >= len(self.__driver_infos):
|
||||
return
|
||||
driver_info = self.__driver_infos[index]
|
||||
if driver_info.driver_status.name == "INSTALLED":
|
||||
return
|
||||
self.StatusLabel.status = ALStatusLabel.Status.RUNNING
|
||||
self.DownloadButton.setEnabled(False)
|
||||
self.RefreshButton.setEnabled(False)
|
||||
self.DriverComboBox.setEnabled(False)
|
||||
self.ProgressBar.setValue(0)
|
||||
self.ProgressText.setText("正在下载驱动...")
|
||||
self.__download_thread = DownloadWorker(self.__driver_manager, driver_info)
|
||||
self.__download_thread.progress.connect(self.onDownloadProgress)
|
||||
self.__download_thread.finished.connect(self.onDownloadFinished)
|
||||
self.__download_thread.error.connect(self.onDownloadError)
|
||||
self.__download_thread.cancelled.connect(self.onDownloadCancelled)
|
||||
self.__download_thread.start()
|
||||
|
||||
@Slot()
|
||||
def onDownloadProgress(
|
||||
self,
|
||||
downloaded: float,
|
||||
total: int,
|
||||
speed: float,
|
||||
message: str
|
||||
):
|
||||
|
||||
progress = downloaded
|
||||
self.ProgressBar.setValue(progress)
|
||||
if speed >= 1024:
|
||||
speed_text = f"{speed/1024:.1f} MB/s"
|
||||
else:
|
||||
speed_text = f"{speed:.1f} KB/s"
|
||||
progress_text = f"{message}... {downloaded:.1f}% - {speed_text}"
|
||||
self.ProgressText.setText(progress_text)
|
||||
|
||||
@Slot()
|
||||
def onDownloadFinished(
|
||||
self
|
||||
):
|
||||
|
||||
self.ProgressBar.setValue(100)
|
||||
self.ProgressText.setText("下载完成 !")
|
||||
self.StatusLabel.status = ALStatusLabel.Status.SUCCESS
|
||||
index = self.DriverComboBox.currentIndex()
|
||||
if 0 <= index < len(self.__driver_infos):
|
||||
driver_info = self.__driver_infos[index]
|
||||
self.updateDriverInfoDisplay(driver_info)
|
||||
self.__download_thread = None
|
||||
self.ConfirmButton.setEnabled(True)
|
||||
self.DownloadButton.setEnabled(False)
|
||||
self.RefreshButton.setEnabled(True)
|
||||
self.DriverComboBox.setEnabled(True)
|
||||
self.DeleteButton.setEnabled(True)
|
||||
|
||||
@Slot()
|
||||
def onDownloadError(
|
||||
self,
|
||||
error_message: str
|
||||
):
|
||||
|
||||
self.StatusLabel.status = ALStatusLabel.Status.FAILURE
|
||||
QMessageBox.critical(self, "下载失败 - AutoLibrary", error_message)
|
||||
self.DownloadButton.setEnabled(True)
|
||||
self.RefreshButton.setEnabled(True)
|
||||
self.DriverComboBox.setEnabled(True)
|
||||
self.CancelButton.setEnabled(True)
|
||||
|
||||
|
||||
@Slot()
|
||||
def onDownloadCancelled(
|
||||
self
|
||||
):
|
||||
|
||||
if self.__download_thread:
|
||||
self.__download_thread.wait(3000)
|
||||
self.__download_thread = None
|
||||
index = self.DriverComboBox.currentIndex()
|
||||
if 0 <= index < len(self.__driver_infos):
|
||||
driver_info = self.__driver_infos[index]
|
||||
self.__driver_manager.cancelDriverDownload(driver_info)
|
||||
self.updateDriverInfoDisplay(driver_info)
|
||||
self.ProgressText.setText("下载已取消")
|
||||
self.ProgressBar.setValue(0)
|
||||
self.StatusLabel.status = ALStatusLabel.Status.WAITING
|
||||
self.DownloadButton.setEnabled(True)
|
||||
self.RefreshButton.setEnabled(True)
|
||||
self.DriverComboBox.setEnabled(True)
|
||||
self.CancelButton.setEnabled(True)
|
||||
self.DeleteButton.setEnabled(False)
|
||||
|
||||
|
||||
@Slot()
|
||||
def onConfirmButtonClicked(
|
||||
self
|
||||
):
|
||||
|
||||
index = self.DriverComboBox.currentIndex()
|
||||
if index < 0 or index >= len(self.__driver_infos):
|
||||
return
|
||||
driver_info = self.__driver_infos[index]
|
||||
if driver_info.driver_status.name != "INSTALLED":
|
||||
return
|
||||
self.__selected_driver_info = driver_info
|
||||
self.__confirmed = True
|
||||
self.accept()
|
||||
|
||||
|
||||
@Slot()
|
||||
def onCancelButtonClicked(
|
||||
self
|
||||
):
|
||||
|
||||
if self.__download_thread:
|
||||
reply = QMessageBox.question(
|
||||
self,
|
||||
"确认取消 - AutoLibrary",
|
||||
"正在下载中, 确定要取消下载吗 ?",
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
||||
)
|
||||
if reply == QMessageBox.StandardButton.Yes:
|
||||
self.__download_thread.cancel()
|
||||
else:
|
||||
self.__confirmed = False
|
||||
self.__selected_driver_info = None
|
||||
self.reject()
|
||||
|
||||
|
||||
def closeEvent(
|
||||
self,
|
||||
event: QCloseEvent
|
||||
):
|
||||
|
||||
if self.__download_thread and self.__download_thread.isRunning():
|
||||
reply = QMessageBox.question(
|
||||
self,
|
||||
"确认关闭 - AutoLibrary",
|
||||
"驱动正在下载中, 确定要取消并关闭对话框吗 ?",
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
||||
)
|
||||
if reply == QMessageBox.StandardButton.No:
|
||||
event.ignore()
|
||||
return
|
||||
self.__download_thread.cancel()
|
||||
self.__download_thread.wait(5000)
|
||||
if not self.__confirmed:
|
||||
self.__selected_driver_info = None
|
||||
event.accept()
|
||||
super().closeEvent(event)
|
||||
|
||||
|
||||
def getSelectedDriverInfo(
|
||||
self
|
||||
) -> Optional[WebDriverInfo]:
|
||||
|
||||
return self.__selected_driver_info
|
||||
|
||||
|
||||
def updateDriverInfoDisplay(
|
||||
self,
|
||||
driver_info: WebDriverInfo
|
||||
):
|
||||
|
||||
if driver_info.driver_type == WebDriverType.CHROME:
|
||||
driver_type = "Google Chrome"
|
||||
elif driver_info.driver_type == WebDriverType.FIREFOX:
|
||||
driver_type = "Mozilla Firefox"
|
||||
elif driver_info.driver_type == WebDriverType.EDGE:
|
||||
driver_type = "Microsoft Edge"
|
||||
else:
|
||||
driver_type = "未知"
|
||||
self.BrowserTypeLabel.setText(f"类型:{driver_type}")
|
||||
self.VersionLabel.setText(f"版本:{driver_info.driver_version}")
|
||||
if driver_info.driver_path:
|
||||
self.PathLabel.setText(str(driver_info.driver_path))
|
||||
else:
|
||||
self.PathLabel.setText("未安装")
|
||||
match driver_info.driver_status.name:
|
||||
case "NOT_INSTALLED":
|
||||
self.StatusLabel.status = ALStatusLabel.Status.WAITING
|
||||
case "INSTALLED":
|
||||
self.StatusLabel.status = ALStatusLabel.Status.SUCCESS
|
||||
case "DOWNLOADING":
|
||||
self.StatusLabel.status = ALStatusLabel.Status.RUNNING
|
||||
case "ERROR":
|
||||
self.StatusLabel.status = ALStatusLabel.Status.FAILURE
|
||||
|
||||
|
||||
def updateButtonStates(
|
||||
self,
|
||||
driver_info: WebDriverInfo
|
||||
):
|
||||
|
||||
if driver_info.driver_status.name == "INSTALLED":
|
||||
self.DownloadButton.setEnabled(False)
|
||||
self.DeleteButton.setEnabled(True)
|
||||
self.ConfirmButton.setEnabled(True)
|
||||
else:
|
||||
self.DeleteButton.setEnabled(False)
|
||||
self.DownloadButton.setEnabled(True)
|
||||
self.ConfirmButton.setEnabled(False)
|
||||
Reference in New Issue
Block a user