Files
Feeding_control_system/view/widgets/production_progress_widget.py
2025-10-31 18:52:35 +08:00

194 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from PySide6.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout
from PySide6.QtGui import QPixmap, QRegion, QPainter, QColor, QPainterPath
from PySide6.QtCore import Qt, QPropertyAnimation, Property, QSize, QRectF
import sys
class MaskedLabel(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setFixedSize(28, 20) # 遮罩大小
self.setStyleSheet("background-color: transparent; border: none;")
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# parent_widget = self.parent()
bg_color = QColor("#023eab") # 默认颜色 注意:需要根据背景颜色修改
# if parent_widget:
# # 从父控件的调色板中提取背景色
# bg_color = parent_widget.palette().color(parent_widget.backgroundRole())
# 用父控件背景色绘制遮罩
painter.setBrush(bg_color)
painter.setPen(Qt.NoPen)
# 步骤3绘制遮罩路径逻辑不变
path = QPainterPath()
mask_rect = QRectF(0, 0, 28, 20)
circle_radius = 10
circle_center_x = 28
circle_center_y = 10
path.addRect(mask_rect)
path.addEllipse(
circle_center_x - circle_radius,
circle_center_y - circle_radius,
circle_radius * 2,
circle_radius * 2,
)
path.setFillRule(Qt.OddEvenFill)
painter.drawPath(path)
class LinearProductionProgress(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self._progress = 0 # 进度0-100
self.setFixedSize(450 + 18, 20)
self.setStyleSheet(
"""
border-radius: 9px;
"""
)
# 底层背景
self.bg_label = QLabel(self)
self.bg_label.setFixedSize(450, 20)
# self.bg_label.setStyleSheet(
# """
# background-color: #e7e7e7;
# """
# )
# #011454
self.bg_label.setStyleSheet(
"""
background-color: #011454;
"""
)
self.bg_label.move(17, 0) # 这里需要调整对齐
# 上层进度填充
self.fg_label = QLabel(self)
# self.fg_label.setStyleSheet(
# """
# background-color: #0052d9;
# min-width: 18px;
# """
# )
# #02f2fe
self.fg_label.setStyleSheet(
"""
background-color: #02f2fe;
min-width: 18px;
"""
)
self.fg_label.setFixedHeight(20)
self.fg_label.move(0, 0)
self.fg_label.raise_()
# 百分比标签宽33px高19px右偏9px
self.percent_label = QLabel(self)
self.percent_label.setText("0%")
self.percent_label.setAlignment(Qt.AlignCenter)
self.percent_label.setFixedSize(33, 19)
# self.percent_label.setStyleSheet(
# """
# color: white;
# font-size: 12px;
# font-weight: bold;
# background-color: transparent;
# """
# )
# #02366c #001c83
self.percent_label.setStyleSheet(
"""
color: #001c83;
font-size: 13px;
font-weight: bold;
background-color: transparent;
"""
)
self.percent_label.move(18, 0) # 百分比标签初始位置
self.percent_label.raise_()
# 遮盖左侧区域
self.mask_label = MaskedLabel(self)
self.mask_label.move(0, 0)
# 进度属性
@Property(int)
def progress(self):
return self._progress
@progress.setter
def progress(self, value):
if 0 <= value <= 100 and value != self._progress:
self._progress = value
self.update_foreground()
# 线性更新进度显示
def update_foreground(self):
# 注意为了实现前4%的动态效果,需要从 fd_width的4%起开始计算
fg_width = int(450 * (self._progress + 4) / 100)
self.fg_label.setFixedWidth(fg_width)
# 计算百分比标签位置:进度条右边缘 - 9px偏移 - 标签宽度33px
if fg_width > 60: # 当上层进度条宽度大于60px开始移动
label_x = fg_width - 9 - 33
# 移动百分比标签
self.percent_label.move(label_x, 0)
else:
# 复原百分比标签
# 移动回初始位置
self.percent_label.move(18, 0)
# 设置百分比标签
self.percent_label.setText(f"{self._progress}%")
class ProductionProgressWidget(QWidget):
def __init__(self):
super().__init__()
self.setFixedSize(620, 49) # 进度条控件大小
# 左侧文字标签
self.text_label = QLabel("进度")
self.text_label.setFixedSize(112, 29)
self.text_label.setAlignment(Qt.AlignTop | Qt.AlignRight)
self.text_label.setStyleSheet("font-family: 'Microsoft YaHei';font-size: 20px;color: #16FFFF;")
# 右侧进度条
self.linear_progress = LinearProductionProgress()
self.main_layout = QHBoxLayout(self)
self.main_layout.addWidget(self.text_label)
self.main_layout.addWidget(self.linear_progress, alignment=Qt.AlignLeft)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.setSpacing(0)
def testProgress(self, seconds: float):
self.animation = QPropertyAnimation(self.linear_progress, b"progress")
self.animation.setDuration(seconds * 1000)
self.animation.setStartValue(0)
self.animation.setEndValue(100)
self.animation.start()
def setProgress(self, progress: float):
"""
设置progress之后, 会根据该值调整进度条
Args:
progress: 传入去掉百分号之后的数值, 如80%, 传入80.0
"""
self.linear_progress.progress = progress
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ProductionProgressWidget()
window.testProgress(60) # 进度条测试
window.show()
sys.exit(app.exec())