Mike Mike - 12 days ago 7
Python Question

Escape key to Close WxPython GUI

I am working on a rather simple wxpython GUI, and would like to be able to have the escape key close the window. Right now I just have a close button that executes sys.exit(0), but I'd like the escape key to do this to.

Does anyone know a way to do this?

import win32clipboard
import wx
from time import sleep
import sys

class MainFrame(wx.Frame):
def __init__(self,title):

wx.Frame.__init__(self, None, title="-RRESI Rounder-", pos=(0,0), size=(210,160))
panel=Panel(self)

icon = wx.Icon('ruler_ico.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(icon)

class Panel(wx.Panel):

def __init__(self, parent):
wx.Panel.__init__(self, parent)

x1=10; x2=110
y1=40; dy=25; ddy=-3
boxlength=80

self.button =wx.Button(self, label="GO", pos=(100,y1+dy*3))
self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)
self.button.SetDefault()

self.button2 =wx.Button(self, label="Close", pos=(100,y1+dy*4))
self.Bind(wx.EVT_BUTTON, self.OnClose, self.button2)
self.button.SetDefault()

self.Bind(wx.EVT_KEY_UP, self.OnKeyUP)

self.label1 = wx.StaticText(self, label="Input Number:", pos=(x1,y1+dy*1))
self.Input = wx.TextCtrl(self, value="1.001", pos=(x2,ddy+y1+dy*1), size=(boxlength,-1))

self.label0 = wx.StaticText(self, label="Round to closest: 1/", pos=(x1,y1+dy*0))
self.Denominator = wx.TextCtrl(self, value="64", pos=(x2,ddy+y1+dy*0), size=(boxlength,-1))

self.label2 = wx.StaticText(self, label="Output Number:", pos=(x1,y1+dy*2))
self.display = wx.TextCtrl(self, value="1.0", pos=(x2,ddy+y1+dy*2), size=(boxlength,-1))
self.display.SetBackgroundColour(wx.Colour(232, 232, 232))

self.label3 = wx.StaticText(self, label=" ", pos=(x2+7,y1+dy*2+20)) #Copied

self.label4 = wx.StaticText(self, label="Type value and hit Enter", pos=(x1-5,y1-dy*1.5))
self.label5 = wx.StaticText(self, label="Output is copied", pos=(x1-5,y1-dy*1))
font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
self.label4.SetFont(font)
self.label5.SetFont(font)

def OnKeyUP(self, event):
keyCode = event.GetKeyCode()
if keyCode == wx.WXK_ESCAPE:
sys.exit(0)


def OnClose(self, event):
print "Closed"
sys.exit(0)

def OnClick(self,event):
print "You clicked the button!"

def openClipboard():
try:
win32clipboard.OpenClipboard()
except Exception, e:
print e
pass

def closeClipboard():
try:
win32clipboard.CloseClipboard()
except Exception, e:
print e
pass

def clearClipboard():
try:
openClipboard()
win32clipboard.EmptyClipboard()
closeClipboard()
except TypeError:
pass

def setText(txt):
openClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(txt)
closeClipboard()

Denominator = float(self.Denominator.GetValue())
Input=float(self.Input.GetValue())
Output=round(Input*Denominator,0)/Denominator
self.display.SetValue(str(Output))
setText(str(Output))
self.label3.SetLabel("Copied")
self.Update()#force redraw
sleep(.5)
wx.Timer
self.label3.SetLabel(" ")


if __name__=="__main__":
app = wx.App(redirect=False) # Error messages don't go to popup window
frame = MainFrame("RRESI Rounder")
frame.Show()
app.MainLoop()

Answer

This sorta works ... albiet with some issues

[edit]ok EVT_CHAR_HOOK works much better than EVT_KEY_UP

import wx

class Test(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, -1, title='Event Test',
size=(200, 200))

        panel = wx.Panel(self)

        panel.SetFocus()

        self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyUP)

    def OnKeyUP(self, event):
        print "KEY UP!"
        keyCode = event.GetKeyCode()
        if keyCode == wx.WXK_ESCAPE:
            self.Close()
        event.Skip() 


class App(wx.App):
    """Application class."""

    def OnInit(self):
        self.frame = Test()
        self.frame.Show()
        self.SetTopWindow(self.frame)
        self.frame.SetFocus()
        return True

if __name__ == '__main__':
    app = App()
    app.MainLoop()