from PySide6.QtWidgets import (QWidget, QPushButton, QVBoxLayout, QSizePolicy) from PySide6.QtCore import Signal, Qt, QObject from PySide6.QtGui import QFont class FrequencyButtonGroup(QWidget): """振捣频率选择按钮组""" # 该信号frequency_changed,用于振捣频率的控制逻辑,表示需要按照int类型的频率开始振捣 frequency_changed = Signal(int) # 选中切换信号(新选中频率) # 该信号frequency_cleared,用于停止振捣 frequency_cleared = Signal() # 取消选中信号(无参数) def __init__(self, parent=None): super().__init__(parent) self.setFixedSize(115, 159) self._init_ui() self._selected_freq = None # 当前选中的频率(None表示未选中) def _init_ui(self): """初始化UI:垂直排列3个按钮, 设置样式和交互""" # 1. 布局:垂直排列,间隔16px self.layout = QVBoxLayout(self) self.layout.setSpacing(16) # 按钮间间隔16px self.layout.setContentsMargins(0, 0, 0, 0) # 去除外层边距 self.layout.setAlignment(Qt.AlignCenter) # 按钮垂直居中 # 2. 按钮配置:频率列表、样式 self.freq_buttons = {} # 存储按钮映射:{频率值: 按钮实例} freq_list = [220, 230, 240] # 频率设置,设置三个频率 font = QFont() font.setPointSize(15) # 字体大小15px for freq in freq_list: btn = QPushButton(f"{freq}Hz", self) btn.setFont(font) btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # 固定尺寸 btn.setFixedSize(96, 36) # 按钮固定大小(匹配背景图尺寸) btn.setCursor(Qt.PointingHandCursor) # 3. 绑定点击事件 btn.clicked.connect(lambda checked, target_freq=freq: self._on_btn_clicked(target_freq)) # 4. 设置默认样式(未选中状态) self._set_btn_style(btn, is_selected=False) # 5. 添加到布局和映射表 self.layout.addWidget(btn) self.freq_buttons[freq] = btn # 6. 禁止布局拉伸(按钮垂直居中,不填充多余空间) self.layout.addStretch() def _set_btn_style(self, btn, is_selected: bool): """设置按钮样式""" if is_selected: btn.setStyleSheet(""" QPushButton { background-image: url(images/频率按钮2.png); background-repeat: no-repeat; background-position: center; background-origin: content-box; background-clip: content-box; color: #05267d; border: none; padding: 0px; } QPushButton:hover { opacity: 0.95; background-image: url(images/频率按钮2.png); background-repeat: no-repeat; background-position: center; background-origin: content-box; background-clip: content-box; } """) else: btn.setStyleSheet(""" QPushButton { background-image: url(images/频率按钮1.png); background-repeat: no-repeat; background-position: center; background-origin: content-box; background-clip: content-box; color: #3bfff8; border: none; padding: 0px; } QPushButton:hover { opacity: 0.95; background-image: url(images/频率按钮1.png); background-repeat: no-repeat; background-position: center; background-origin: content-box; background-clip: content-box; } """) btn.repaint() def _on_btn_clicked(self, target_freq): """按钮点击事件:支持切换选中/取消选中""" if target_freq == self._selected_freq: self.clear_selection() self.frequency_cleared.emit() return if self._selected_freq is not None: prev_btn = self.freq_buttons[self._selected_freq] self._set_btn_style(prev_btn, is_selected=False) current_btn = self.freq_buttons[target_freq] self._set_btn_style(current_btn, is_selected=True) self._selected_freq = target_freq self.frequency_changed.emit(target_freq) def _set_frequency_show(self, target_freq:int): """设置振捣频率, 只修改显示, 不控制变频器""" if self._selected_freq is not None: prev_btn = self.freq_buttons[self._selected_freq] self._set_btn_style(prev_btn, is_selected=False) current_btn = self.freq_buttons[target_freq] self._set_btn_style(current_btn, is_selected=True) self._selected_freq = target_freq # ------------------- 外部接口 ------------------- def set_selected_frequency(self, freq: int): """ 设置显示选中的频率, 只显示不控制 """ try: freq_int = int(freq) if freq_int not in self.freq_buttons: # 除了220、230、240,其他的数值(比如:0)都表示取消显示的频率 self.clear_selection() return self._set_frequency_show(freq_int) except (ValueError, TypeError): pass # 传入的振捣频率类型错误,维持原频率 def get_selected_frequency(self): """获取当前选中的频率(外部接口),没有选中返回None""" return self._selected_freq def clear_selection(self): """清除所有选中状态(内部调用+外部接口)""" if self._selected_freq is not None: prev_btn = self.freq_buttons[self._selected_freq] self._set_btn_style(prev_btn, is_selected=False) self._selected_freq = None