连接到带参数的函数 [英] Connecting to a function with arguments
问题描述
我正在使用 PyQt 开发用户界面,并最终想出了如何使多个显示选项成为可能(用户单击单选按钮,保存信号,并根据该信号运行不同的功能,当用户点击显示").但是,我遇到了此错误消息:
I'm working on a user interface with PyQt and have finally figured out how to make multiple display options possible (user clicks on a radio button, a signal is saved, and depending on that signal a different function runs when the user hits "display"). I am running into this error message, however:
TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'
而且我认为这与我将带参数的函数传递给connect"方法的事实有关.简而言之,这是我正在查看的代码块:
And I think it has to do with the fact that I'm passing functions with arguments into the "connect" method. Here's the chunk of code I'm looking at, in a nutshell:
from PyQt4 import QtCore, QtGui
import sys
import myFunctions
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_ROIGUI(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setupUi(self)
def setupUi(self, ROIGUI):
#sets up radio buttons and display button in AnalyzeDisplay tab
#i can post more if needed but I haven't messed with it much
self.buttonGroup = QtGui.QButtonGroup(self.AnalyzeDisplay)
self.buttonGroup.addButton(self.radiobutton1,1)
self.buttonGroup.addButton(self.radiobutton2,2)
def retranslateUi(self, ROIGUI):
self.Display.clicked.connect(self.readSignal)
def readSignal(self):
signal = self.buttonGroup.checkedId()
arg1,arg2=myFunctions.loadData()
if signal == -1:
print("No option selected")
elif signal == 1:
self.ROITotalActivity.clicked.connect(lambda: myFunctions.function1(arg1,arg2))
elif signal == 2:
self.ROITimeVActivity.clicked.connect(lambda: myFunctions.function2(arg1))
在选择Display"按钮后调用readSignal"函数,从按钮组中获取信号.有趣的是,即使我收到错误消息,指定的函数(函数 1 和函数 2)似乎仍在运行.我读过 lambda 方法可以用来解决这个问题:
The "readSignal" function is called after the "Display" button has been selected, and the signal is obtained from a button group. The interesting thing is that the specified functions (function1 and function2) appear to run even though I get the error message. I've read that the lambda method can be used to solve this:
self.ROITimeVActivity.clicked.connect(lambda: self.function2(deltaPix))
但是当我尝试实施时出了点问题.虽然我在执行此操作时没有收到错误消息,但连接/信令中的某些内容被搞砸了 - 而不是在单击单选按钮然后单击显示按钮时运行,我想要的功能仅在单击单选按钮时运行--> 显示按钮--> 单选按钮.
But something is going wrong when I try to implement it. Although I don't get the error message when I do this, something in the connection/signaling gets messed up - instead of running when I click the radio button and then the display button, the function I want only runs when I click radio button--> display button--> radio button.
ETA:它本质上是这样的:
ETA: It essentially looks like this:
如果没有 lambda,函数在选择单选按钮并单击显示后运行,但我收到上述错误消息.使用 lambda,我没有收到错误消息,但我必须再次单击单选按钮、显示按钮和单选按钮才能运行该函数.
Without lambda, the functions run after choosing a radio button and clicking display, but I get the above error message. With lambda, I do not get an error message, but I have to click a radio button, the display button, and the radio button again to get the function to run.
想法?提前致谢!
推荐答案
你说:
有趣的是,指定的函数(function1 和功能 2) 似乎在运行,即使我收到错误消息.
The interesting thing is that the specified functions (function1 and function2) appear to run even though I get the error message.
这并不奇怪——您正在调用这些函数之一,并传递该函数的结果(毫无疑问,None
你收到错误信息)到 connect
-- 那是 always,在 Python 中,
Nothing surprising about that -- you're calling one of those functions right here, and passing that function's result (no doubt the None
you get error messaged about) to connect
-- that's always, in Python, the meaning of
a(b(c))
对于任何可调用对象 b
和 a
:这意味着使用参数 c
调用 b
并传递其结果作为 a
的单个参数.
for any callables b
and a
: it means "call b
with argument c
and pass its result as the single argument of a
.
现在当你使用时,
a(lambda: b(c))
您要求 100% 不同的语义 -- 作为 a
的单个参数 函数 传递,稍后调用时(不带参数),然后将使用参数 c
调用 b
".
you're asking for a 100%-different semantics -- passing as a
's single argument a function that, when later called (w/o arguments), will then "call b
with argument c
".
functools.partial(b, c)
可以说是一种比 lambda
更优雅的方法——但产生完全相同的语义.
functools.partial(b, c)
, by the way, is an arguably more elegant approach then lambda
-- but produces exactly the same semantics.
至于为什么这不能为你解决所有问题——我不知道:你展示的代码,用 lambda
修改,应该没问题——如果你没有展示的大量代码中的其他一切都是绝对完美的.所以我怀疑后一个条件不成立.您能否制作一个简单但完整的示例来展示您仍然观察到的错误(一旦应用了 lambda
修复程序)...?
As for why this isn't fixing everything for you -- I don't know: the code you show, amended with lambda
, should be fine -- if everything else in the vast amount of code you don't show was absolutely perfect. So I suspect the latter condition doesn't hold. Can you make a simplified-to-the-bone but complete example that exhibits the bug you still observe (once the lambda
fix is applied)...?
这篇关于连接到带参数的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!