Mam GUI wxpython i chcę programowo generować wydarzenie.

Próbowałem taką składniową:

e = wx.Event.__init__(grid, eventType=wx.EVT_LEFT_DOWN)

Co skutkuje w:

TypeError: unbound method __init__() must be called with Event instance as first argument (got Grid instance instead)

Lub:

 e = wx.CommandEvent(commandType=wx.EVT_BUTTON)

TypeError: in method 'new_CommandEvent', expected argument 1 of type 'wxEventType'

Więc pytanie jest po prostu, jaka jest dokładna, dosłowna składnia, której potrzebuję, aby utworzyć obiekt zdarzenia? Lub może ktoś wskazywał na dobry zasób za sens zdarzeń? Nie wiem, czy jestem w moim zrozumieniu czegoś prostego. Nie udało mi się znaleźć bezpośredniej odpowiedzi na to pytanie. Sprawdziłem to pytanie: Wygeneruj niestandardowy CommandEvent w Wxpython, ale nie Chcesz zrobić niestandardowe wydarzenie.

Z góry dziękuję!

3
J Jones 14 sierpień 2014, 07:49

4 odpowiedzi

Najlepsza odpowiedź

Chcesz użyć wx.PostEvent

Programowo generować wydarzenie:

wx.PostEvent(self.GetEventHandler(), wx.PyCommandEvent(wx.EVT_BUTTON.typeId, self.GetId()))

Jeśli chcesz opublikować wydarzenie wx.EVT_BUTTON. Czyniąc go PyCommandEvent oznacza, że będzie on propagowany w górę; Inne typy zdarzeń nie propagują domyślnie.

Ogólna forma wx.PostEvent(): http: //www.wxpython .org / DOCS / API / WX-MODULE.HTML # POSTEVENT

Oto mały przykładowy kod:

import wx

class MyFrame ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Test", pos = wx.DefaultPosition, size = wx.Size( 200,200 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        sizer_inside = wx.BoxSizer( wx.VERTICAL )

        # Adding a button and a textCtrl widget
        self.button = wx.Button( self, wx.ID_ANY, u"Click Me", wx.DefaultPosition, wx.DefaultSize, 0 )
        sizer_inside.Add( self.button, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
        self.textCtrl = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_NO_VSCROLL )
        sizer_inside.Add( self.textCtrl, 0, wx.ALIGN_CENTER|wx.ALL, 5 )

        self.SetSizer( sizer_inside )
        self.Layout()
        self.Centre( wx.BOTH )
        self.Show()

        self.counter = 0

        # Binding Events
        self.Bind( wx.EVT_BUTTON, self.on_click )
        self.Bind( wx.EVT_CHOICE, self.test_dummy)

    #Event handlers
    def on_click( self, event ):
        self.counter += 1
        wx.PostEvent(self.GetEventHandler(), wx.PyCommandEvent(wx.EVT_CHOICE.typeId, self.GetId()))

    def test_dummy(self, event):
        self.counter += 1
        self.textCtrl.SetValue(str(self.counter))

if __name__ == "__main__":
    app = wx.App(False)
    MyFrame(None)
    app.MainLoop()

Jeśli uruchomisz to, zauważ, że textCtrl wyświetli 2 po kliknięciu przycisku. Pierwsza obsługiwanie zdarzeń ręcznie ogarnie drugie wydarzenie, które jest obsługiwane przez test_dummy.

3
user2963623 14 sierpień 2014, 07:52

Myślę, że lepiej używasz Win32gui.postMessage ().

To by ci pomogło.

http://markmail.org/message/epiclzlaph44f3kk.

0
i5on9i 14 sierpień 2014, 04:39

Użyj wx.postevent ... jak:

class launcherWindow(wx.Frame):
    def __init__(self):
    wx.Frame.__init__(self, parent=None, title='New Window')
    #now add the main body, start with a panel
    panel = wx.Panel(self)
    #instantiate a new dropdown
    self.productDropDown = wx.ComboBox(panel, size=wx.DefaultSize, style = wx.CB_READONLY)

    #get the products and product subtypes
    self.productDict = self.getProductsAndSubtypes()

    #setup subtypes first, just in case, since onProductSelection will reference this
    self.productSubtypeDropDown = wx.ComboBox(panel, size=wx.DefaultSize, style = wx.CB_READONLY)

    #add products
    for product in self.productDict.keys():
        self.productDropDown.Append(product)

    #bind selection event
    self.productDropDown.Bind(wx.EVT_COMBOBOX, self.onProductSelection)

    #set default selection
    self.productDropDown.SetSelection(0)

    #pretend that we clicked the product selection, so it's event gets called
    wx.PostEvent(self.productDropDown, wx.CommandEvent(wx.wxEVT_COMMAND_COMBOBOX_SELECTED))

    #now add the dropdown to a sizer, set the sizer for the panel, fit the panel, etc...

def onProductSelection(self, event):
    productSelected = self.productDropDown.GetStringSelection()
    productSubtypes = self.productDict[productSelected]

    #clear any existing product subtypes, since each product may have different ones
    self.productSubtypeDropDown.Clear()

    for productSubtype in productSubtypes:
        self.productSubtypeDropDown.Append(productSubtype)

    #select the first item by default
    self.productSubtypeDropDown.SetSelection(0)
0
nmz787 14 sierpień 2014, 21:33

Dzięki. @ I5on9i Komentarz mnie uratował.

Próbowałem zadzwonić do następnego przycisku na wxpython pod Windows.

Kiedy próbowałem użyć imprezy Pythonic, mój kreator po prostu skończy się bez przechodzenia przez strony, jak gdybym nacisnął przycisk "Zakończ", mimo że nie było widoczne na stronie.

Jeśli rozumiem poprawnie, ponieważ jest to klasa systemu Windows (a nie klasa Pythonic) Nie mogłem użyć zdarzenia Pythonic. Dlatego musiałem zadzwonić do wydarzenia Windows.

Być może inna strategia byłaby włączyć z klasy kreatora Windows do klasy Kreator Pythonic, ale nie próbowałem tego.

BTW wiadomość, którą trafiłem, wysłałem:

win32gui.PostMessage(wizard.GetHandle(),0x0111,wx.ID_FORWARD,self.wizard.FindWindowById(wx.ID_FORWARD).GetHandle())
0
uri 12 wrzesień 2016, 12:11