连接到带参数的函数 [英] Connecting to a function with arguments

查看:34
本文介绍了连接到带参数的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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))

对于任何可调用对象 ba:这意味着使用参数 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆