Предотвратить событие wxPython от нескольких окон? - PullRequest
3 голосов
/ 26 мая 2011

Мое приложение wxPython использует wx.ScrolledWindow для основной области рисования - взято прямо из демонстрации и взломано под мои нужды. Когда пользователь дважды щелкает в области прокрутки, я хочу открыть (возможно модальное) диалоговое окно для редактирования параметров объектов, которые они нарисовали. Так что я выскочил диалог через код из другой демонстрации:

    def OnLeftDoubleClickEvent(self, event):
    dlg = TestDialog(self, -1, "Sample Dialog", size=(350, 200),
                     #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME,
                     style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX
                     )
    dlg.CenterOnScreen()

    # this does not return until the dialog is closed.
    val = dlg.ShowModal()

Это просто тест, конечно. Сам диалог был четко определен в одной из демонстраций. В любом случае, после закрытия всплывающего окна ScrolledArea переходит на новую позицию, а в Windows события мыши перестают отображаться с правильными координатами. Смещение происходит только в том случае, если вы перемещаете всплывающее окно так, что вы щелкаете мышью за пределами области прокрутки, чтобы закрыть ее. Имейте в виду, что «ОК» и «Отмена» находятся в совершенно другом диалоге, чем область прокрутки. В Linux прокручиваемая область движется в зависимости от того, как далеко за пределами области была нажата мышь - и в том же направлении. В Windows прокручиваемая область перемещается и запутывается - дальнейшие щелчки мыши также смещают ее и (потому что?) Щелчок записывается не в том месте.

Таким образом, версия проблемы Linux, похоже, указывает на то, что событие щелчка во всплывающем окне фактически обрабатывается прокручиваемой областью в исходном окне.

Похоже ли это на то, что происходит?

Если так, как я могу предотвратить это?

РЕДАКТИРОВАТЬ: больше информации. Я попытался закрыть всплывающее окно, нажав на кнопку ОК или Отмена. Каждый раз, когда фокус перемещается к другому элементу управления, область прокрутки в другом окне перемещается. Это зависит от того, где всплывающее окно по отношению к другому окну. Я сейчас совершенно сбит с толку.

EDIT2: я добавил опцию в меню главного окна, чтобы вызвать всплывающее диалоговое окно. При активации таким способом не возникает никаких проблем. Я думаю, что проблема как-то связана с созданием всплывающего окна в событии двойного щелчка прокручиваемой области, в результате чего некоторые события обрабатываются обоими. Имеет ли это смысл? Когда у меня будет время, я попытаюсь отправить событие (пользовательское?) В родительский диалог и сопоставить его с той же функцией, что и новый пункт меню. Это приведет к тому, что мое всплывающее окно появится в главном окне, и, надеюсь, устранит проблему. Посмотрим.

РЕДАКТИРОВАТЬ 3 СЛУЧАЙ ТЕСТА

Чтобы увидеть это, возьмите файл: ScrolledWindow.py из демоверсии, добавьте следующее:

from Dialog import *

Затем в области событий мыши класса MyCanvas свяжите двойной щелчок следующим образом:

self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDoubleClickEvent)

Затем добавьте следующую функцию к тому же классу (взято из демонстрации Dialog):

    def OnLeftDoubleClickEvent(self, event):
    useMetal = False
    if 'wxMac' in wx.PlatformInfo:
        useMetal = self.cb.IsChecked()

    dlg = TestDialog(self, -1, "Sample Dialog", size=(350, 200),
                     #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME,
                     style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX,
                     useMetal=useMetal,
                     )
    dlg.CenterOnScreen()

    # this does not return until the dialog is closed.
    val = dlg.ShowModal()

    if val == wx.ID_OK:
        self.log.WriteText("You pressed OK\n")
    else:
        self.log.WriteText("You pressed Cancel\n")

    dlg.Destroy()

Теперь запустите демонстрацию и выберите Core Windows / Controls и «ScrolledWindow». Вы сможете писать на прокручиваемой области как обычно, но теперь вы можете дважды щелкнуть там, и появится диалоговое окно. Переместите это новое диалоговое окно за пределы области рисования, а затем перейдите в поля ввода или нажмите «ОК». Активность в этом диалоговом окне приведет к тому, что прокручиваемый чертеж в другом окне изменит позиции.

И вот оно у вас есть. Чем это вызвано? Я адаптировал демо для рисования своих собственных объектов и хочу иметь возможность двойного щелчка, чтобы вызвать диалог свойств объекта. Это ошибка или неправильный путь? Мой план от Edit2 больше похож на "правильный путь"?

1 Ответ

0 голосов
/ 16 июня 2011

Решение оказывается тем, что я предложил в Edit2.Я не уверен, почему, но создание всплывающего окна внутри события ScrolledArea DoubleClick вызывало проблемы.Решение - создать собственное сообщение и отправить его себе внутри события двойного щелчка.Пользовательское событие обрабатывается окном верхнего уровня, а не областью прокрутки.Это работает нормально, но теперь мне нужно где-то хранить идентификатор выбранного объекта, чтобы окно верхнего уровня могло передать его в диалог.Это немного больше работы, но это кажется более «правильным», чем всплывающее окно внутри события двойного щелчка в области рисования.Тем не менее, окно все еще всплывает внутри обработчика событий, это просто другой объект, обрабатывающий его с другим событием.Специфика того, почему это работает, до сих пор ускользает от меня.

Я уверен, что есть способ думать об этом, который делает это решение, очевидно, правильным.Я все еще буду голосовать за ответ, который дает представление о том, почему один метод работает, а не другой, или каков «правильный» способ сделать этот тип вещей.опубликовать это после истечения +50 щедрости по этому вопросу.Да, я отправил награду до того, как попробовал свою идею - глупый я.В следующий раз я попробую список рассылки wxPython, прежде чем предлагать награду, хотя мне не нравятся списки рассылки.

...