485 lines
18 KiB
Python
485 lines
18 KiB
Python
# coding:utf-8
|
||
from PySide6.QtCore import Qt, QEasingCurve, QTimer
|
||
from PySide6.QtGui import QColor, QImage, QPixmap
|
||
from PySide6.QtWidgets import (
|
||
QWidget,
|
||
QStackedWidget,
|
||
QVBoxLayout,
|
||
QLabel,
|
||
QHBoxLayout,
|
||
QFrame,
|
||
QSizePolicy,
|
||
)
|
||
from qfluentwidgets import (
|
||
Pivot,
|
||
qrouter,
|
||
SegmentedWidget,
|
||
TabBar,
|
||
CheckBox,
|
||
ComboBox,
|
||
TabCloseButtonDisplayMode,
|
||
BodyLabel,
|
||
SpinBox,
|
||
BreadcrumbBar,
|
||
SegmentedToggleToolWidget,
|
||
FluentIcon,
|
||
TransparentPushButton,
|
||
EditableComboBox,
|
||
PrimaryPushButton,
|
||
Slider,
|
||
DisplayLabel,
|
||
TextBrowser,
|
||
SwitchButton,
|
||
PillPushButton,
|
||
ToggleButton,
|
||
)
|
||
|
||
from .gallery_interface import GalleryInterface
|
||
from ..common.translator import Translator
|
||
from ..common.style_sheet import StyleSheet
|
||
import cv2
|
||
|
||
|
||
class SystemInterface(GalleryInterface):
|
||
"""Navigation view interface"""
|
||
|
||
def __init__(self, parent=None):
|
||
t = Translator()
|
||
super().__init__(
|
||
title=t.navigation,
|
||
subtitle="qfluentwidgets.components.navigation",
|
||
parent=parent,
|
||
)
|
||
self.setObjectName("systemInterface")
|
||
|
||
# breadcrumb bar
|
||
card = self.addExampleCard(
|
||
title=self.tr(""),
|
||
widget=TabInterface(self),
|
||
sourcePath="https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/PySide6/examples/navigation/tab_view/demo.py",
|
||
stretch=1,
|
||
)
|
||
card.topLayout.setContentsMargins(12, 0, 0, 0)
|
||
|
||
def createToggleToolWidget(self):
|
||
w = SegmentedToggleToolWidget(self)
|
||
w.addItem("k1", FluentIcon.TRANSPARENT)
|
||
w.addItem("k2", FluentIcon.CHECKBOX)
|
||
w.addItem("k3", FluentIcon.CONSTRACT)
|
||
w.setCurrentItem("k1")
|
||
return w
|
||
|
||
|
||
class TabInterface(QWidget):
|
||
"""Tab interface"""
|
||
|
||
def __init__(self, parent=None):
|
||
super().__init__(parent=parent)
|
||
self.tabCount = 1
|
||
|
||
# self.tabBar = TabBar(self)
|
||
# self.stackedWidget = QStackedWidget(self)
|
||
self.tabView = QWidget(self)
|
||
self.controlPanel = QFrame(self)
|
||
|
||
# clock
|
||
self.clock = TransparentPushButton(
|
||
"2025-08-04 16:55", self, FluentIcon.DATE_TIME
|
||
)
|
||
|
||
# combo box
|
||
self.comboBox1 = ComboBox()
|
||
self.comboBox1.addItems(["反应釜1", "反应釜2"])
|
||
self.comboBox1.setCurrentIndex(0)
|
||
self.comboBox1.setMinimumWidth(180)
|
||
|
||
# label
|
||
self.label = QLabel("自定义数量", self)
|
||
|
||
# editable combo box
|
||
self.comboBox = EditableComboBox()
|
||
self.comboBox.addItems(
|
||
[
|
||
"10",
|
||
"20",
|
||
"30",
|
||
"40",
|
||
"50",
|
||
"60",
|
||
"70",
|
||
"80",
|
||
]
|
||
)
|
||
self.comboBox.setPlaceholderText("自定义数量")
|
||
self.comboBox.setMinimumWidth(90)
|
||
|
||
# hBoxLayout
|
||
self.container1 = QWidget()
|
||
self.hBoxLayout1 = QHBoxLayout(self.container1)
|
||
self.hBoxLayout1.addWidget(self.label)
|
||
self.hBoxLayout1.addWidget(self.comboBox)
|
||
|
||
# button
|
||
self.primaryButton1 = PrimaryPushButton(FluentIcon.PLAY, "启动", self)
|
||
self.primaryButton2 = PrimaryPushButton(FluentIcon.PAUSE, "暂停", self)
|
||
self.primaryButton3 = PrimaryPushButton(FluentIcon.POWER_BUTTON, "停止", self)
|
||
self.primaryButton4 = PrimaryPushButton(FluentIcon.ROTATE, "复位", self)
|
||
self.primaryButton5 = PrimaryPushButton(FluentIcon.CLOSE, "急停", self)
|
||
self.primaryButton6 = PrimaryPushButton(FluentIcon.SYNC, "清除", self)
|
||
|
||
self.primaryButton1.setObjectName("primaryButton1")
|
||
self.primaryButton2.setObjectName("primaryButton2")
|
||
self.primaryButton3.setObjectName("primaryButton3")
|
||
self.primaryButton4.setObjectName("primaryButton4")
|
||
self.primaryButton5.setObjectName("primaryButton5")
|
||
self.primaryButton6.setObjectName("primaryButton6")
|
||
|
||
# hBoxLayout2
|
||
self.container2 = QWidget()
|
||
self.hBoxLayout2 = QHBoxLayout(self.container2)
|
||
self.hBoxLayout2.addWidget(self.primaryButton1)
|
||
self.hBoxLayout2.addWidget(self.primaryButton2)
|
||
|
||
# hBoxLayout3
|
||
self.container3 = QWidget()
|
||
self.hBoxLayout3 = QHBoxLayout(self.container3)
|
||
self.hBoxLayout3.addWidget(self.primaryButton3)
|
||
self.hBoxLayout3.addWidget(self.primaryButton4)
|
||
|
||
# hBoxLayout4
|
||
self.container4 = QWidget()
|
||
self.hBoxLayout4 = QHBoxLayout(self.container4)
|
||
self.hBoxLayout4.addWidget(self.primaryButton5)
|
||
self.hBoxLayout4.addWidget(self.primaryButton6)
|
||
|
||
# 滑动条
|
||
self.slider = Slider(Qt.Horizontal)
|
||
self.slider.setFixedWidth(200)
|
||
|
||
# 设置取值范围和当前值
|
||
self.slider.setRange(0, 50)
|
||
self.slider.setValue(20)
|
||
|
||
# Displaylabel
|
||
self.label2 = DisplayLabel("目标袋数")
|
||
self.label3 = DisplayLabel("0")
|
||
self.label3.setObjectName("label3")
|
||
self.label3.setStyleSheet("color: red;")
|
||
self.label4 = DisplayLabel("剩余袋数")
|
||
self.label5 = DisplayLabel("0")
|
||
self.label5.setObjectName("label5")
|
||
self.label5.setStyleSheet("color: green;")
|
||
|
||
# hBoxLayout
|
||
self.container5 = QWidget()
|
||
self.hBoxLayout5 = QHBoxLayout(self.container5)
|
||
self.hBoxLayout5.addWidget(self.label2)
|
||
self.hBoxLayout5.addWidget(self.label3)
|
||
|
||
# hBoxLayout
|
||
self.container6 = QWidget()
|
||
self.hBoxLayout6 = QHBoxLayout(self.container6)
|
||
self.hBoxLayout6.addWidget(self.label4)
|
||
self.hBoxLayout6.addWidget(self.label5)
|
||
|
||
# self.movableCheckBox = CheckBox(self.tr('IsTabMovable'), self)
|
||
# self.scrollableCheckBox = CheckBox(self.tr('IsTabScrollable'), self)
|
||
# self.shadowEnabledCheckBox = CheckBox(self.tr('IsTabShadowEnabled'), self)
|
||
# self.tabMaxWidthLabel = BodyLabel(self.tr('TabMaximumWidth'), self)
|
||
# self.tabMaxWidthSpinBox = SpinBox(self)
|
||
# self.closeDisplayModeLabel = BodyLabel(self.tr('TabCloseButtonDisplayMode'), self)
|
||
# self.closeDisplayModeComboBox = ComboBox(self)
|
||
|
||
self.hBoxLayout = QHBoxLayout(self)
|
||
self.vBoxLayout = QVBoxLayout(self.tabView)
|
||
self.panelLayout = QVBoxLayout(self.controlPanel)
|
||
|
||
# 富文本编辑栏用来显示日志
|
||
self.textBrowser = TextBrowser()
|
||
# self.textBrowser.setMarkdown("## Steel Ball Run \n * Johnny Joestar 🦄 \n * Gyro Zeppeli 🐴 aaa\n * aaa\n * aaa\n * aaa\n * aaa\n *")
|
||
self.textBrowser.setMarkdown(
|
||
"## 日志\n * 2025-08-06 09:54:24 - 🦄进入系统\n * 2025-08-06 09:54:24 - 🐴无回复\n * 2025-08-06 09:54:24 - 🦄进入系统\n * 2025-08-06 09:54:24 - 🐴无回复\n * 2025-08-06 09:54:24 - 🦄进入系统\n * 2025-08-06 09:54:24 - 🐴无回复\n * 2025-08-06 09:54:24 - 🦄进入系统\n * 2025-08-06 09:54:24 - 🐴无回复\n *"
|
||
)
|
||
|
||
# 日志切换按钮
|
||
self.button = SwitchButton()
|
||
# self.button.checkedChanged.connect(
|
||
# lambda checked: print("是否选中按钮:", checked)
|
||
# )
|
||
# 更改按钮状态
|
||
self.button.setChecked(True)
|
||
# 获取按钮是否选中
|
||
self.button.setOffText("报警")
|
||
self.button.setOnText("日志")
|
||
|
||
# 状态按钮
|
||
# PillPushButton(self.tr('Tag'), self, FluentIcon.TAG),
|
||
self.state_button1 = PillPushButton()
|
||
self.state_button1.setFixedHeight(15)
|
||
self.state_button1.setFixedWidth(100)
|
||
|
||
self.state_button2 = PillPushButton("1", self, "")
|
||
self.state_button2.setFixedHeight(15)
|
||
self.state_button2.setFixedWidth(100)
|
||
|
||
self.state_button3 = PillPushButton("0", self, "")
|
||
self.state_button3.setFixedHeight(15)
|
||
self.state_button3.setFixedWidth(100)
|
||
|
||
self.state_button4 = PillPushButton()
|
||
self.state_button4.setFixedHeight(15)
|
||
self.state_button4.setFixedWidth(100)
|
||
|
||
self.state_button5 = PillPushButton("0", self, "")
|
||
self.state_button5.setFixedHeight(15)
|
||
self.state_button5.setFixedWidth(100)
|
||
|
||
self.state_button6 = PillPushButton("0", self, "")
|
||
self.state_button6.setFixedHeight(15)
|
||
self.state_button6.setFixedWidth(100)
|
||
|
||
self.state1 = DisplayLabel("连接状态:")
|
||
self.state2 = DisplayLabel("当前模式:")
|
||
self.state3 = DisplayLabel("远程指令数量:")
|
||
self.state4 = DisplayLabel("当前速度:")
|
||
self.state5 = DisplayLabel("当前工具号:")
|
||
self.state6 = DisplayLabel("报警代码:")
|
||
|
||
# 状态hBoxLayout
|
||
self.state_container1 = QWidget()
|
||
self.state_hBoxLayout1 = QHBoxLayout(self.state_container1)
|
||
self.state_hBoxLayout1.addWidget(self.state1)
|
||
self.state_hBoxLayout1.addWidget(self.state_button1)
|
||
|
||
self.state_container2 = QWidget()
|
||
self.state_hBoxLayout2 = QHBoxLayout(self.state_container2)
|
||
self.state_hBoxLayout2.addWidget(self.state2)
|
||
self.state_hBoxLayout2.addWidget(self.state_button2)
|
||
|
||
self.state_container3 = QWidget()
|
||
self.state_hBoxLayout3 = QHBoxLayout(self.state_container3)
|
||
self.state_hBoxLayout3.addWidget(self.state3)
|
||
self.state_hBoxLayout3.addWidget(self.state_button3)
|
||
|
||
self.state_container4 = QWidget()
|
||
self.state_hBoxLayout4 = QHBoxLayout(self.state_container4)
|
||
self.state_hBoxLayout4.addWidget(self.state4)
|
||
self.state_hBoxLayout4.addWidget(self.state_button4)
|
||
|
||
self.state_container5 = QWidget()
|
||
self.state_hBoxLayout5 = QHBoxLayout(self.state_container5)
|
||
self.state_hBoxLayout5.addWidget(self.state5)
|
||
self.state_hBoxLayout5.addWidget(self.state_button5)
|
||
|
||
self.state_container6 = QWidget()
|
||
self.state_hBoxLayout6 = QHBoxLayout(self.state_container6)
|
||
self.state_hBoxLayout6.addWidget(self.state6)
|
||
self.state_hBoxLayout6.addWidget(self.state_button6)
|
||
|
||
# 日志vboxlayout
|
||
self.container7 = QWidget()
|
||
self.vBoxLayout7 = QVBoxLayout(self.container7)
|
||
self.vBoxLayout7.addWidget(self.button)
|
||
self.vBoxLayout7.addWidget(self.textBrowser)
|
||
|
||
# 状态vboxlayout
|
||
self.container9 = QWidget()
|
||
self.vBoxLayout9 = QVBoxLayout(self.container9)
|
||
self.vBoxLayout9.addWidget(self.state_container1)
|
||
self.vBoxLayout9.addWidget(self.state_container2)
|
||
self.vBoxLayout9.addWidget(self.state_container3)
|
||
self.vBoxLayout9.addWidget(self.state_container4)
|
||
self.vBoxLayout9.addWidget(self.state_container5)
|
||
self.vBoxLayout9.addWidget(self.state_container6)
|
||
|
||
# 日志+状态vboxlayout
|
||
self.container8 = QWidget()
|
||
self.hBoxLayout8 = QHBoxLayout(self.container8)
|
||
self.hBoxLayout8.addWidget(self.container7)
|
||
self.hBoxLayout8.addWidget(self.container9)
|
||
|
||
# self.songInterface = QLabel('Song Interface', self)
|
||
# self.albumInterface = QLabel('Album Interface', self)
|
||
# self.artistInterface = QLabel('Artist Interface', self)
|
||
|
||
# add items to pivot
|
||
self.__initWidget()
|
||
|
||
def __initWidget(self):
|
||
self.initLayout()
|
||
|
||
# self.shadowEnabledCheckBox.setChecked(True)
|
||
|
||
# self.tabMaxWidthSpinBox.setRange(60, 400)
|
||
# self.tabMaxWidthSpinBox.setValue(self.tabBar.tabMaximumWidth())
|
||
|
||
# self.closeDisplayModeComboBox.addItem(self.tr('Always'), userData=TabCloseButtonDisplayMode.ALWAYS)
|
||
# self.closeDisplayModeComboBox.addItem(self.tr('OnHover'), userData=TabCloseButtonDisplayMode.ON_HOVER)
|
||
# self.closeDisplayModeComboBox.addItem(self.tr('Never'), userData=TabCloseButtonDisplayMode.NEVER)
|
||
# self.closeDisplayModeComboBox.currentIndexChanged.connect(self.onDisplayModeChanged)
|
||
|
||
# self.addSubInterface(self.songInterface,
|
||
# 'tabSongInterface', self.tr('Song'), ':/gallery/images/MusicNote.png')
|
||
# self.addSubInterface(self.albumInterface,
|
||
# 'tabAlbumInterface', self.tr('Album'), ':/gallery/images/Dvd.png')
|
||
# self.addSubInterface(self.artistInterface,
|
||
# 'tabArtistInterface', self.tr('Artist'), ':/gallery/images/Singer.png')
|
||
|
||
self.controlPanel.setObjectName("controlPanel")
|
||
StyleSheet.SYSTEM_INTERFACE.apply(self)
|
||
|
||
# self.connectSignalToSlot()
|
||
|
||
# qrouter.setDefaultRouteKey(
|
||
# self.stackedWidget, self.songInterface.objectName())
|
||
|
||
# def connectSignalToSlot(self):
|
||
# self.movableCheckBox.stateChanged.connect(
|
||
# lambda: self.tabBar.setMovable(self.movableCheckBox.isChecked()))
|
||
# self.scrollableCheckBox.stateChanged.connect(
|
||
# lambda: self.tabBar.setScrollable(self.scrollableCheckBox.isChecked()))
|
||
# self.shadowEnabledCheckBox.stateChanged.connect(
|
||
# lambda: self.tabBar.setTabShadowEnabled(self.shadowEnabledCheckBox.isChecked()))
|
||
|
||
# self.tabMaxWidthSpinBox.valueChanged.connect(self.tabBar.setTabMaximumWidth)
|
||
|
||
# self.tabBar.tabAddRequested.connect(self.addTab)
|
||
# self.tabBar.tabCloseRequested.connect(self.removeTab)
|
||
|
||
# self.stackedWidget.currentChanged.connect(self.onCurrentIndexChanged)
|
||
|
||
def initLayout(self):
|
||
# self.tabBar.setTabMaximumWidth(200)
|
||
|
||
# self.setFixedHeight(450)
|
||
self.setMaximumSize(787, 800)
|
||
self.setMinimumSize(450, 450)
|
||
self.controlPanel.setFixedWidth(220)
|
||
self.hBoxLayout.addWidget(self.tabView, 1)
|
||
self.hBoxLayout.addWidget(self.controlPanel, 0, Qt.AlignRight)
|
||
self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
|
||
|
||
# self.vBoxLayout.addWidget(self.tabBar)
|
||
# self.vBoxLayout.addWidget(self.stackedWidget)
|
||
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
|
||
|
||
self.panelLayout.setSpacing(8)
|
||
self.panelLayout.setContentsMargins(14, 16, 14, 14)
|
||
self.panelLayout.setAlignment(Qt.AlignTop)
|
||
|
||
self.panelLayout.addWidget(self.clock)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.comboBox1)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.container1)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.container2)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.container3)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.container4)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.slider)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.container5)
|
||
self.panelLayout.addStretch()
|
||
self.panelLayout.addWidget(self.container6)
|
||
self.panelLayout.addStretch()
|
||
|
||
# self.panelLayout.addWidget(self.movableCheckBox)
|
||
# self.panelLayout.addWidget(self.scrollableCheckBox)
|
||
# self.panelLayout.addWidget(self.shadowEnabledCheckBox)
|
||
|
||
self.panelLayout.addSpacing(4)
|
||
# self.panelLayout.addWidget(self.tabMaxWidthLabel)
|
||
# self.panelLayout.addWidget(self.tabMaxWidthSpinBox)
|
||
|
||
self.panelLayout.addSpacing(4)
|
||
# self.panelLayout.addWidget(self.closeDisplayModeLabel)
|
||
# self.panelLayout.addWidget(self.closeDisplayModeComboBox)
|
||
|
||
# 左边窗口
|
||
# 创建加载框
|
||
# self.loading_button1=ToggleButton(self.tr('Start practicing'), self, FluentIcon.BASKETBALL)
|
||
self.loading_button1 = ToggleButton()
|
||
self.loading_button2 = ToggleButton()
|
||
self.loading_button3 = ToggleButton()
|
||
self.loading_button4 = ToggleButton()
|
||
self.loading1 = DisplayLabel("取料中...")
|
||
self.loading2 = DisplayLabel("拍照中...")
|
||
self.loading3 = DisplayLabel("抓料中...")
|
||
self.loading4 = DisplayLabel("投料中...")
|
||
self.loading_container = QWidget()
|
||
self.loading_hBoxLayout = QHBoxLayout(self.loading_container)
|
||
self.loading_hBoxLayout.addWidget(self.loading_button1)
|
||
self.loading_hBoxLayout.addWidget(self.loading1)
|
||
self.loading_hBoxLayout.addWidget(self.loading_button2)
|
||
self.loading_hBoxLayout.addWidget(self.loading2)
|
||
self.loading_hBoxLayout.addWidget(self.loading_button3)
|
||
self.loading_hBoxLayout.addWidget(self.loading3)
|
||
self.loading_hBoxLayout.addWidget(self.loading_button4)
|
||
self.loading_hBoxLayout.addWidget(self.loading4)
|
||
|
||
self.vBoxLayout.addWidget(self.loading_container)
|
||
|
||
# 创建显示视频的 QLabel
|
||
self.video_label = QLabel()
|
||
self.vBoxLayout.addWidget(self.video_label)
|
||
|
||
# 使用 OpenCV 读取视频
|
||
self.cap = cv2.VideoCapture(
|
||
"./app/resource/video/test.mp4"
|
||
) # 替换为你的视频路径
|
||
if not self.cap.isOpened():
|
||
print("无法打开视频文件!")
|
||
return
|
||
|
||
# 使用 QTimer 定时更新视频帧
|
||
self.timer = QTimer()
|
||
self.timer.timeout.connect(self.update_frame)
|
||
self.timer.start(30) # 30ms 更新一帧(约 33 FPS)
|
||
# self.vBoxLayout.addWidget()
|
||
|
||
# 左边窗口下面的日志栏位和状态栏
|
||
self.vBoxLayout.addWidget(self.container8)
|
||
|
||
def addSubInterface(self, widget: QLabel, objectName, text, icon):
|
||
widget.setObjectName(objectName)
|
||
widget.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
||
# self.stackedWidget.addWidget(widget)
|
||
# self.tabBar.addTab(
|
||
# routeKey=objectName,
|
||
# text=text,
|
||
# icon=icon,
|
||
# onClick=lambda: self.stackedWidget.setCurrentWidget(widget)
|
||
# )
|
||
|
||
# def onDisplayModeChanged(self, index):
|
||
# mode = self.closeDisplayModeComboBox.itemData(index)
|
||
# self.tabBar.setCloseButtonDisplayMode(mode)
|
||
|
||
# def onCurrentIndexChanged(self, index):
|
||
# widget = self.stackedWidget.widget(index)
|
||
# if not widget:
|
||
# return
|
||
|
||
# self.tabBar.setCurrentTab(widget.objectName())
|
||
# qrouter.push(self.stackedWidget, widget.objectName())
|
||
|
||
def update_frame(self):
|
||
ret, frame = self.cap.read()
|
||
if not ret:
|
||
self.timer.stop()
|
||
self.cap.release()
|
||
return
|
||
|
||
# 转换 OpenCV BGR 格式为 RGB,并调整大小以适应 QLabel
|
||
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||
h, w, ch = frame.shape
|
||
bytes_per_line = ch * w
|
||
q_img = QImage(frame.data, w, h, bytes_per_line, QImage.Format_RGB888)
|
||
pixmap = QPixmap.fromImage(q_img)
|
||
self.video_label.setPixmap(
|
||
pixmap.scaled(self.video_label.size())
|
||
) # 自适应窗口大小
|