接着做
3、为指示器设计合适的模型:
新建MyLamp.py,代码如下:
from PyQt5.QtWidgets import QLabelclass MyLamp(QLabel):def __init__(self, parent=None):super().__init__(parent)self.rad = Noneself.blink = Falseself.normal_style = Noneself.style = ''self.off_color = ''self.on_color = ''self.border_color = ''self.lamp = None# self.cal_rad()# self.last = ''def init(self, isRound=True, off_color='#767676', on_color='#039806',border_color='#868686'): # 在部件初始化的时候运行一次if isRound:self.rad = str(round(self.width() / 2))else:self.rad = 2self.off_color = off_color # 默认off颜色self.on_color = on_color # 默认on颜色self.border_color = border_color # 默认的边框颜色def set_color(self, color): # 设置自定义的颜色# self.cal_rad()self.style = f'border-radius:{self.rad}px;background-color:{color};border:1px solid {self.border_color}; 'if not self.blink:self.setStyleSheet(self.style)def set_blink(self): # 启动闪烁self.style = self.styleSheet()self.blink = Truedef reset_blink(self): # 停止闪烁self.blink = Falseself.setStyleSheet(self.style)def blinker(self, color1, color2, bool_in): # 执行闪烁if not self.blink:return Falseif bool_in:self.setStyleSheet(f'border-radius:{self.rad} px;background-color: {color1}')else:self.setStyleSheet(f'border-radius:{self.rad} px;background-color: {color2}')def color_on_bool(self, bool_in): # 由输入的bool来控制颜色的显示,默认为on:绿色,off:灰色if bool_in:self.style = f'border-radius:{self.rad}px;background-color:{self.on_color}; border:1px solid {self.border_color};'else:self.style = f'border-radius: {self.rad}px;background-color:{self.off_color}; border:1px solid {self.border_color};'self.setStyleSheet(self.style)def color_on_bit(self, bytes_in, n): # 由输入的字的某一位l来控制颜色的显示,默认为on:绿色,off:灰色if bytes_in >> n & 1:self.style = f'border-radius: {self.rad}px;background-color:{self.on_color}; border:1px solid {self.border_color};'else:self.style = f'border-radius:{self.rad} px;background-color:{self.off_color}; border:1px solid solid {self.border_color};'self.setStyleSheet(self.style)
打开Qt设计师,将MyLamp加入“提升的窗口部件”,并将几个指示器全部“提升为”MyLamp”。
4、至此,所有的子部件都已经创建完毕。现在创建容器部件(父部件):
新建MySelectorBox.py,代码如下:
# 自定义的多选一选择器
from PyQt5.QtWidgets import QGroupBox, QLabel, QWidget
from PyQt5.Qt import pyqtSignalclass MySelectorBox(QGroupBox):def __init__(self, parent=None):super().__init__(parent)self.start_on = 0 # 初始为on的序号self.controls = [] # 所有的控制器self.states = [] # 所有的状态指示器def init(self): # 需要在部件初始化的时候运行一次_ = self.findChildren(QWidget) # 查找子部件 for i in range(len(_)): # 查找子部件n = _[i].objectName().find('_control') # 子部件的名称是‘_control’if n != -1:t = f'self.control{_[i].objectName()[n + 8]}'exec(f'{t} = _[{i}]') # 将控制器的变量定义映射到查找到的对应子部件,这里最多可以有10个控制器,如果超过10个,需要修改程序exec(f'self.controls.append({t})')continuen = _[i].objectName().find('_state') # 子部件的名称是‘_state’if n != -1:t = f'self.state{_[i].objectName()[n + 6]}'exec(f'{t} = _[{i}]') # 将指示器的变量定义映射到查找到的对应子部件,这里最多可以有10个指示器,如果超过10个,需要修改程序exec(f'self.states.append({t})')self.controls.sort(key=lambda child: child.objectName()) # 根据名称排序self.states.sort(key=lambda child: child.objectName()) # 根据名称排序# for _ in self.controls:# try:# _.init()# except AttributeError:# continue# for _ in self.states:# try:# _.init()# except AttributeError:# continueself.connect() # 信号的连接def connect(self): # 信号的连接for i in range(len(self.controls)):def callback(idx):return lambda: self.toggle_states(idx)self.controls[i].clicked.connect(callback(i))def toggle_states(self, n): # 切换指示器的显示状态for i in range(len(self.states)):if i == n:self.states[i].set_color(self.states[i].on_color) # 点亮对应的指示器else:self.states[i].set_color(self.states[i].off_color) # 熄灭对应的指示器
打开Qt设计师,将MySelectorBox加入“提升的窗口部件”,并将_selector_1“提升为”MySelectorBox“。
5、修改主程序,代码如下:
from PyQt5 import uic
from sys import exit, argv
from PyQt5.QtWidgets import QApplication, QWidgetif __name__ == '__main__':app = QApplication(argv)# 读取 UI 文件并转换为 Python 代码ui_file = '../UIS/test2.ui' # 更换为实际的ui文件地址form0 = uic.loadUi(ui_file) # 创建显示界面# 初始化form0._selector_1.init()form0._selector_1.control0.init()form0._selector_1.control1.init()# form0._selector_1.control2.init()form0._selector_1.control2.init(style_enter='border:1px solid #868686;border-radius:2px;background-color: rgba(194, 56, 37, 200);') # 控制器的control2需要单独定义form0._selector_1.state0.init()form0._selector_1.state1.init()form0._selector_1.state2.init()form0.show()exit(app.exec_())
运行截图:
至此,组合部件的建设基本完成。
如果需要多个相同的组合部件,只需要再Qt设计师里面简单的复制粘贴即可。例如,三个相同的选择器:将第一个选择器简单复制粘贴即可。
然后在主程序中增加另外两个选择器的初始化代码 :
from PyQt5 import uic
from sys import exit, argv
from PyQt5.QtWidgets import QApplication, QWidgetif __name__ == '__main__':app = QApplication(argv)# 读取 UI 文件并转换为 Python 代码ui_file = '../UIS/test2.ui' # 更换为实际的ui文件地址form0 = uic.loadUi(ui_file) # 创建显示界面# 初始化form0._selector_1.init()form0._selector_1.control0.init()form0._selector_1.control1.init()# form0._selector_1.control2.init()form0._selector_1.control2.init(style_enter='border:1px solid #868686;border-radius:2px;background-color: rgba(194, 56, 37, 200);') # 控制器的control2需要单独定义form0._selector_1.state0.init()form0._selector_1.state1.init()form0._selector_1.state2.init()form0._selector_2.init()form0._selector_2.control0.init()form0._selector_2.control1.init()form0._selector_2.control2.init()form0._selector_2.state0.init()form0._selector_2.state1.init()form0._selector_2.state2.init()form0._selector_3.init()form0._selector_3.control0.init()form0._selector_3.control1.init()form0._selector_3.control2.init()form0._selector_3.state0.init()form0._selector_3.state1.init()form0._selector_3.state2.init()form0.show()exit(app.exec_())
运行截图:
可以看到,主程序中仍然必须有每一个部件的init()语句,所以,下一步的任务就是要把部件的init()语句自动或半自动隐式执行。