Как получить сигнал от QWiget, чтобы изменить объект get? - PullRequest
0 голосов
/ 16 июня 2019

Здравствуйте, у меня есть QWidget, и если я щелкаю по нему, я хочу получить объект (элемент QWidget, на который я щелкнул), есть ли способ сделать это?

Я уже нашел некоторый код, но я толькополучить MouseClickEvent от

self.widget_34.mouseReleaseEvent = лямбда-событие: self.myfunction (event)

Ответы [ 2 ]

1 голос
/ 16 июня 2019

Хотя решение, предлагаемое @ 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_())
0 голосов
/ 16 июня 2019

Я не уверен, что это будет правильное решение или нет, но я думаю, вы можете использовать частичный метод модуля functools . Сложный объект можно рассматривать как функцию для целей этого модуля. Здесь вы можете увидеть мой пример,

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
import functools

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(200,200,200,200)

        self.button = QPushButton('Button', self)
        self.button.move(50,50)

        self.label = QLabel(self)
        self.label.setText("Label")
        self.label.move(100,100)

        self.items = [self.button, self.label]

        for i in self.items:
            i.mousePressEvent = functools.partial(self.getClickedItem, source_object=i)

        self.show()

    def getClickedItem(self, event, source_object=None):
        print("Clicked, from", source_object)
        #item text
        #print(source_object.text()) 

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...