简体   繁体   English

将参数传递给PyQt SIGNAL连接

[英]Passing argument to PyQt SIGNAL connection

Is it possible to pass an argument to PyQt4 Signal connections? 是否可以将参数传递给PyQt4信号连接? In my case I have n buttons with set the same menu dinamically created on the interface, depending on user's input: 在我的情况下,我有n个按钮,这些按钮具有在界面上动态创建的相同菜单,具体取决于用户的输入:

for j in range(0, len(self.InputList)):

    arrow = QtGui.QPushButton(Form)
    arrow.setGeometry(QtCore.QRect(350, 40*(j+3)+15, 19, 23))

    menu = QtGui.QMenu(Form)
    for element in SomeList:
        cb = QtGui.QRadioButton(element,menu)
        ca = QtGui.QWidgetAction(menu)
        ca.setDefaultWidget(cb)
        QtCore.QObject.connect(cb,QtCore.SIGNAL("stateChanged(int)"),self.SomeFunction)
    arrow.setMenu(menu)  

Although the menu is the same for all the buttons into the interface, the user should be able to select a value from any of the buttons and, for any of them, the action is the same ("add the selected value to a line edit") with the only difference that the line edit might be the 1st as well as the 2nd , the 3rd . 尽管进入界面的所有按钮的菜单都是相同的,但用户应该能够从任何按钮中选择一个值,并且对于任何一个按钮,操作都是相同的(“将所选值添加到行编辑中“),唯一不同的是,行编辑可能是第1 2个 ,第3个

What I would like to ask, then, is if there's any way to pass an argument j here: 那么,我想问的是,是否有任何方法可以在此处传递参数j

QtCore.QObject.connect(cb,QtCore.SIGNAL("stateChanged(int)"),self.SomeFunction(j))

EXAMPLE : 范例

At this execution the user's inputs are 3, so I will have 3 line edits and three push buttons with the same menu: 在此执行中,用户输入为3,因此我将进行3行编辑和具有相同菜单的三个按钮:

Line Edit 1:
Line Edit 2:
Line Edit 3:

Using the same function SomeFunction , I'd like to edit the value of the Line Edits. 使用相同的功能SomeFunction ,我想编辑Line Edits的值。 So if the user is touching the menu attached to the 2nd line edit, the function SomeFunction shall be called with the argument 2 SomeFunction(2) , so the same method will understand itself which Line Edit is the right one: 因此,如果用户触摸附加到第二行编辑的菜单,则应使用参数2 SomeFunction(2)调用功能SomeFunction ,因此相同的方法将了解自身哪个行编辑是正确的:

Line Edit 1:
Line Edit 2: modified
Line Edit 3: 

I need this because the number of Line Edits on the main window depends on what the user is selecting. 我需要这样做是因为主窗口上的“行编辑”数量取决于用户选择的内容。 I'm a newbie and so far I've always created one function for any object into the GUI, but this time the number is dynamic and I'm sure there are some more elegant ways to create this kind of signal connections, that I have not understood though so far from my documentations reading. 我是一个新手,到目前为止,我一直为GUI中的任何对象创建一个函数,但是这次数字是动态的,并且我确定有一些更优雅的方法可以创建这种信号连接,虽然到目前为止我的文档阅读还不了解。

Be advised that you are using a deprecated version of SIGNAL/SLOT implementation in PyQt that has been removed in PyQt5 (and even its current implementation in PyQt4 is somewhat buggy). 请注意,您在PyQt中使用了不赞成使用的SIGNAL / SLOT实现,而该版本已在PyQt5中删除 (甚至在PyQt4中当前的实现也有问题)。

If possible, I would change the SIGNAL/SLOT syntax in your code. 如果可能的话,我会在您的代码中更改SIGNAL / SLOT语法。

The way the new Signal/Slot mechanism works is this: 新的信号/插槽机制的工作方式如下:

class Worker(QThread):
    stateChanged = Signal(int)

    ....

    def some_method(self):
        self.stateChanged.emit(1)

In the GUI thread, you would similarly have something like this (assuming worker = Worker() is defined somewhere: 在GUI线程中,您将类似地具有以下内容(假设worker = Worker()在某处定义:

class GUI(QDialog)

    worker = Worker()

    def __init__(self, parent=None):
        super(GUI, self).__init__(parent)
        self.worker.stateChanged.connect(self.my_desired_method)

    def my_desired_method(self, param):
        print param #prints out '1'

Of course, this code wouldn't work "out of the box", but it's a general concept of how Signals/Slots should be handled in PyQt (and PySide). 当然,此代码无法“开箱即用”地工作,但这是应如何在PyQt(和PySide)中处理信号/插槽的一般概念。

Here is a different approach: instead of attaching the data as an argument to the signal handler, attach it to the menu-item itself. 这是另一种方法:将数据作为参数附加到信号处理程序,而不是将其附加到菜单项本身。 This offers much greater flexibility, because the data is not hidden inside an anonymous function, and so can be accessed by any part of the application. 这提供了更大的灵活性,因为数据没有隐藏在匿名函数中,因此可以被应用程序的任何部分访问。

It is very easy to implement, because Qt already provides the necessary APIs. 这很容易实现,因为Qt已经提供了必要的API。 Here is what your example code would look like if you took this approach: 如果采用这种方法,则示例代码如下所示:

        for j in range(0, len(self.InputList)):

            arrow = QtGui.QPushButton(self)
            arrow.setGeometry(QtCore.QRect(350, 40*(j+3)+15, 19, 23))

            menu = QtGui.QMenu(self)
            group = QtGui.QActionGroup(menu)
            for element in SomeList:
                action = menu.addAction(element)
                action.setCheckable(True)
                action.setActionGroup(group)
                action.setData(j)
            arrow.setMenu(menu)

            group.triggered.connect(self.SomeFunction)

    def SomeFunction(self, action):
        print(action.data())

I think this should help. 我认为这应该有所帮助。

self.op = "point"
QtCore.QObject.connect(self.radioButton, QtCore.SIGNAL("clicked(bool)"),lambda : self.anyButton(self.radioButton.isChecked(),self.op))

def anyButton(self,kol,vv):
    print kol
    print vv

The output is 输出是

>>> 
True
point

you can take a look at this : PyQt sending parameter to slot when connecting to a signal 您可以看一下: 连接信号时PyQt将参数发送到插槽

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM