PySide:如何在QPushButton点击槽中获取被点击的QPushButton对象?

13

我是PySide的新手。我想在clicked槽函数中获取QPushButton对象(例如使用它来获取其文本)。

button = QtGui.QPushButton("start go")
button.clicked.connect(self.buttonClick)

def buttonClick(self):
    ... # How can I get the button  object?
    # print button.text()  how to get the text : 'start go' ?

谢谢!

4个回答

20

您可以使用self.sender()来确定发起信号的对象。

在您的代码中,类似以下内容的代码应该可以工作。

button = QtGui.QPushButton("start go")
button.clicked.connect(self.buttonClick)

def buttonClick(self):
    print self.sender().text()

我刚刚测试了一下,但是它出现了一个错误 - tao4yu
2
@tao4yu。示例代码应为:print self.sender().text() - ekhumoro
感谢 @ekhumoro,是我复制粘贴出了问题。 - user764357

20

以下是我解决问题的方法:

button = QtGui.QPushButton("start go")
button.clicked.connect(lambda: self.buttonClick(button))

def buttonClick(self, button):
    print button.text()

5
这可能是避免使用 sender() 最好的方法。但在连接许多循环中的按钮时,使用像这样的 lambda 可能会有些棘手。 - ekhumoro
Lambda函数是什么? - Mr_LinDowsMac
在Python中,lambda创建一个匿名函数,更多信息请参见http://www.secnetix.de/olli/Python/lambda_functions.hawk - qurban
@qurban 我们可以将其写在单独的.py文件中,因为当我们在QT设计师中进行更改并从.ui转换为.py文件时,主窗口文件会发生变化。 - pjrockzzz
1
@pjrockzzz,刚刚看到你的评论,写下来以备将来参考:当你有一个从.ui文件生成的.py文件时,通常不直接编辑那个.py文件来连接信号和槽,而是继承一个子类从.py文件中的类。你可以把这个子类放在单独的.py文件中,并在那里进行连接。 - qurban

1
通常,大多数小部件将在主窗口的设置代码中创建。最好将这些小部件始终添加为主窗口的属性,以便稍后可以轻松访问:
class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None)
        super(MainWindow, self).__init__(parent)
        ...
        self.button = QtGui.QPushButton("start go")
        self.button.clicked.connect(self.buttonClick)
        ...

    def buttonClick(self):
        print(self.button.text())

如果您有许多按钮都使用相同的处理程序,您可以将这些按钮添加到 QButtonGroup 中,并将处理程序连接到其 buttonClicked 信号。此信号可以发送单击的按钮或您自己指定的标识符。
还有一种可能性是使用 self.sender() 来获取发送信号的对象的引用。然而,这有时被认为是不良实践,因为它破坏了使用信号的主要原因(有关此问题的警告,请参见 发件人文档)。

0

我本来想在第一条回答的评论中发表评论,但是我还没有足够的声望 :). 评论是“当连接很多按钮时,使用lambda可能会很棘手。”这正是我在找到这个页面时需要做的。

在循环中这样做行不通:

for button in button_list :
    button.clicked().connect( lambda: self.buttonClick( button )

您的回调函数将始终使用 button_list 中的最后一个按钮进行调用(原因请参见我刚刚发现的此页面上的信息 - https://blog.mister-muffin.de/2011/08/14/python-for-loop-scope-and-nested-functions

请改为使用以下代码,它可以正常工作:

for button in button_list :
    button.clicked().connect( lambda b=button: self.buttonClick( b ))

然而,这里可能会有一个问题... 作为局部变量,小部件的C++对象在回调被调用时可能已经被删除了。我现在遇到了这个问题。 - elenad

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