2016-10-21 2 views
1

У меня есть QListWidget в QDialog, и я хочу, чтобы все колеса событие будет перенаправлено в список, так что я сделал это:PyQt wheelEvent Перенаправления и максимальные рекурсии превышены

class Form(QDialog): 
    def __init__(self): 
    ... 
     self.myList = QListWidget() 
    ... 
    def wheelEvent(self, scrollEvent): 
     if not scrollEvent.isAccepted(): 
      scrollEvent.accept() 
      self.myList.wheelEvent(scrollEvent) 

Он работает отлично, пока свитка действие пытается переместить список за его пределы. Похоже, что в тех случаях QListWidget не принимает (игнорирует) событие прокрутки и передает его (игнорируется) своему родительскому элементу Form, который снова отправляет его в QListWidget до тех пор, пока не будет превышена «максимальная глубина рекурсии», появляется сообщение об ошибке.

Если событие принято до перенаправления на QListWidget, почему, когда он возвращается в Qdialog, перенаправляется снова в QListWidget? Похоже, что флаг «accept» события не сохраняется (или QListWidget устанавливает его обратно в «не принято»), и когда он возвращается к QDialog, рассматривается как новое событие. Как сохранить эти флаги или заставить QListWidget принять событие, даже если список находится сверху/снизу?

Я попытался определить подкласс QListWidget и принять событие в этом подклассе перед перенаправлением его на суперкласс, но тот же результат, событие возвращается к диалогу как не принятое.

EDIT: Привет! Я нашел решение:

class Form(QDialog): 
    def __init__(self): 
    ... 
     self.processingWheel = False 
     self.myList = QListWidget() 
    ... 
    def wheelEvent(self, scrollEvent): 
     if not self.processingWheel: 
      self.processingWheel = True 
      self.myList.wheelEvent(scrollEvent) 
      self.processingWheel = False 

Теперь, когда QListWidget не обрабатывает событие (причина список находится в верхней/нижней) событие снова достигает QDialog но второй раз не перенаправлен QListWidget снова. Я полагаю, что он перенаправляется на родителя QDialog и там он обрабатывается (ничего не делает).

Если это разрешено, я хотел бы оставить вопрос открытым, потому что мне все еще интересно, почему мне пришлось управлять флагом самостоятельно и не мог использовать флаг isAccepted(), связанный с событием, как в моей первой попытке , Боюсь, я не понял, что происходит за сценой с флагами событий во время распространения события в Qt.

ответ

1

NB: это относится к Qt5 - в Qt4 все может работать по-другому.

Когда вы вызываете self.myList.wheelEvent(scrollEvent), внутренне это вызовет QListView.wheelEvent(event), что создаст новый QWheelEvent и пересылает его соответствующему виджету прокрутки. Если полоса прокрутки не может обрабатывать событие, она установит для принятого флага значение false. Это приведет к тому, что событие будет немедленно повторно размножается в диалоговом окне, и все это снова пройдет.

После того как вы отправите событие в виджет списка, вы не можете повторно установить флаг accept, пока не вернется myList.wheelEvent(). Но, конечно, если полоса прокрутки списка-виджета игнорирует событие, он может никогда не возвращать, так как он сразу же вводит бесконечный регресс.

Вызов event.flag() перед пересылкой события не будет иметь никакого эффекта, так как полоса прокрутки по умолчанию устанавливает его в значение false и устанавливает значение true только в том случае, если оно явно обрабатывает событие.

Учитывая все это, ваше решение с использованием внешнего флага кажется единственно возможным (оно несколько аналогично механизму blockSignals).

+0

Вы действительно вызываете «слот» вручную, в этом случае вызываете QListView.wheelEvent (событие), генерируете новый QWheelEvent? – Pablovx

+0

Я имею в виду, я отправляю событие в качестве параметра, мне не кажется логичным, что он создает новый. – Pablovx

+0

Извините, только что открытая новостная линия не принимается в разделе комментариев. ;) Однако тот факт, что scrollbar повторно устанавливает флаг события в значение false по умолчанию, объясняет ситуацию, даже если это одно и то же событие постоянно и не создается новое. Спасибо за вашу помощь! – Pablovx