I'm trying to make a series of buttons navigable with the arrow keys and enter key.
I have the arrow keys implemented easily enough, but I can't seem to find the answer online how to bind the focused button to the enter key. Specifically I want to be able to use the up/down keys to set the focus to a button, and then hit the enter key to activate the button.
I can highlight the button i want with the arrows, but the enter key does nothing. Any ideas?
import wx
class Example(wx.Frame):
def __init__(self, parent, title):
frame = wx.Frame.__init__(self, parent, title=title, )
self.btn = []
self.btn.append(wx.Button(self, label='Button 1', id=0))
self.btn.append(wx.Button(self, label='Button 2', id=1))
self.Bind(wx.EVT_BUTTON, self.button1_press, id=0)
self.Bind(wx.EVT_TEXT_ENTER, self.button1_press)
self.Bind(wx.EVT_BUTTON, self.button2_press, id=1)
self.Bind(wx.EVT_TEXT_ENTER, self.button2_press)
self.Bind(wx.EVT_CHAR_HOOK, self.on_key)
self.sizer = wx.GridBagSizer(0, 0)
self.sizer.Add(self.btn[0], pos=(0, 0), flag=wx.ALIGN_CENTER)
self.sizer.Add(self.btn[1], pos=(1, 0), flag=wx.ALIGN_CENTER)
self.SetSizer(self.sizer)
self.Fit()
def button1_press(self, event):
print 'button 1'
def button2_press(self, event):
print 'button 2'
def on_key(self, event):
i = self.get_focus()
if event.GetKeyCode() == wx.WXK_DOWN:
i = min(i+1, 1)
self.btn[i].SetFocus()
elif event.GetKeyCode() == wx.WXK_UP:
i = max(i-1, 0)
self.btn[i].SetFocus()
elif event.GetKeyCode() == wx.WXK_RETURN: # <-doesn't work
print 'ENTER!'
else:
event.Skip()
def get_focus(self):
focused = wx.Window.FindFocus()
if focused == self.btn[0]:
return 0
elif focused == self.btn[1]:
return 1
class AppMenu(wx.App):
def OnInit(self):
'Create the main window and insert the custom frame'
frame = Example(None, 'Example')
frame.Show(True)
return True
app = AppMenu(0)
app.MainLoop()
Your code is close and to be honest, on my machine (ubuntu 18.04) enter does work but the arrows keys don't.
The key to this appears to be setting Default() for the focus within the window.
If you put it all in a Panel you get the added benefit of Tab traversval, so tabbing moves between your buttons as well, without any effort on your part.
Here is a version of your code working on my box using python2.7 wx (3.0.2.0) and python 3.6 wx (4.0.3)
import wx
class Example(wx.Frame):
def __init__(self, parent, title):
frame = wx.Frame.__init__(self, parent, title=title, )
self.panel = wx.Panel(self, -1, size=(200,100))
self.btn1 = wx.Button(self.panel, label='Button 1', id=1)
self.btn2 = wx.Button(self.panel, label='Button 2', id=2)
self.btn1.SetDefault()
self.btn1.SetFocus()
self.sizer = wx.GridBagSizer(0, 0)
self.sizer.Add(self.btn1, pos=(0, 0), flag=wx.ALIGN_CENTER)
self.sizer.Add(self.btn2, pos=(1, 0), flag=wx.ALIGN_CENTER)
self.Bind(wx.EVT_BUTTON, self.button_press)
self.Bind(wx.EVT_CHAR_HOOK, self.on_key)
self.panel.SetSizer(self.sizer)
self.Fit()
def button_press(self, event):
Id = event.GetId()
print ('Click Button',str(Id))
def on_key(self, event):
key = event.GetKeyCode()
if key == wx.WXK_DOWN or key == wx.WXK_UP:
i = self.get_focus()
if i == 1:
self.btn1.SetDefault()
self.btn1.SetFocus()
else:
self.btn2.SetDefault()
self.btn2.SetFocus()
print ('Focus on',str(i))
elif key == wx.WXK_RETURN:
print ('ENTER on Button',str(event.GetId()))
else:
event.Skip()
def get_focus(self):
focused = wx.Window.FindFocus()
if focused == self.btn1:
return 2
elif focused == self.btn2:
return 1
class AppMenu(wx.App):
def OnInit(self):
'Create the main window and insert the custom frame'
frame = Example(None, 'Example')
frame.Show(True)
return True
app = AppMenu()
app.MainLoop()
Related
I have a custom button and want to disable the bright highlight color on mouse hover. I have tried to call event.Skip() in the EVT_ENTER_WINDOW, but the highlight color still shows up.
class CustomButton(Button):
def __init__(self, parent, id, label, style):
Button.__init__(self, parent, id=id, label=label, style=style)
self.Bind(EVT_ENTER_WINDOW, self.OnEnterWindow)
def OnEnterWindow(self, event):
event.Skip()
One option is to create your own custom event, then activate that event and perform whatever you need to do with it i.e. in your case, flip the colour of a button.
Custom events make use of wx.lib.newevent e.g.
import wx
import wx.lib.newevent
NewEvent, EVT_MY_EVENT = wx.lib.newevent.NewEvent()
CMD_ID = wx.NewIdRef()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame()
return True
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Window", pos=(100,150), size=(250,200))
sizer = wx.BoxSizer()
self.button1 = wx.Button(self, CMD_ID, label="Button 1")
sizer.Add(self.button1)
self.Bind(wx.EVT_BUTTON, self.OnButton, id=CMD_ID)
self.Bind(EVT_MY_EVENT, self.OnMyEvent)
self.Layout()
self.Show()
def OnButton(self, event):
id = event.GetId()
event = NewEvent(action="perform a defined action",button=id,other_setting=1234)
wx.PostEvent(self, event)
def OnMyEvent(self, event):
button = event.button
action = event.action
other = event.other_setting
print("event button number", button)
print("event action request", action)
print("event other", other)
if __name__ == "__main__":
app = MyApp()
app.MainLoop()
I am new to this site and fairly new to Python. I am working on a program using wxPython for the GUI. This is being developed and will be used on Windows OS machines. The GUI uses a number of buttons that trigger different processes in my script. I decided to try using the AGW AquaButtons for visual interest. I am finding that an "AquaButton" with focus will not respond to pressing the "Enter" key while the standard "wx.Button" does. Below are examples (mostly borrowed from similar questions, thanks "Rolf of Saxony" and "Mike Driscoll") of the working and non-working code.
Is there a way to get an "AquaButton" (with Focus) have it's event triggered by the "Enter" key?
This works:
import wx
class Example(wx.Frame):
def __init__(self, parent, title):
frame = wx.Frame.__init__(self, parent, title=title, )
self.panel = wx.Panel(self, -1, size=(200,100))
self.btn1 = wx.Button(self.panel, label='Button 1', id=1)
self.btn1.SetForegroundColour("black")
self.btn2 = wx.Button(self.panel, label='Button 2', id=2)
self.btn2.SetForegroundColour("black")
self.sizer = wx.GridBagSizer(0, 0)
self.sizer.Add(self.btn1, pos=(0, 0), flag=wx.ALIGN_CENTER)
self.sizer.Add(self.btn2, pos=(1, 0), flag=wx.ALIGN_CENTER)
self.text_box = wx.StaticText(self.panel, style = wx.NO_BORDER)
self.text_box.SetFont(wx.Font(14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, ""))
self.text_box.SetForegroundColour((40,115,180))
self.sizer.Add(self.text_box, pos=(2,0), flag=wx.ALIGN_CENTER)
self.Bind(wx.EVT_BUTTON, self.button_press)
self.panel.SetSizer(self.sizer)
self.Show()
def button_press(self, event):
Id = event.GetId()
print ('Click Button',str(Id))
retVal = F"Click Button {Id}"
self.text_box.SetLabel(str(retVal))
class AppMenu(wx.App):
def OnInit(self):
'Create the main window and insert the custom frame'
frame = Example(None, 'Example')
frame.Show(True)
return True
app = AppMenu()
app.MainLoop()
This doesn't:
import wx
import wx.lib.agw.aquabutton as AB
class Example(wx.Frame):
def __init__(self, parent, title):
frame = wx.Frame.__init__(self, parent, title=title, )
self.panel = wx.Panel(self, -1, size=(200,100))
self.btn1 = AB.AquaButton(self.panel, label='Button 1', id=1)
self.btn1.SetForegroundColour("black")
self.btn2 = AB.AquaButton(self.panel, label='Button 2', id=2)
self.btn2.SetForegroundColour("black")
self.sizer = wx.GridBagSizer(0, 0)
self.sizer.Add(self.btn1, pos=(0, 0), flag=wx.ALIGN_CENTER)
self.sizer.Add(self.btn2, pos=(1, 0), flag=wx.ALIGN_CENTER)
self.text_box = wx.StaticText(self.panel, style = wx.NO_BORDER)
self.text_box.SetFont(wx.Font(14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, ""))
self.text_box.SetForegroundColour((40,115,180))
self.sizer.Add(self.text_box, pos=(2,0), flag=wx.ALIGN_CENTER)
self.Bind(wx.EVT_BUTTON, self.button_press)
self.panel.SetSizer(self.sizer)
self.Show()
def button_press(self, event):
Id = event.GetId()
print ('Click Button',str(Id))
retVal = F"Click Button {Id}"
self.text_box.SetLabel(str(retVal))
class AppMenu(wx.App):
def OnInit(self):
'Create the main window and insert the custom frame'
frame = Example(None, 'Example')
frame.Show(True)
return True
app = AppMenu()
app.MainLoop()
Bizarrely, the AquaButton is pressed using the Spacebar and not the Enter key.
Navigating appears to be via Arrow keys and/or Tab and Shift Tab.
If in doubt the source code is in:
your_python_location/dist-packages/wx/lib/agw/aquabutton.py
I hope that clears that up for you, if not for your users. :)
I have a listbox with a set of strings. The set of strings I want to display depends on which radio button is selected. I would like it such that while the user is interacting with the Form, if they ever change the radio button it will update the list box.
Here is my code (I'm leaving the array for t87 and t89 out because they are very long (assume they exist):
def OnBtnSuperTesting(self, event):
class MainWindow(wx.Frame):
def __init__(self, parent, title):
self.dirname=''
wx.Frame.__init__(self, parent, title=title, size=(320,440))
self.SetBackgroundColour(wx.WHITE)
self.CenterOnScreen()
self.CreateStatusBar()
self.radioT89 = wx.RadioButton(self, -1, 'T89 only', pos = (2,0), style = wx.RB_GROUP)
self.radioT87 = wx.RadioButton(self, -1, 'T87 only', pos = (154, 0))
self.radioKeySort = wx.RadioButton(self, -1, 'Sort by Key', pos = (2,40), style = wx.RB_GROUP)
self.radioAtoZ = wx.RadioButton(self, -1, 'Sort Name A-Z', pos = (2,60))
self.radioZtoA = wx.RadioButton(self, -1, 'Sort Name Z-A', pos = (2,80))
self.checkCode = wx.CheckBox(self, -1, 'Generate Code', pos = (154,40))
self.checkBuild = wx.CheckBox(self, -1, 'Generate Build Report', pos = (154, 60))
self.ln = wx.StaticLine(self, -1, pos = (0,15), size = (300,3), style = wx.LI_HORIZONTAL)
self.ln2 = wx.StaticLine(self, -1, pos = (150,15), size = (3,100), style = wx.LI_VERTICAL)
self.radioT87.Bind(wx.EVT_RADIOBUTTON, self.updateList)
#self.Bind(wx.EVT_RADIOBUTTON, self.radioT89, self.updateList())
self.listbox = wx.ListBox(self, -1, pos = (0,120), size = (300,200), choices = T89, style = (wx.LB_SINGLE|wx.LB_HSCROLL))
self.go = wx.Button(self,-1, label = 'Go!', pos = (110, 325))
# Setting up the menu.
filemenu= wx.Menu()
menuAbout= filemenu.Append(wx.ID_ABOUT, "&About"," Information about this program")
menuExit = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
# Creating the menubar.
menuBar = wx.MenuBar()
menuBar.Append(filemenu,"&File")
self.SetMenuBar(menuBar)
# Events.
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
self.SetAutoLayout(1)
self.Show()
def OnExit(self,e):
self.Close(True) # Close the frame.
def updateList(self):
if self.radioT87.GetValue() == True:
choices = T87
self.listbox.Set(choices)
else:
choices = T89
self.listbox.Set(choices)
app = wx.App(False)
frame = MainWindow(None, "Supervisory Testing")
app.MainLoop()
When you create each radiobutton you can create a bind event. What this does (as you have implemented later on in your code) is execute a command function when the bind event occurs. In your case it would look like this:
self.Bind(wx.EVT_RADIOBUTTON,self.RadioButton,self.DoSomething)
Explanation:
wx.EVT_RADIOBUTTON
This is the event that is triggered when the user changes the Radiobutton's status. It may or may not have attributes.
self.RadioButton
This is the radiobutton which you would like to bind. In your case "self.radioAtoZ" or similar.
self.DoSomething
THis is the callback function. You can make it whatever you want such as:
def DoSomething(self):
if self.radioAtoZ.getStatus():
rearrangeNumbersFromAtoZ
print 'Re-arranged numbers from A to Z'
else:
etc.
EDIT:
self.RadioButton.Bind(EVT_RADIOBUTTON, self.DoSomething)
Your structure for self.DoSomething should be like this:
Class MainWindow:
def __init_(self, parent):
def DoSomething(self):
#dostuff
Also in response to your other comment:
when a function is called within a Bind event, it passes the event to the function by default. In addition, all functions have the "self" arg, thus 2 given args. You need to change the following:
def DoSomething(self, event):
#dostuff
I decided to rewrite the OP's code to demonstrate how to bind 2 RadioButton's to 2 different event handlers and update the ListBox:
import wx
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Radios!")
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.radioAtoZ = wx.RadioButton(panel, label='Sort Name A-Z',
style = wx.RB_GROUP)
self.radioAtoZ.Bind(wx.EVT_RADIOBUTTON, self.sortAZ)
sizer.Add(self.radioAtoZ, 0, wx.ALL|wx.EXPAND, 5)
self.radioZtoA = wx.RadioButton(panel, label='Sort Name Z-A')
self.radioZtoA.Bind(wx.EVT_RADIOBUTTON, self.sortZA)
sizer.Add(self.radioZtoA, 0, wx.ALL|wx.EXPAND, 5)
choices = ["aardvark", "zebra", "bat", "giraffe"]
self.listbox = wx.ListBox(panel, choices=choices)
sizer.Add(self.listbox, 0, wx.ALL, 5)
panel.SetSizer(sizer)
self.Show()
#----------------------------------------------------------------------
def sortAZ(self, event):
""""""
choices = self.listbox.GetStrings()
choices.sort()
self.listbox.SetItems(choices)
#----------------------------------------------------------------------
def sortZA(self, event):
""""""
choices = self.listbox.GetStrings()
choices.sort()
choices.reverse()
self.listbox.SetItems(choices)
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
You will want to take a look at the following wiki article on the differences of binding it this way versus the other:
http://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind
Most of the time when you create a group of widgets that do different things, you bind them to different event handlers. If you want to bind all the RadioButtons to the same handler, then you'll probably need to name each widget with a unique name so that when they come to the handler, you can tell which button was pressed. Then you can use a series of if statements to decide what to do to the list box. Here's a tutorial that talks about that sort of thing:
http://www.blog.pythonlibrary.org/2011/09/20/wxpython-binding-multiple-widgets-to-the-same-handler/
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()
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()
Probably an easier way is to set the frame up as a dialogue with a cancel button (which you can hide):
class MainFrame(wx.Dialog):
...
def __init__(self, ...):
...
# the frame must have a cancel button
cancel_button = wx.Button(..., id=wx.ID_CANCEL)
# it still works if you hide it
cancel_button.Hide()
This seems to provide the default handling for the escape key. You could even bind it to an event handler to perform some actions before closing - if you do the handler must use event.Skip(True) to propagate the event or event.Skip(False) to stop the cancel operation.
i am trying to Refresh() a panel which uses the wx.ColourDialog. Once I refresh the panel once, it is unable to refresh again. Try the following to see the problem in action.
By clicking the button, it will ask you what color you would like to change the rectangle to. Once you press OK, it should change the rectangles color. It will not work it will not change the rectangle.
import wx
xcolor_of_font_dia=(0,0,0)
class MyFrame(wx.Frame):
"""a frame with a panel"""
def __init__(self, parent=None, id=wx.ID_ANY, title=None):
global xcolor_of_font_dia
global dc
wx.Frame.__init__(self, parent, wx.ID_ANY, title)
self.panel = wx.Panel(self, size=(350, 200))
self.panel.Bind(wx.EVT_PAINT, self.on_paint)
self.button2 = wx.Button(self.panel, id=wx.ID_ANY, label='Button2',pos=(8, 38), size=(175, 28))
self.button2.Bind(wx.EVT_BUTTON, self.onColorDlg)
self.Fit()
def onColorDlg(self, event):
global xcolor_of_font_dia
global dc
"""
This is mostly from the wxPython Demo!
"""
dlg = wx.ColourDialog(self)
# Ensure the full colour dialog is displayed,
# not the abbreviated version.
dlg.GetColourData().SetChooseFull(True)
if dlg.ShowModal() == wx.ID_OK:
data = dlg.GetColourData()
print 'You selected: %s\n' % str(data.GetColour().Get())
xcolor_of_font_dia='#%02x%02x%02x' % data.GetColour().Get()
dlg.Destroy()
self.panel.Refresh()
def on_paint(self, event):
global xcolor_of_font_dia
global dc
dc = wx.PaintDC(self.panel)
dc.SetPen(wx.Pen(xcolor_of_font_dia, 1))
rect = wx.Rect(50, 50, 100, 100)
dc.DrawRoundedRectangleRect(rect, 8)
# test it ...
app = wx.PySimpleApp()
frame1 = MyFrame(title='rounded-rectangle & circle')
frame1.Center()
frame1.Show()
app.MainLoop()
I cleaned your code a bit. Basically your globals were producing some problems as you were creating (and deleting) different dc instances after every size event.
You should not use globals if it is not strictly necessary (rarely is).
This works:
import wx
class MyFrame(wx.Frame):
"""a frame with a panel"""
def __init__(self, parent=None, id=wx.ID_ANY, title=None):
wx.Frame.__init__(self, parent, wx.ID_ANY, title)
self.xcolor = (0, 0, 0)
self.panel = wx.Panel(self, size=(350, 200))
self.panel.Bind(wx.EVT_PAINT, self.on_paint)
self.button2 = wx.Button(self.panel, id=wx.ID_ANY, label='Button2',
pos=(8, 38), size=(175, 28))
self.button2.Bind(wx.EVT_BUTTON, self.onColorDlg)
self.Fit()
def onColorDlg(self, event):
"""
This is mostly from the wxPython Demo!
"""
dlg = wx.ColourDialog(None)
dlg.GetColourData().SetChooseFull(True)
if dlg.ShowModal() == wx.ID_OK:
data = dlg.GetColourData()
self.xcolor = data.GetColour().Get()
print 'You selected: %s\n' % str(self.xcolor)
dlg.Destroy()
self.panel.Refresh()
def on_paint(self, event):
dc = wx.PaintDC(self.panel)
dc.SetPen(wx.Pen(self.xcolor, 2))
rect = wx.Rect(50, 50, 100, 100)
dc.DrawRoundedRectangleRect(rect, 8)
# test it ...
app = wx.PySimpleApp()
frame1 = MyFrame(title='rounded-rectangle & circle')
frame1.Center()
frame1.Show()
app.MainLoop()