通过 connect 传递额外参数
- 2024-12-20 08:37:00
- admin 原创
- 77
问题描述:
是否可以通过插槽传递变量以便我可以打印出某些文本?尝试将在另一个函数中定义的变量“DiffP”传递给插槽。
“DiffP” 根据所选文件而变化。
def addLineEdit(self):
try:
self.clearLayout()
self.FileButton ={}
self.Input = {}
self.TotalInput = []
for i in range(int(self.numberLine.text())):
self.FileButton[i] = QtWidgets.QPushButton(self.centralwidget)
self.FileButton[i].setText('Case {}'.format(i+1))
self.FileButton[i].setFlat(True)
self.FileButton[i].setMaximumSize(QtCore.QSize(50, 50))
self.hboxlayout[0].addWidget(self.FileButton[i])
self.FileButton[i].clicked.connect(lambda i=i: self.openfile(i))
self.buttonGroup.addButton(self.FileButton[i],i)
self.buttonGroup.buttonClicked['int'].connect(self.input)
def searchfile(self,dir):
with open(dir) as f:
content = f.readlines()
MainList = content[44].split()
RPM = round(float(MainList[0]), 2)
Ps = round(float(MainList[1]), 2)
Ts = round(float(MainList[2]), 2)
Pd = round(float(MainList[3]), 2)
Ratio = round(Pd / Ps, 2)
DiffP = round(Pd - Ps, 2)
@pyqtSlot(int)
def input(self,button_or_id,DiffP):
if isinstance(button_or_id, int):
if button_or_id == 0:
self.TotalInput[0].setText(str(DiffP))
elif button_or_id == 1:
self.TotalInput[54].setText('1')
def openfile(self,i):
filename = QtWidgets.QFileDialog.getOpenFileName(self, 'Choose file')
dir = filename[0]
directory = os.path.split(dir)[0]
return self.searchfile(dir)
解决方案 1:
这个问题可以通过两种方式解决:
使用 lambda 函数:
一般来说:
obj.signal.connect(lambda param1, param2, ..., arg1=val1, arg2= value2, ... : fun(param1, param2,... , arg1, arg2, ....))
def fun(param1, param2,... , arg1, arg2, ....):
[...]
在哪里:
param1, param2, ... :是信号发送的参数
arg1、arg2、...:是您想要使用的额外参数
就你的情况而言:
self.buttonGroup.buttonClicked['int'].connect(lambda i: self.input(i, "text"))
@pyqtSlot(int)
def input(self, button_or_id, DiffP):
if isinstance(button_or_id, int):
if button_or_id == 0:
self.TotalInput[0].setText(DiffP)
elif button_or_id == 1:
self.TotalInput[54].setText('1')
使用functools.partial
:
一般来说:
obj.signal.connect(partial(fun, args1, arg2, ... ))
def fun(arg1, arg2, ..., param1, param2, ...):
[...]
在哪里:
param1, param2, ... :是信号发送的参数
arg1、arg2、...:是您要发送的额外参数
就你的情况而言:
from functools import partial
[...]
self.buttonGroup.buttonClicked['int'].connect(partial(self.input, "text"))
@pyqtSlot(int)
def input(self, DiffP, button_or_id):
if isinstance(button_or_id, int):
if button_or_id == 0:
self.TotalInput[0].setText(DiffP)
elif button_or_id == 1:
self.TotalInput[54].setText('1')
解决方案 2:
其他答案中建议的方法存在问题,
self.whatever.connect(lambda x: self.method(..., x)) # approach 1 (suboptimal)
self.whatever.connect(functools.partial(self.method, ...)) # approach 2 (suboptimal)
也就是说,它们会创建一个引用循环:对象self
持有对带有信号的对象的引用(或本身就是该对象),而信号持有对函数或partial
对象的引用,函数或对象持有对该对象的引用self
。结果是(在 CPython 中)当对它们的所有其他引用消失时,这些对象都不会被垃圾回收;它们只会在下次循环收集器运行时被回收。它们反过来会保持它们引用的所有其他 Python 数据结构以及它们共同拥有的任何 Qt 对象处于活动状态。这不完全是内存泄漏,因为所有内容最终都会被释放,但这可能是一个问题。
如果你这样写,就不会出现引用循环
self.whatever.connect(self.method)
因为在 PyQt 和 PySide 中,connect
Python 绑定方法对象都有一个特殊情况:它仅包含对“自身”对象的弱引用。functools.partial
不返回connect
可识别的特定类型的对象。但您可以定义一个functools.partial
返回该类型的替代品,这样您就可以获得避免循环的行为:
def partial_bound_method(bound_method, *args, **kwargs):
f = functools.partialmethod(bound_method.__func__, *args, **kwargs)
# NB: the seemingly redundant lambda is needed to ensure the correct result type
return (lambda *args: f(*args)).__get__(bound_method.__self__)
...
self.whatever.connect(partial_bound_method(self.method, ...)) # approach 2' (better)
请参阅这个较长的答案以了解更多详细信息。
相关推荐
热门文章
项目管理软件有哪些?
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件
热门标签
云禅道AD