Как установить обработчик событий для включаемого / отключаемого элемента (QTableWidget)?

#python #pyqt #pyqt5

#python #pyqt #pyqt5

Вопрос:

У меня есть QTableWidget, который включается и отключается в зависимости от определенных данных.

У меня есть кнопка, которую я хочу включить, когда включен QTableWidget, и отключить, когда виджет отключен.

Есть ли какой-либо обработчик событий, который позволил бы мне это сделать? Например (и это не работает):

     myTable.changeEvent.connect(lambda: print("test"))
 

В идеале в приведенном выше коде ‘test’ будет печататься каждый раз, когда таблица включается или отключается.

Комментарии:

1. Поскольку вы уже самостоятельно включаете / отключаете подключение, разве вы не можете просто создать для этого сигнал и передать его?

2. Я мог бы, но это немного больше, чем базовый вариант, который я описал. Это просто делает код намного более запутанным, и я пытаюсь избежать этого.

Ответ №1:

Самое простое решение заключается в том, что в тот момент, когда вы деактивируете QTableWidget, вы также деактивируете кнопку (или используете сигнал для передачи информации).

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

 import random
import sys

from PyQt5 import QtCore, QtWidgets


class EnableHelper(QtCore.QObject):
    enableChanged = QtCore.pyqtSignal(bool)

    def __init__(self, widget):
        super().__init__(widget)
        self._widget = widget
        self.widget.installEventFilter(self)

    @property
    def widget(self):
        return self._widget

    def eventFilter(self, obj, event):
        if obj is self.widget and event.type() == QtCore.QEvent.EnabledChange:
            self.enableChanged.emit(self.widget.isEnabled())
        return super().eventFilter(obj, event)


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

        self.table = QtWidgets.QTableWidget(5, 4)
        self.button = QtWidgets.QPushButton("Hello world")

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.table)
        lay.addWidget(self.button)

        helper = EnableHelper(self.table)
        helper.enableChanged.connect(self.button.setEnabled)

        self.test()

    def test(self):
        self.table.setEnabled(random.choice([True, False]))
        QtCore.QTimer.singleShot(1000, self.test)


def main():
    app = QtWidgets.QApplication(sys.argv)
    win = Widget()
    win.show()
    ret = app.exec_()
    sys.exit(ret)


if __name__ == "__main__":
    main()
 

Примечание: ChangeEvent не является сигналом, поэтому вам не следует использовать connect, поскольку это метод класса. Также не рекомендуется использовать его, если вы хотите только определить, изменяет ли виджет состояние с включенного на отключенное или наоборот, поскольку это также вызывается в других случаях.