wx.Dialog mit Escape key schließen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo, folgendes Beispiel:

Code: Alles auswählen

import wx
import sys

class ScrolledMessageDialog(wx.Dialog):
    def __init__(self, parent, message, title, position = wx.DefaultPosition, size = (400, 300)):
        wx.Dialog.__init__(self, parent, -1, title, position, size, wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER | wx.WANTS_CHARS)

        #self.ID_CLOSE = 101

        self.theSizer = wx.BoxSizer(wx.VERTICAL)

        self.cmdSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.btnClose = wx.Button(self, wx.ID_CANCEL, "Close")
        self.cmdSizer.Add(self.btnClose, 0, wx.SHAPED | wx.ALIGN_CENTER)
        self.btnClose.SetDefault()

        self.txtMessage = wx.TextCtrl(self, -1, message, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE | wx.TE_READONLY)

        self.theSizer.Add(self.txtMessage, 9, wx.EXPAND)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 0, wx.SHAPED)
        self.theSizer.Add(self.cmdSizer, 0, wx.SHAPED | wx.ALIGN_CENTER)
        self.theSizer.Add(wx.StaticText(self, -1, "   "), 0, wx.SHAPED)

        self.SetAutoLayout(True)
        self.SetSizer(self.theSizer)

        self.Bind(wx.EVT_BUTTON,  self.OnbtnClose, id=wx.ID_CANCEL)

        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

        #whatever i want to bind to the key, it doesn't work
        ##self.txtMessage.Bind(wx.EVT_CHAR, self.OnChar)
        self.Bind(wx.EVT_CHAR, self.OnChar)
        self.Bind(wx.EVT_KEY_DOWN, self.OnChar)
        self.Bind(wx.EVT_CHAR_HOOK, self.OnCharHook)
        self.SetEscapeId(wx.ID_CANCEL)
        #self.SetAcceleratorTable(wx.AcceleratorTable([(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, wx.ID_CANCEL),]))

    def OnCharHook(self, event):
        print "char hook"
        if event.GetKeyCode() == wx.WXK_ESCAPE:
            self.EndModal(wx.ID_CANCEL)
        else:
            event.Skip()

    def OnChar(self, event):
        print "onchar"
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_ESCAPE:
            self.Close(1)


    def OnbtnClose(self, event):
        print "close"
        self.EndModal(1)

    def OnKeyDown(self, event):
        print "on key down"
        if event.GetKeyCode() == wx.WXK_ESCAPE:
            self.Close(1)

if __name__ == '__main__':
    app = wx.App()
    d = ScrolledMessageDialog(None, "message", "title")
    d.ShowModal()
    d.Destroy()
    app.MainLoop()
Gleich vorweg. Der Code ist schon ein bisschen ein Durcheinander. Man sieht schon an den (verzweifelten) kommentaren, was ich schon alles versucht habe. ;) Entweder ich stehe auf der Leitung oder ich mache etwas falsch. Esc Key (und andere Key events) kommen nicht durch. Eins ginge schon, den Focus auf das TextCtrl zu setzen, das möchte ich aber nicht, das mus doch irgendwie anders gehen. :?
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Die Events werden nur ausgelöst, wenn das entsprechende Widget den Focus hat, AFAIR kannst du den manuell mit SetFocus setzen
the more they change the more they stay the same
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Dav1d hat geschrieben:Die Events werden nur ausgelöst, wenn das entsprechende Widget den Focus hat, AFAIR kannst du den manuell mit SetFocus setzen
Vielen Dank, das war tatsächlich das Problem (self.SetFocus() brachte den Erfolg). Was ich nciht verstehe, ich mein der Dialog müsste eh den Focus haben (was denn sonst), oder war der Focus auf den Button oder dem TextCtrl?
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Kann das sein, dass du auch in der MailingList gefragt hast? (und die selbe Antwort von Steven Sproat alias sproaty bekommen hast?)

Ich weiß nicht wie das mit Dialogen ist, aber z.b. ein wx.Panel gibt den Focus automatisch an ein "child" weiter, bei einem Dialog könnte das genauso sein.
the more they change the more they stay the same
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Dav1d hat geschrieben:Kann das sein, dass du auch in der MailingList gefragt hast? (und die selbe Antwort von Steven Sproat alias sproaty bekommen hast?)
Ich hoffe es wird nicht als stillos aufgefasst, aber ich bin ein bisschen ungeduldig. :wink: Auf jeden Fall freut es mich sehr, die Dialoge nun mit ESC wegzubekommen, das bin ich ja schon jahrelang so gewohnt, und meiner Meinung nach sollte das bei allen "Bestätigungs- oder Info"-Dialogen so sein. Was anderes sind komplexere Dialog, da sollte der User den schon explizit schließen (und nicht "unabsichtlich" mit Esc).
Dav1d hat geschrieben: Ich weiß nicht wie das mit Dialogen ist, aber z.b. ein wx.Panel gibt den Focus automatisch an ein "child" weiter, bei einem Dialog könnte das genauso sein.
Das kann sein, ja, recht viele Möglichkeiten gibt es bei diesem simplen Dialog nicht. Im Textfeld war er nicht, dann kann er nur am button selbst sein... Eigenartig ist trotzdem, dass ich dem Dialog explizit nochmals den Focus geben kann. Das Event des Characters funktioniert nur, wenn man es auf den Button bindet und nicht auf den Dialog selbst. Aber das wird den Grund haben, den du angeführt hast.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

mit Windows 7 verhält sich dein Script jetzt schon so wie du es möchtest. Es schliesst sobald man Esc drückt.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

DaMutz hat geschrieben:mit Windows 7 verhält sich dein Script jetzt schon so wie du es möchtest. Es schliesst sobald man Esc drückt.
Ich erinnere mich, dass ich schon einmal in gtk so ein Problem hatte, dass man den Focus nochmals setzen muss.
Ich habe/hätte einmal eine (zugegebenermassen nicht sehr schöne) wxPyhton wiki Seite begonnen (scheint aber auf relativ wenig Interesse gestossen zu sein); ist aber schon ein paar Jahre her... in der Zwischenzeit, wenn man weniger damit macht, vergisst man aber auch wieder vieles ... ;)

http://wiki.wxpython.org/Gtk%20and%20Wi ... omatically

Newly created Dialogs do not gain focus automatically
Möglicherweise hat das auch damit zu tun. Eigenartig ist es, wenn man wieder einmal liest, was man selbst vor längerer Zeit einmal geschrieben hat. ;) Hab ich damals aus der Mailingliste und von eigenen Erfahrungen zusammengetragen, kann sein, dass einige Dinge mit der jetzigen (ich verwende wxPy 2.8.10.1, aktuelle ist glaube ich 2.8.11)

Habs soeben auf Windows probiert, und es ist so, wie Du (DaMutz) gesagt hast. Da hat sich mein Verdacht bestätigt. Ein self.SetFocus wird nicht benötigt, damit die Esc funktioniert.
Antworten