Files
Feeding_control_system/view/widgets/arc_progress_widget.py

282 lines
11 KiB
Python
Raw Normal View History

2025-10-18 18:29:40 +08:00
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QWidget, QVBoxLayout, QSizePolicy
from PySide6.QtGui import QPixmap
from PySide6.QtCore import Qt, QPropertyAnimation, Property
import os
2025-10-31 18:52:31 +08:00
import resources.resources_rc
2025-10-18 18:29:40 +08:00
# 拱形进度条
class OverlapArcProgress(QWidget):
def __init__(self, bg_img_path, fg_img_path, parent=None):
super().__init__(parent)
self._progress = 0 # 进度0-100
self.setStyleSheet("background: transparent; border: none;")
# 加载并统一图片尺寸
self.bg_pixmap = QPixmap(bg_img_path)
self.fg_pixmap = QPixmap(fg_img_path)
if self.bg_pixmap.isNull():
print(f"错误:拱进度条背景图 {bg_img_path} 加载失败")
if self.fg_pixmap.isNull():
print(f"错误:拱进度条前景图 {fg_img_path} 加载失败")
if self.bg_pixmap.size() != self.fg_pixmap.size():
self.fg_pixmap = self.fg_pixmap.scaled(
self.bg_pixmap.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation
)
# 控件尺寸与图片一致(避免缩放失真)
self.setFixedSize(self.bg_pixmap.size())
self.total_height = self.bg_pixmap.height() # 缓存总高度(背景/前景高度一致)
# 背景标签(下层,完整显示背景)
self.bg_label = QLabel(self)
self.bg_label.setPixmap(self.bg_pixmap)
self.bg_label.setScaledContents(False) # 禁用缩放
# 前景标签(上层,初始加载完整前景图,通过高度控制显示区域)
self.fg_label = QLabel(self)
self.fg_label.setPixmap(self.fg_pixmap) # 直接加载完整前景图
self.fg_label.setScaledContents(False) # 禁用缩放(避免图片拉伸)
self.fg_label.setAlignment(Qt.AlignBottom) # 图片在标签内底部对齐
self.fg_label.raise_() # 确保在背景上层
# 初始状态高度为0位置在底部不显示任何内容
self.fg_label.setGeometry(0, self.total_height, self.bg_pixmap.width(), 0)
# ---------- 进度显示标签 ----------
2025-10-31 18:52:31 +08:00
# self.progress_label = QLabel(self)
# self.progress_label.setGeometry(217, 17, 121, 34)
# self.progress_label.setStyleSheet("""
# background-color: #444750;
# color: #A2EF4D;
# font-size: 20px;
# font-weight: bold;
# """)
# # 文本在标签内部居中显示
# self.progress_label.setAlignment(Qt.AlignCenter)
# self.progress_label.raise_() # 确保在前景上层(最上层)
# self.progress_label.setText("0%") # 初始文本
2025-10-18 18:29:40 +08:00
# ---------- 进度属性 ----------
@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):
"""通过调整前景标签的高度和Y坐标, 实现从底部向上填充的进度条"""
# 同步更新进度标签文本
2025-10-31 18:52:31 +08:00
# self.progress_label.setText(f"{self._progress}%")
2025-10-18 18:29:40 +08:00
# print(f"{self._progress}%")
progress_ratio = self._progress / 100.0
k = 8 # 调整此系数k越大“快慢差异”越明显推荐范围 3~10
# 公式height_ratio = x + k*(x³/3 - x²/2 + x/6)
height_ratio = progress_ratio + k * (
(progress_ratio ** 3) / 3 -
(progress_ratio ** 2) / 2 +
progress_ratio / 6
)
height_ratio = max(0.0, min(1.0, height_ratio)) # 限制范围0-1
# 计算目标高度(随进度变化)
target_height = int(self.total_height * height_ratio)
# fg_label标签Y坐标 = 总高度 - 目标高度(实现底部对齐,向上延伸)
target_y = self.total_height - target_height
# 标签宽度与背景一致,高度为目标高度
self.fg_label.setGeometry(
0, # X坐标与背景左对齐
target_y, # Y坐标底部对齐
self.bg_pixmap.width(), # 宽度(与背景一致)
target_height # 高度(随进度变化)
)
class ArcProgressWidget(QWidget):
def __init__(self):
super().__init__()
2025-10-31 18:52:31 +08:00
# 加载ArcProgressWidget背景图
2025-10-18 18:29:40 +08:00
# 添加了 拱3.png 作为背景图
bg_img = ":/icons/images/拱3.png" # 需要修改为实际的图片的路径
# self.setStyleSheet(f"background-image: url({bg_img}); background-repeat: no-repeat; background-position: center;")
self.bg_pixmap = QPixmap(bg_img)
2025-10-31 18:52:31 +08:00
# self.setStyleSheet("background-color: red;")
2025-10-18 18:29:40 +08:00
# # 设置控件widget大小与背景图一致
2025-10-31 18:52:31 +08:00
# self.bg_pixmap.size() 为 555x227
# self.setFixedSize(self.bg_pixmap.size())
# self.setFixedSize(555, 254)
self.setFixedSize(555, 259)
2025-10-18 18:29:40 +08:00
self.setSizePolicy(
QSizePolicy.Fixed, # 水平方向固定
QSizePolicy.Fixed # 垂直方向固定
)
2025-10-31 18:52:31 +08:00
# 创建垂直主布局
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0) # 去除边距
main_layout.setSpacing(0) # 去除控件间距
# 1. 添加标题标签(保持居中)
self.arc_title_label = QLabel("振捣模具车", self)
self.arc_title_label.setFixedSize(555, 29)
self.arc_title_label.setAlignment(Qt.AlignCenter)
self.arc_title_label.setStyleSheet("""
color: #0bffff;
font-size: 18px;
background-image: url(:/icons/images/文字标题底.png);
background-repeat: no-repeat;
background-position: center;
margin: 4px auto;
""")
main_layout.addWidget(self.arc_title_label, alignment=Qt.AlignCenter)
# 2. 创建普通QWidget作为容器大小与背景图一致
container = QWidget(self)
container.setFixedSize(self.bg_pixmap.size()) # 容器大小=背景图大小
# 容器内设置背景图
background_label = QLabel(container)
2025-10-18 18:29:40 +08:00
background_label.setPixmap(self.bg_pixmap)
background_label.setScaledContents(True)
2025-10-31 18:52:31 +08:00
background_label.setFixedSize(container.size())
background_label.lower() # 背景置底,避免遮挡其他控件
2025-10-18 18:29:40 +08:00
2025-10-31 18:52:31 +08:00
# 3. 在容器内添加所有标签和拱形进度条用setGeometry定位
2025-10-18 18:29:40 +08:00
# 创建拱形进度条控件
2025-10-31 18:52:31 +08:00
arc_bg_img = ":/icons/images/拱2.png" # 替换为实际路径
arc_fg_img = ":/icons/images/拱1.png" # 替换为实际路径
self.arc_progress = OverlapArcProgress(arc_bg_img, arc_fg_img, container)
# 显示环号的标签
self.ring_number_label = QLabel("环号: 1", container)
self.ring_number_label.setGeometry(98, 118, 116, 29) # 保持原坐标
self.ring_number_label.setStyleSheet("""
background-color: #143a6e;
color: #16ffff;
font-size: 18px;
""")
self.ring_number_label.setAlignment(Qt.AlignCenter)
# 显示重量的标签
self.weight_label = QLabel("2000kg", container)
self.weight_label.setGeometry(217, 118, 118, 29) # 保持原坐标
2025-10-18 18:29:40 +08:00
self.weight_label.setStyleSheet("""
2025-10-31 18:52:31 +08:00
background-color: #143a6e;
color: #16ffff;
font-size: 18px;
2025-10-18 18:29:40 +08:00
""")
self.weight_label.setAlignment(Qt.AlignCenter)
2025-10-31 18:52:31 +08:00
# 显示管片型号的标签
self.segment_model_label = QLabel("中埋: R12", container)
self.segment_model_label.setGeometry(98, 150, 116, 29)
2025-10-18 18:29:40 +08:00
self.segment_model_label.setStyleSheet("""
2025-10-31 18:52:31 +08:00
background-color: #143a6e;
color: #16ffff;
font-size: 18px;
2025-10-18 18:29:40 +08:00
""")
self.segment_model_label.setAlignment(Qt.AlignCenter)
2025-10-31 18:52:31 +08:00
# 显示频率的标签
self.frequency_label = QLabel("210Hz", container)
self.frequency_label.setGeometry(217, 150, 118, 29)
2025-10-18 18:29:40 +08:00
self.frequency_label.setStyleSheet("""
2025-10-31 18:52:31 +08:00
background-color: #143a6e;
color: #16ffff;
font-size: 18px;
2025-10-18 18:29:40 +08:00
""")
self.frequency_label.setAlignment(Qt.AlignCenter)
2025-10-31 18:52:31 +08:00
# 显示管片编号的标签
self.segment_number_label = QLabel("SHRB1-3", container)
self.segment_number_label.setGeometry(338, 150, 116, 29)
2025-10-18 18:29:40 +08:00
self.segment_number_label.setStyleSheet("""
2025-10-31 18:52:31 +08:00
background-color: #143a6e;
color: #16ffff;
font-size: 18px;
2025-10-18 18:29:40 +08:00
""")
self.segment_number_label.setAlignment(Qt.AlignCenter)
2025-10-31 18:52:31 +08:00
# 显示管片尺寸的标签
self.segment_size_label = QLabel("6900*1500", container)
self.segment_size_label.setGeometry(98, 182, 116, 29)
self.segment_size_label.setStyleSheet("""
background-color: #143a6e;
color: #16ffff;
font-size: 18px;
""")
self.segment_size_label.setAlignment(Qt.AlignCenter)
# 显示状态的标签
self.state_label = QLabel("振动中", container)
self.state_label.setGeometry(217, 182, 118, 29)
2025-10-18 18:29:40 +08:00
self.state_label.setStyleSheet("""
2025-10-31 18:52:31 +08:00
background-color: #143a6e;
color: #16ffff;
font-size: 18px;
2025-10-18 18:29:40 +08:00
""")
self.state_label.setAlignment(Qt.AlignCenter)
2025-10-31 18:52:31 +08:00
# 4. 将拱形进度条容器添加到主布局
main_layout.addWidget(container, alignment=Qt.AlignCenter)
2025-10-18 18:29:40 +08:00
# 进度条测试
def testProgress(self, seconds: float):
# 启动动画从0%到100% (模拟进度加载)
self.animation = QPropertyAnimation(self.arc_progress, b"progress")
self.animation.setDuration(seconds * 1000)
self.animation.setStartValue(0)
self.animation.setEndValue(100)
self.animation.start()
# 进度条设置
def setProgress(self, progress:int):
"""
设置progress之后, 会根据该值调整进度条
Args:
progress: 传入去掉百分号之后的数值, 如80%, 传入80
"""
self.arc_progress.progress = progress
# 重量设置 (单位kg)
def setWeight(self, weight:float):
self.weight_label.setText(f"{weight}kg")
# 频率设置单位Hz
def setFrequency(self, frequency:float):
self.frequency_label.setText(f"{frequency}Hz")
# 状态设置 (...中)
def setState(self, stateStr:str):
self.state_label.setText(stateStr)
2025-10-31 18:52:31 +08:00
# 管片类型设置 (B1、B2、中埋: R12 等)
2025-10-18 18:29:40 +08:00
def setSegmentModel(self, segmentModelStr:str):
self.segment_model_label.setText(segmentModelStr)
# 管片编号设置
def setSegmentNumber(self, segmentNumberStr:str):
self.segment_number_label.setText(segmentNumberStr)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
window = ArcProgressWidget()
window.testProgress(120)
2025-10-31 18:52:31 +08:00
# window.setState("测试中")
2025-10-18 18:29:40 +08:00
window.show()
sys.exit(app.exec())