先说方式,我目前接触的有以下几种:
1. 使用exec()
2. 立即执行一次lambda表达式
3. 使用QSignalMapper()
exec()
exec可以执行 Python 代码,用于执行存储在字符串或对象代码中的 Python 语句
# 字母键连接到槽函数
for i in range(97, 123):
exec("""self.char_{0}_.clicked.connect(
self.btn_char_{0}_clicked)""".format(chr(i)))
# 字母键槽函数
for i in range(97, 123):
exec("""
def btn_char_{}_clicked(self):
name = sys._getframe().f_code.co_name
char = self.get_key_symbol(name)
if self.Caps or self.double_Caps:
char = char.upper()
self.Caps = False # 一次一按
self.change_caps_style()
self.data = char
self.send_data()
msg = name + ' 按下 ' + char + ' 发送: ' + self.data
print(msg)
""".format(chr(i)))
lambda表达式
info['data_carrier']的数据类型为QPushButton
lambda表达式中的参数不会立即被调用,只有当lambda表达式被真正执行时,其中的参数当时的数据才会被真正使用
因此会出现一种问题:for循环connect了N个lambda表达式,传参0-N,但是在实际触发时,传入的参数始终是N
为了避免这个问题,应当首先执行一次lambda表达式,利用函数指针
self.info_list = gridLayout_dynamic_create(999, self.rows, self.group, self.ui.gridLayout, None, self)
# 点击事件
for info in self.info_list:
def on_data_carrier_buttons_clicked(data_carrier):
return lambda: self._show_pop_box(data_carrier)
connect_func = on_data_carrier_buttons_clicked(info['data_carrier'])
info['data_carrier'].clicked.connect(connect_func)
QSignalMapper
self.my_mapper = QSignalMapper()
for i, unit in enumerate(units):
self.my_mapper.setMapping(button, i)
button.clicked.connect(self.my_mapper.map)
self.my_mapper.mappedInt.connect(self._fun)