PyQt:如何将QComboBox连接到带参数的函数

6

使用以下语法将QComboBox连接到函数:

myComboBox.activated.connect(self.myFunction )

但是我需要能够将ComboBox中的参数发送到myFunction()函数。但是如果我使用:

myComboBox.activated.connect(self.myFunction(myArg1, myArg2 )

我正在获得

TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'

如何连接QComboBox到一个能够接收从Comobobox发来的参数的函数?

稍后编辑:

这是导致TypeError错误的代码:

connect()的槽参数应为可调用对象或信号,而不是'NoneType'


from PyQt4 import QtCore, QtGui
import sys

class MyClass(object):
    def __init__(self, arg):
        super(MyClass, self).__init__()
        self.arg = arg        

class myWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(myWindow, self).__init__(parent)

        self.comboBox = QtGui.QComboBox(self)
        self.comboBox.addItems([str(x) for x in range(3)])

        self.myObject=MyClass(id(self) )

        self.comboBox.activated.connect(self.myFunction(self.myObject, 'someArg'))

    def myFunction(self, arg1=None, arg2=None):
        print '\n\t myFunction(): ', type(arg1),type(arg2)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('myApp')
    dialog = myWindow()
    dialog.show()
    sys.exit(app.exec_())

3
把你的代码改成self.comboBox.activated.connect(self.myFunction),就可以了。不需要在连接时指定参数。 - Raydel Miranda
@Raydel:我需要在连接槽时指定参数。如果我在连接槽时不指定参数,那么我如何能够将参数发送到函数中呢?如果不需要发送参数,这就非常简单了。但在这种情况下,需要在连接槽时指定参数。 - alphanumeric
2
@Sputnix 我认为你误解了信号和槽的工作原理。在特定信号上,你不能发送任意类型的参数。QComboBox 的信号 activate 是使用 int 发出的,请参见:http://pyqt.sourceforge.net/Docs/PyQt4/qcombobox.html#activated。因此,你必须定义自己的信号,一个发出你想要的值类型的信号(对于 self.myObjectMyClass,对于 someArgstr)。然后,你可以从处理 activate 事件的函数中发出你的信号。当然,你自己的信号也需要一个处理程序/槽。 - Raydel Miranda
1
@Sputnix 内置的信号已知(这是预定义的)将发送多少个和哪些类型的参数到插槽中。您唯一需要做的就是实现一个准备接收此类参数的插槽。如果信号无法处理您需要的参数类型,那么您需要自定义信号。 - Raydel Miranda
1
@alphanumeric:在尝试将参数传递给myFunction时,您调用了它,因此将None传递给connect而不是myFunction本身。解决方案是使用临时函数包装调用并传递它:lambda: self.myFunction(self.myObject, 'someArg')。这是解决此问题的标准方法。例如,在tkinter中,您也可以以同样的方式解决它。 - z33k
显示剩余3条评论
2个回答

11

我发布了一个问题后,Stackoverflow建议了一个链接,解释了很多内容。这是答案:

from PyQt4 import QtCore, QtGui

class MyClass(object):
    def __init__(self, arg):
        super(MyClass, self).__init__()
        self.arg = arg        

class myWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(myWindow, self).__init__(parent)

        self.comboBox = QtGui.QComboBox(self)
        self.comboBox.addItems([str(x) for x in range(3)])

        self.myObject=MyClass(id(self) )

        slotLambda = lambda: self.indexChanged_lambda(self.myObject)
        self.comboBox.currentIndexChanged.connect(slotLambda)

    @QtCore.pyqtSlot(str)
    def indexChanged_lambda(self, string):
        print 'lambda:', type(string), string

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('myApp')
    dialog = myWindow()
    dialog.show()
    sys.exit(app.exec_())

1
好的,我发现了为什么你在原问题中的代码失败了。难道不值得点赞吗?确实,你找到的代码可以工作,但它并没有解释为什么你的代码一开始会失败。 - Raydel Miranda
1
你应该发布链接,因为虽然我们感谢您花时间发布自己问题的解决方案,但那并不足够。 - Oliver
1
@RaydelMiranda:抱歉,但你实际上没有完成你所声称的事情。代码失败的原因是 connect 方法期望传递给它一个函数对象,但 OP 实际上传递了 None 给它(当他试图向自己的函数传递参数时,他实际上调用了它)。简单的解决方案是在 ad hoc 中包装带其参数调用的 myFunctionlambda: self.myFunction(self.myObject, 'someArg'),但你却引导问题指向插槽和信号机制,而 @alphanumeric 需要的是一个简单的回调。 - z33k

0

推理

在这里,通过装饰器内部传递的activated.connect(yourFunc),您的函数yourFunc有两个参数selfval,而不使用functools.partial。现在,当使用functools.partial时,装饰器将self和传递的参数val放入yourFunc中。请注意,使用partial和不使用partial时参数的顺序。

    # Warning code must go inside extended QWidget class.
    QCombox.activated.connect(yourFunc)
    #! above line will pass two arguments to YourFunc function, so while accessing you can,
    def yourFunc(self,val):
        print(val)

    #________

    from funcTools import partial as pars
    comboList = ["Male","Female"]
    comboBox = QCombox.addItems(combolist)
    comboBox.activated.connect(pars(yourFuncWithCustomArguments,comboList))
    #! above line will pass two arguments to YourFuncWithCArgs function, socWithCustomArgume while accessing you can,
    def yourFuncWithCustomArguments(self,comboList:list[str],val):
        print(comboList[val])


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接