Как обрабатывать события колеса QComboBox с помощью фильтра событий?Python

Программы на Python
Ответить
Anonymous
 Как обрабатывать события колеса QComboBox с помощью фильтра событий?

Сообщение Anonymous »


В Qt6 многие виджеты (QComboBox, QSpinBox) крадут события колесика мыши, которые должны обрабатываться их родительским виджетом (например, QScrollArea), даже если у них нет фокуса и даже когда focusPolicy< /code> установлено значение StrongFocus.

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

класс MyComboBox(QtWidgets.QComboBox): defwheelEvent(self, event: QtGui.QWheelEvent) -> Нет: если не self.hasFocus(): событие.игнорировать() еще: супер().wheelEvent(событие) Qt предлагает другой способ игнорировать события с помощью installEventFilter, который кажется гораздо более масштабируемым и элегантным, поскольку я могу создать один фильтр событий и применить его к любому количеству различных виджетов.

class WheelEventFilter(QtCore.QObject): """Игнорирует события колеса, когда виджет еще не находится в фокусе.""" def eventFilter(self, смотрел: QtCore.QObject, событие: QtCore.QEvent) -> bool: если ( isinstance(просматривалось, QtWidgets.QWidget) и не смотрел.hasFocus() и event.type() == QtCore.QEvent.Type.Wheel ): # Это фильтрует событие, но также останавливает его # от распространения до родительского виджета. вернуть истину # На самом деле это не игнорирует событие для данного виджета. событие.игнорировать() вернуть ложь еще: вернуть super().eventFilter(просмотренное, событие) Однако моя проблема в том, что этот фильтр событий не фильтрует события так, как я ожидал. Я ожидаю, что он отфильтрует событие только для просматриваемого объекта, а также позволит передать событие родительскому виджету для обработки, но этого не происходит. .

Можно ли добиться того же эффекта, что и обработчик wheelEvent, определенный выше, с помощью eventFilter?

Вот автономный воспроизводимый пример, демонстрирующий такое поведение. Если вы попытаетесь прокрутить область прокрутки, наведя указатель мыши на одно из полей со списком, поле со списком украдет фокус и событие колеса.
импортировать систему из PySide6 импортировать QtWidgets, QtCore класс MyWidget(QtWidgets.QWidget): def __init__(self) -> Нет: супер().__init__() # # макет self._layout = QtWidgets.QVBoxLayout() self.setLayout(self._layout) # макет виджета self._mainwidget = QtWidgets.QWidget() self._mainlayout = QtWidgets.QVBoxLayout() self._mainwidget.setLayout(self._mainlayout) # виджеты для виджета self._widgets = {} число_виджетов = 20 для меня в диапазоне (num_widgets): комбо = QtWidgets.QComboBox() combo.addItems([str(x) для x в диапазоне(1, 11)]) комбо.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) self._mainlayout.addWidget(комбо) self._widgets = комбо # область прокрутки self._scrollarea = QtWidgets.QScrollArea(self) self._scrollarea.setWidgetResizable(True) self._scrollarea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOn) self._scrollarea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOn) self._layout.addWidget(self._scrollarea) # виджет для области прокрутки self._scrollarea.setWidget(self._mainwidget) def main() -> Нет: приложение = QtWidgets.QApplication(sys.argv) виджет = МойВиджет() виджет.шоу() приложение.exec() если __name__ == "__main__": основной()
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»