接着做
3、为指示器设计合适的模型:
新建MyLamp.py,代码如下:
from PyQt5.QtWidgets import QLabel
class MyLamp(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.rad = None
self.blink = False
self.normal_style = None
self.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 = 2
self.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 = True
def reset_blink(self): # 停止闪烁
self.blink = False
self.setStyleSheet(self.style)
def blinker(self, color1, color2, bool_in): # 执行闪烁
if not self.blink:
return False
if 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 pyqtSignal
class 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})')
continue
n = _[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:
# continue
self.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, QWidget
if __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, QWidget
if __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()语句自动或半自动隐式执行。