首页 > 解决方案 > 如何从 QWiget 获取信号以更改获取对象?

问题描述

您好,我有一个 QWidget,如果我点击它,我想获取该对象(我点击的 QWidget 元素)有没有办法做到这一点?

我已经找到了一些代码,但我只得到了 MouseClickEvent

self.widget_34.mouseReleaseEvent = lambda 事件:self.myfunction(event)

标签: pythonpyqtpyqt5

解决方案


尽管@Cin提供的解决方案很有趣,但它有一个严重的问题:它取消了小部件的 mousePressEvent,因此小部件失去了在小部件被按下时可能具有的行为,例如按钮不再发出单击信号,其他小部件也会有同样的问题。

一个侵入性较小的解决方案是使用 eventFilter:

import sys
import weakref
from PyQt5 import QtCore, QtWidgets


class ClickListener(QtCore.QObject):
    clicked = QtCore.pyqtSignal(QtWidgets.QWidget)

    def addWidget(self, widget, other_widget=None):
        if not hasattr(self, "_widgets"):
            self._widgets = {}
        widget.installEventFilter(self)
        self._widgets[widget] = widget if other_widget is None else other_widget
        weakref.ref(widget, self.removeWidget)

    def eventFilter(self, obj, event):
        if (
            obj in self._widgets
            and event.type() == QtCore.QEvent.MouseButtonPress
        ):
            self.clicked.emit(self._widgets[obj])
        return super(ClickListener, self).eventFilter(obj, event)

    def removeWidget(self, widget):
        if hasattr(self, "_widgets"):
            if widget in self._widgets:
                del self._widgets[widget]


class App(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        button = QtWidgets.QPushButton("Press Me")
        label = QtWidgets.QLabel("Stack Overflow")
        spinBox = QtWidgets.QSpinBox()
        te = QtWidgets.QTextEdit()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(button)
        lay.addWidget(label)
        lay.addWidget(spinBox)
        lay.addWidget(te)

        listener = ClickListener(self)
        listener.clicked.connect(self.onClicked)
        listener.addWidget(button)
        listener.addWidget(label)
        listener.addWidget(spinBox.lineEdit(), spinBox)
        listener.addWidget(te.viewport(), te)

    def onClicked(self, obj):
        print("Clicked, from", obj)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

推荐阅读