亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何斷言 PyQt5 信號的身份?

如何斷言 PyQt5 信號的身份?

慕哥9229398 2021-11-09 20:19:16
我想斷言 PyQt5 信號的身份。具體來說,我想檢查clicked來自給定QPushButton對象的信號是否與存儲在名為 的變量中的信號相同signal。以下代碼段說明了這種情況:from PyQt5.QtWidgets import QApplication, QPushButtonapp = QApplication([])widget = QPushButton()signal = widget.clickedwidget.clicked == signalOut[1]: Falsewidget.clicked is signalOut[2]: Falseid(widget.clicked) == id(signal)Out[3]: False如圖所示,分別涉及==、is和的三個比較id()都產生False,即它們不能斷言左手和右手參數的同一性。有沒有辦法斷言widget.clicked并signal引用相同的信號?
查看完整描述

2 回答

?
慕斯王

TA貢獻1864條經驗 獲得超2個贊

每次調用時都會創建作為實體的信號,因為它們代表不同的連接:


In [1]: import sys


In [2]: from PyQt5 import QtWidgets


In [3]: app = QtWidgets.QApplication(sys.argv)


In [4]: button = QtWidgets.QPushButton()


In [5]: id(button.clicked)

Out[5]: 140150155639464


In [6]: id(button.clicked)

Out[6]: 140150154507528


In [7]: id(button.clicked)

Out[7]: 140150155640184


In [8]: id(button.clicked)

Out[8]: 140150155640504


In [9]: id(button.clicked)

Out[9]: 140150154510128


In [10]: id(button.clicked)

Out[10]: 140149427454320

因此,如果在同一個信號和插槽之間連接 100 次,并且在發出信號時,該插槽將被調用 100 次:


import sys

from PyQt5 import QtCore, QtWidgets


def foo():

    print("clicked")


if __name__ == '__main__':


    app = QtWidgets.QApplication(sys.argv)

    button = QtWidgets.QPushButton("Press me")

    button.show()

    for _ in range(10):

        button.clicked.connect(foo)

    # the click is emulated

    QtCore.QTimer.singleShot(1000, lambda: button.animateClick(500))

    QtCore.QTimer.singleShot(2000, app.quit)

    sys.exit(app.exec_())

輸出:


clicked

clicked

clicked

clicked

clicked

clicked

clicked

clicked

clicked

clicked

所以直接解決你的問題是不可能的,但我認為你的目標是區分哪個對象發出調用插槽的信號,因為你可能有幾個對象連接到同一個插槽,如果有解決方案:


一、使用sender()方法

如果插槽屬于 QObject(或從 QObject 派生的類作為小部件),那么您可以使用 sender 方法獲取發出信號的對象。


import sys

from PyQt5 import QtCore, QtWidgets


class Widget(QtWidgets.QWidget):

    def __init__(self, parent=None):

        super(Widget, self).__init__(parent)


        self.button_1 = QtWidgets.QPushButton("button 1")

        self.button_1.clicked.connect(self.foo)

        self.button_2 = QtWidgets.QPushButton("button 2")

        self.button_2.clicked.connect(self.foo)

        self.button_3 = QtWidgets.QPushButton("button 3")

        self.button_3.clicked.connect(self.foo)


        lay = QtWidgets.QVBoxLayout(self)

        lay.addWidget(self.button_1)

        lay.addWidget(self.button_2)

        lay.addWidget(self.button_3)


    @QtCore.pyqtSlot()

    def foo(self):

        button = self.sender()

        if button is self.button_1:

            print("button_1")

        elif button is self.button_2:

            print("button_2")

        elif button is self.button_3:

            print("button_3")


if __name__ == '__main__':


    app = QtWidgets.QApplication(sys.argv)

    w = Widget()

    w.show()

    sys.exit(app.exec_())

2. 將對象作為附加參數傳遞

2.1 拉姆達函數

import sys

from PyQt5 import QtCore, QtWidgets


class Widget(QtWidgets.QWidget):

    def __init__(self, parent=None):

        super(Widget, self).__init__(parent)


        self.button_1 = QtWidgets.QPushButton("button 1")

        self.button_1.clicked.connect(lambda *args, b=self.button_1 : self.foo(b))

        self.button_2 = QtWidgets.QPushButton("button 2")

        self.button_2.clicked.connect(lambda *args, b=self.button_2 : self.foo(b))

        self.button_3 = QtWidgets.QPushButton("button 3")

        self.button_3.clicked.connect(lambda *args, b=self.button_3 : self.foo(b))


        lay = QtWidgets.QVBoxLayout(self)

        lay.addWidget(self.button_1)

        lay.addWidget(self.button_2)

        lay.addWidget(self.button_3)


    def foo(self, button):

        if button is self.button_1:

            print("button_1")

        elif button is self.button_2:

            print("button_2")

        elif button is self.button_3:

            print("button_3")


if __name__ == '__main__':


    app = QtWidgets.QApplication(sys.argv)

    w = Widget()

    w.show()

    sys.exit(app.exec_())

2.1 functools.partial 函數

import sys

from PyQt5 import QtCore, QtWidgets

from functools import partial


class Widget(QtWidgets.QWidget):

    def __init__(self, parent=None):

        super(Widget, self).__init__(parent)


        self.button_1 = QtWidgets.QPushButton("button 1")

        self.button_1.clicked.connect(partial(self.foo, self.button_1))

        self.button_2 = QtWidgets.QPushButton("button 2")

        self.button_2.clicked.connect(partial(self.foo, self.button_2))

        self.button_3 = QtWidgets.QPushButton("button 3")

        self.button_3.clicked.connect(partial(self.foo, self.button_3))


        lay = QtWidgets.QVBoxLayout(self)

        lay.addWidget(self.button_1)

        lay.addWidget(self.button_2)

        lay.addWidget(self.button_3)


    def foo(self, button):

        if button is self.button_1:

            print("button_1")

        elif button is self.button_2:

            print("button_2")

        elif button is self.button_3:

            print("button_3")


if __name__ == '__main__':


    app = QtWidgets.QApplication(sys.argv)

    w = Widget()

    w.show()

    sys.exit(app.exec_())

就我而言,如果可以使用,我更喜歡使用 sender,然后是 functools.partial,最后是 lambda 方法


查看完整回答
反對 回復 2021-11-09
?
胡子哥哥

TA貢獻1825條經驗 獲得超6個贊

嘗試一下:


import sys

from PyQt5.QtWidgets import QApplication, QPushButton


app = QApplication([])


def clickButton(w):

    # Check what you clicked here.                        # <-----

    return print(w.text())


widget  = QPushButton('Button 1')

widget.clicked.connect(lambda : clickButton(widget))


widget2 = QPushButton('Button 2')

widget2.clicked.connect(lambda : clickButton(widget2))


widget.setGeometry(300, 150, 100, 100)

widget.show()


widget2.setGeometry(450, 150, 100, 100)

widget2.show()


sys.exit(app.exec_())

http://img1.sycdn.imooc.com//618a676b0001e53604160160.jpg

查看完整回答
反對 回復 2021-11-09
  • 2 回答
  • 0 關注
  • 230 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號