Problem mit Button-Event

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Guido24

Hallo,

ich habe gerade mit wxPython angefangen und bin nun auf folgendes Problem gestoßen:

Ich habe eine Anwendung mit einem wxFrame und einem wxDialog.
Auf dem wxFrame ist ein Button über dessen Event ich den Dialog aufrufe. Das Problem ist nun aber, daß der Event immer zweimal ausgelöst wird und der Dialog entsprechend auch zweimal erscheint.

Zur Verdeutlichung hier die relevanten Codeabschnitte:

Code: Alles auswählen

from EdtDialog import EdtDialog


class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):
   ...
        self.Bind(wx.EVT_BUTTON, self.btn_NewOnClick, self.btn_New)
    
    def btn_NewOnClick(self, event): # dies wird immer zweimal ausgeloest
        edlg = EdtDialog(self)
        edlg.ShowModal()
        edlg.Destroy()
        event.Skip()

class EdtDialog(wx.Dialog):
    def __init__(self, *args, **kwds):
    ...
    
    def btn_CloseOnClick(self, event):
        self.Close(True)
        event.Skip()

Was mache ich falsch?

Gruß
Guido
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Guido24 hat geschrieben:Hallo,

ich habe gerade mit wxPython angefangen und bin nun auf folgendes Problem gestoßen:

Ich habe eine Anwendung mit einem wxFrame und einem wxDialog.
Auf dem wxFrame ist ein Button über dessen Event ich den Dialog aufrufe. Das Problem ist nun aber, daß der Event immer zweimal ausgelöst wird und der Dialog entsprechend auch zweimal erscheint.

Zur Verdeutlichung hier die relevanten Codeabschnitte:

Code: Alles auswählen

from EdtDialog import EdtDialog


class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):
   ...
        self.Bind(wx.EVT_BUTTON, self.btn_NewOnClick, self.btn_New)
    
    def btn_NewOnClick(self, event): # dies wird immer zweimal ausgeloest
        edlg = EdtDialog(self)
        edlg.ShowModal()
        edlg.Destroy()
        event.Skip()

class EdtDialog(wx.Dialog):
    def __init__(self, *args, **kwds):
    ...
    
    def btn_CloseOnClick(self, event):
        self.Close(True)
        event.Skip()

Was mache ich falsch?

Gruß
Guido
Hallo Guido,
habe versucht, ein kurzes, vollständiges Programm zu erstellen, um
das zu simulieren.

Ja, ich habe das auch gesehen.

Wenn du das event.Skip() herausnimmst, dann funktioniert das.
Warum das genauso ist, weiss ich nicht.

Aber auf jeden Fall sollte ein Panel auf das Frame gelegt werden.
Die Controls sollte dann das Panel als parent haben und nicht das Frame.
Das ist die eigentliche Funktion eines Panels

Code: Alles auswählen


import wx


class EdtDialog(wx.Dialog):
    def __init__(self, *args, **kwds):
        wx.Dialog.__init__(self, *args, **kwds)
   
        
class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.DefaultSize, wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)

        self.btn_New = wx.NewId()
        b = wx.Button(self, self.btn_New, "dlg")
        self.Bind(wx.EVT_BUTTON, self.btn_NewOnClick, id=self.btn_New)
   
    def btn_NewOnClick(self, event): # dies wird immer zweimal ausgeloest
        print "onclick"
        edlg = EdtDialog(self)
        edlg.ShowModal()
        edlg.Destroy()
        #event.Skip()


class DrApp(wx.App):

    def OnInit(self):
        frame1 = MyFrame(None, 101, "MyFrame")
        frame1.Show(True)
        return True
        
if __name__ == '__main__':
    app = DrApp(0)
    app.MainLoop()
Gast

Francesco hat geschrieben:
Wenn du das event.Skip() herausnimmst, dann funktioniert das.
Warum das genauso ist, weiss ich nicht.
Hallo,

vielen Dank - das ist die Lösung. Das event.Skip() hat wxGlade da reingefrimelt.
Wobei ich aus der wxPython-Doku nicht entnehmen kann, daß der Aufruf dieses bewirken könnte.
Skip(self, skip=True)

Called by an event handler, it controls whether additional event handlers bound to this event will be called after the current event handler returns. Skip(false) (the default setting) will prevent additional event handlers from being called and control will be returned to the sender of the event immediately after the current handler has finished. Skip(True) will cause the event processing system to continue searching for a handler function for this event.
Mal sehen über welche Hürden ich noch stolpern werde.

Der Button liegt auf einem Panel. Das ist aber in meinen gerafften Sourcecode nicht ersichtlich gewesen.

Gruß
Guido
Antworten