wxPython: как правильно обрабатывать привязку событий и Show () - PullRequest
0 голосов
/ 26 апреля 2010

Я только начинаю с wxPython, и это то, что я хотел бы сделать:

a) Показать рамку (с панелью внутри нее) и кнопку на этой панели. б) Когда я нажимаю кнопку, появляется диалоговое окно (где я могу выбрать из выбора). c) Когда я нажимаю кнопку ОК в диалоговом окне, диалоговое окно должно исчезнуть (уничтожиться), но исходная кнопка Рамка + Панель + все еще там. г) Если я нажму эту кнопку еще раз, диалоговое окно появится снова.

Мой код указан ниже. К сожалению, я получаю обратный эффект . То есть

a) Диалоговое окно Selection появляется первым (т.е. без нажатия какой-либо кнопки, поскольку кнопка TopLevelframe + никогда не отображается).

б) Когда я нажимаю кнопку ОК в диалоговом окне, появляется рамка с кнопкой.

в) Повторное нажатие на кнопку не имеет никакого эффекта (то есть диалоговое окно больше не появляется).

Что я делаю не так? Кажется, что как только рамка инициализируется (даже до вызова .Show ()), диалоговое окно инициализируется и отображается автоматически.

Я делаю это, используя Eclipse + Pydev на WindowsXP с Python 2.6

============ Файл: MainFile.py ===============

import wx
import MyDialog   #This is implemented in another file: MyDialog.py

class TopLevelFrame(wx.Frame):

    def __init__(self,parent,id):    
        wx.Frame.__init__(self,parent,id,"Test",size=(300,200))
        panel=wx.Panel(self)
        button=wx.Button(panel, label='Show Dialog', pos=(130,20), size=(60,20))

        # Bind EVENTS --> HANDLERS. 
        button.Bind(wx.EVT_BUTTON, MyDialog.start(self))  


# Run the main loop to start program.         
if __name__=='__main__':
    app=wx.PySimpleApp()    
    TopLevelFrame(parent=None, id=-1).Show()  
    app.MainLoop()

============ Файл: MyDialog.py ===============

import wx

def start(parent):
    inputbox = wx.SingleChoiceDialog(None,'Choose Fruit', 'Selection Title',
                                     ['apple','banana','orange','papaya'])
    if inputbox.ShowModal()==wx.ID_OK:
        answer = inputbox.GetStringSelection()
        inputbox.Destroy()

1 Ответ

2 голосов
/ 26 апреля 2010

Есть несколько способов сделать это, но чтобы сделать наименьшее количество изменений в вашем коде,

Изменить def start(parent): на

def start(parent, evt):

И изменить button.Bind(wx.EVT_BUTTON, MyDialog.start(self)) на

    button.Bind(wx.EVT_BUTTON, lambda evt: MyDialog.start(self, evt))

То есть вторым аргументом в Bind должна быть функция, которая принимает и событие, и вам нужно создать диалоговое окно при нажатии кнопки. lambda делает эту функцию также принимающей parent и evt (вы также можете использовать functools.partial для версии> 2.5), а затем при нажатии кнопки будет вызываться start для создания диалога.

Я не совсем уверен, что происходит в вашем коде, но кажется, что вы вызываете start и создаете диалог при первоначальном вызове Bind, а затем передаете возвращаемое значение из начала, None связать.

Примечание 1 Более подробно, причина использования лямбды здесь заключается в том, что Bind должен иметь форму, такую ​​как Bind(event, handler), где event - это wx.PyEventBinder, как wx.EVT_BUTTON, а handler - это функция как foo (evt), где evt - это wx.Event или wx.CommandEvent. (Здесь нет рекурсии, так как вы просто говорите, что делать, когда что-то происходит, но это еще не произошло, поэтому событие не было создано. Когда событие произойдет, оно будет представлено как wx .Event, который будет содержать информацию о событии, например, где была мышь при нажатии и т. Д.)

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

def start2(parent):
    inputbox = wx.SingleChoiceDialog(parent,'Choose Fruit', 'Selection Title',
                                     ['apple','banana','orange','papaya'])
    if inputbox.ShowModal()==wx.ID_OK:
        answer = inputbox.GetStringSelection()
    inputbox.Destroy()

class TopLevelFrame2(wx.Frame):

    def __init__(self,parent,id):    
        wx.Frame.__init__(self,parent,id,"Test",size=(300,200))
        panel=wx.Panel(self)
        button=wx.Button(panel, label='Show Dialog', pos=(130,20), size=(60,20))

        # Bind EVENTS --> HANDLERS. 
        button.Bind(wx.EVT_BUTTON, self.OnClick)  

    def OnClick(self, evt):
        start2(self)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...