•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the Python section within the Software Development category of DaniWeb, a massive community of 397,720 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,559 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Python advertiser:
Views: 5651 | Replies: 72
![]() |
You can use several classes in your wxPython program. This example shows you how to cross reference a widget (or variable) from one class to another:
python Syntax (Toggle Plain Text)
# experiments with wxPython, reference across class instances # from one panel class to another panel class import wx import time class MakePanel1(wx.Panel): def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.SetBackgroundColour('yellow') self.label = wx.StaticText(self, -1, " panel1 label ") self.hbox = wx.BoxSizer(wx.HORIZONTAL) self.hbox.Add(self.label, 0, wx.ALL, 20) self.SetSizer(self.hbox) class MakePanel2(wx.Panel): def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.SetBackgroundColour('green') self.button = wx.Button(self, label=" panel2 button ") self.button.Bind(wx.EVT_BUTTON, self.buttonClick ) self.hbox = wx.BoxSizer(wx.HORIZONTAL) self.hbox.Add(self.button, 0, wx.ALL, 20) self.SetSizer(self.hbox) def buttonClick(self, event=None): # reference panel1's label via frame.panel1 s1 = "panel1 label ..... \n" s2 = "the time is " + time.strftime("%H:%M:%S", time.localtime()) frame.panel1.label.SetLabel(s1 + s2) class MakeFrame(wx.Frame): def __init__(self, *args, **kwargs): wx.Frame.__init__(self, *args, **kwargs) self.panel1 = MakePanel1(self) self.panel2 = MakePanel2(self) vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(self.panel1,1,wx.EXPAND); vbox.Add(self.panel2,1,wx.EXPAND); self.SetSizer(vbox) # select a frame size so everything fits self.Fit() app = wx.App(0) # instance frame is needed for later reference frame = MakeFrame(None) frame.Show(True) app.MainLoop()
drink her pretty
If you like to draw things, here is an example how to draw some basic shapes on wxPython's canvas:
python Syntax (Toggle Plain Text)
# draw a few well known shapes on a wx.PaintDC() canvas import wx class MyFrame(wx.Frame): def __init__(self, parent=None, title=None): wx.Frame.__init__(self, parent, wx.ID_ANY, title) self.panel = wx.Panel(self, size=(350, 450)) # this sets up the painting canvas self.panel.Bind(wx.EVT_PAINT, self.on_paint) # set frame size to fit panel self.Fit() def on_paint(self, event): # establish the painting canvas dc = wx.PaintDC(self.panel) # draw some lines using the given pen specs # from points (x1, y1) to (x2, y2) x1 = 50 y1 = 20 x2 = 300 y2 = 20 # first pen colour is red (thickness = 5) dc.SetPen(wx.Pen('red', 5)) dc.DrawLine(x1, y1, x2, y2) # second pen colour is white dc.SetPen(wx.Pen('white', 5)) dc.DrawLine(x1, y1+5, x2, y2+5) # third pen colour is blue dc.SetPen(wx.Pen('blue', 5)) dc.DrawLine(x1, y1+10, x2, y2+10) # draw a red rounded-rectangle # upper left corner coordinates x, y and width, height # make the pen colour red (thickness = 1) # default brush (fill) is white dc.SetPen(wx.Pen('red', 1)) x = 50 y = 50 w = 100 h = 100 rect = wx.Rect(x, y, w, h) # corners are quarter-circles using a radius of 8 dc.DrawRoundedRectangleRect(rect, 8) # draw a red circle with yellow fill # center coordinates x, y and radius r dc.SetBrush(wx.Brush('yellow')) x = 250 y = 100 r = 50 dc.DrawCircle(x, y, r) # draw an arc from point x1, y1 to point x2, y2 counter # clockwise along a circle with center xc, yc # use previous pen and brush settings xc = 100 yc = 220 x1 = xc y1 = 170 x2 = xc y2 = 270 dc.DrawArc(x1, y1, x2, y2, xc, yc) # draw a polygon connecting the (x, y) points in a list # will also connect first and last points point_list = [(10, 10), (120, 20), (100, 80), (50, 100)] dc.DrawPolygon(point_list, xoffset=180, yoffset=170) # draw 2 gradient filled rectangles # upper left corner coordinates x, y and width, height x = 50 y = 300 w = 100 h = 100 dc.DrawRectangle(x, y, w, h) dc.GradientFillLinear((x, y, w, h), 'red', 'blue') # just a little different fill dc.DrawRectangle(x+150, y, w, h) dc.GradientFillConcentric((x+150, y, w, h), 'red', 'blue', (50, 50)) # test it ... app = wx.App(0) MyFrame(title='put some shapes on a canvas').Show() app.MainLoop()
Last edited by Ene Uran : 25 Days Ago at 3:57 pm. Reason: added corner radius comment
drink her pretty
I am surprised nobody has brought up the old wx.ListBox() widget yet. Well, here it is, a fun thing to experiment with (stole the name_list from vegaseat):
python Syntax (Toggle Plain Text)
# load, sort and clear a wxPython # wx.ListBox(parent, id, pos, size, choices, style) import wx class MyFrame(wx.Frame): def __init__(self, parent, mytitle, name_list): wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle) self.SetBackgroundColour("green") self.name_list = list(name_list) self.listbox = wx.ListBox(self, wx.ID_ANY, choices=[]) self.listbox.Bind(wx.EVT_LISTBOX, self.listboxClick) # create action widgets self.load_button = wx.Button(self, wx.ID_ANY, "load ListBox") self.clear_button = wx.Button(self, wx.ID_ANY, "clear ListBox") self.sort_button = wx.Button(self, wx.ID_ANY, "sort ListBox") # bind mouse event to an action self.load_button.Bind(wx.EVT_BUTTON, self.load_buttonClick) self.clear_button.Bind(wx.EVT_BUTTON, self.clear_buttonClick) self.sort_button.Bind(wx.EVT_BUTTON, self.sort_buttonClick) # create an output widget self.label = wx.StaticText(self, wx.ID_ANY, "") sizer = wx.GridBagSizer(vgap=5, hgap=5) # pos=(row, column) span=(rowspan, columnspan) # wx.ALL puts the specified border on all sides sizer.Add(self.load_button, pos=(0, 0), flag=wx.ALL, border=5) # listbox spans 6 rows and 2 columns sizer.Add(self.listbox, pos=(1, 0), span=(6, 2), flag=wx.ALL|wx.EXPAND, border=5) sizer.Add(self.clear_button, pos=(7, 1), flag=wx.ALL, border=5) sizer.Add(self.sort_button, pos=(7, 0), flag=wx.ALL, border=5) sizer.Add(self.label, pos=(8, 0), flag=wx.ALL, border=5) self.SetSizer(sizer) # size the frame so all the widgets fit self.Fit() def load_buttonClick(self, event): """load the name list into the bistbox""" # use self.listbox.Set(name_list) or ... for name in self.name_list: self.listbox.Append(name) def clear_buttonClick(self, event): """clear all items from the listbox""" self.listbox.Clear() self.label.SetLabel("") def sort_buttonClick(self, event): """sort the items in the listbox""" # GetItems() is new in wxPython2.8 # puts the listbox items into a list name_list = self.listbox.GetItems() name_list.sort() # Set() clears and reloads the listbox self.listbox.Set(name_list) def listboxClick(self, event): """display the selected ListBox item""" selected_item = self.listbox.GetStringSelection() s = "You selected " + selected_item self.label.SetLabel(s) name_list = [ "Andreas", "Erich", "Udo", "Jens", "Bjorn", "Heidrun", "Klaus", "Ulla", "Volger", "Helmut", "Freja", "Larry", "Harry" ] app = wx.App(0) # create the MyFrame instance and then show the frame MyFrame(None, 'listbox test', name_list).Show() app.MainLoop()
Last edited by sneekula : 25 Days Ago at 9:46 pm. Reason: darn spelling
No one died when Clinton lied.
•
•
Join Date: Oct 2004
Location: Mojave Desert
Posts: 2,414
Reputation:
Rep Power: 9
Solved Threads: 173
Thanks Snee for your nice wx.ListBox() example. There is a real high tech listbox in the gizmo section of wxPython. With this one you can edit a selected item including cut, copy, paste portions of it. You can delete, or move selected items up or down in the list. Additionally you can insert, write or paste a new item into the list. You simply have to test it out to get a feel of it ...
python Syntax (Toggle Plain Text)
# wxPython's amazing wx.gizmos.EditableListBox() # you can edit (also cut, copy, paste), delete, move selected # items up or down, and insert (also paste) a new item # tested with Python25 and wxPython28 vegaseat 07aug2008 import wx import wx.gizmos class MyFrame(wx.Frame): def __init__(self, parent, mytitle, name_list): wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle) self.panel = wx.Panel(self, wx.ID_ANY) self.panel.SetBackgroundColour("green") self.name_list = list(name_list) self.elistbox = wx.gizmos.EditableListBox(self.panel, wx.ID_ANY, label="List of Names") # get the actual control portion of the EditableListBox self.actual_listctrl = self.elistbox.GetListCtrl() # binds to any newly focused/selected item self.actual_listctrl.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.listctrlClick) # create action widgets load_button = wx.Button(self.panel, wx.ID_ANY, "load ListBox") clear_button = wx.Button(self.panel, wx.ID_ANY, "clear ListBox") sort_button = wx.Button(self.panel, wx.ID_ANY, "sort ListBox") # bind mouse click event to an action load_button.Bind(wx.EVT_BUTTON, self.load_buttonClick) clear_button.Bind(wx.EVT_BUTTON, self.clear_buttonClick) sort_button.Bind(wx.EVT_BUTTON, self.sort_buttonClick) # create an output widget self.label = wx.StaticText(self.panel, wx.ID_ANY, "") sizer = wx.GridBagSizer(vgap=5, hgap=5) # pos=(row, column) span=(rowspan, columnspan) # wx.ALL puts the specified border on all sides sizer.Add(load_button, pos=(0, 0), flag=wx.ALL, border=5) # listbox spans 6 rows and 2 columns sizer.Add(self.elistbox, pos=(1, 0), span=(6, 2), flag=wx.ALL|wx.EXPAND, border=5) sizer.Add(clear_button, pos=(7, 1), flag=wx.ALL, border=5) sizer.Add(sort_button, pos=(7, 0), flag=wx.ALL, border=5) sizer.Add(self.label, pos=(8, 0), flag=wx.ALL, border=5) # set the sizer and fit all its widgets self.panel.SetSizerAndFit(sizer) # size the frame so all its widgets fit inside self.Fit() def load_buttonClick(self, event): """load the name list into the bistbox""" self.elistbox.SetStrings(name_list) def clear_buttonClick(self, event): """clear all items from the elistbox""" self.elistbox.SetStrings([]) self.label.SetLabel("") def sort_buttonClick(self, event): """sort the items in the elistbox""" # GetStrings() puts the elistbox items into a list name_list = self.elistbox.GetStrings() name_list.sort() # SetStrings() clears and reloads the elistbox self.elistbox.SetStrings(name_list) def listctrlClick(self, event): """display the selected listctrl item of the elistbox""" for n in range(self.actual_listctrl.GetItemCount()): state = wx.LIST_STATE_SELECTED if self.actual_listctrl.GetItemState(n, state): selected_item = self.actual_listctrl.GetItemText(n) s = "You selected " + selected_item self.label.SetLabel(s) name_list = [ "Erich", "Udo", "Jens", "Bjorn", "Heidrun", "Klaus", "Zoe", "Ulla", "Volger", "Helmut", "Lisa", "Larry", "Andreas", "Harry" ] app = wx.App(0) # create a MyFrame instance and show the frame MyFrame(None, 'elistbox test', name_list).Show() app.MainLoop()
Last edited by vegaseat : 22 Days Ago at 11:08 am. Reason: or
May 'the Google' be with you!
•
•
Join Date: Oct 2004
Location: Mojave Desert
Posts: 2,414
Reputation:
Rep Power: 9
Solved Threads: 173
The wxPython GUI toolkit has the Open Graphics Library (OGL) integrated in its later versions. This avoids the often cumbersome download and installation of OGL. Here is an example how you can create a number of shapes and drag them around the canvas ...
python Syntax (Toggle Plain Text)
# the Open Graphics Library (OGL) is now part of wxPython # also test use of a custom class derived from ogl.PolygonShape # tested with Python25 and wxPython28 vegaseat 08aug2008 import wx import wx.lib.ogl as ogl class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__( self, None, wx.ID_ANY, "wx.lib.ogl Demo2", size=(400,300)) canvas = ogl.ShapeCanvas(self) canvas.SetBackgroundColour("yellow") diagram = ogl.Diagram() # marry the two ... canvas.SetDiagram(diagram) diagram.SetCanvas(canvas) # draw some standard shapes ... # (check how creation order affects overlap) circle = ogl.CircleShape(80.0) # radius circle.SetX(125.0) # center x circle.SetY(125.0) # use preset pen and brush types # border ... circle.SetPen(wx.RED_PEN) # fill ... circle.SetBrush(wx.GREEN_BRUSH) canvas.AddShape(circle) rectangle = ogl.RectangleShape(100, 80) # (w, h) rectangle.SetX(55.0) # center x rectangle.SetY(45.0) # center y # use wx.Pen and wx.Brush for more options # wx.Pen(colour, width=1, style=wx.SOLID) # also wx.DOT, wx.DOT_DASH, wx.TRANSPARENT --> no border rectangle.SetPen(wx.Pen("blue", 2)) # wxBrush(colour, style=wx.SOLID) # also wx.CROSS_HATCH, wx.CROSSDIAG_HATCH, wx.TRANSPARENT rectangle.SetBrush(wx.Brush("blue", wx.CROSSDIAG_HATCH)) canvas.AddShape(rectangle) text = ogl.TextShape(250, 30) # (w, h) text.SetX(180) # center x text.SetY(240) text.AddText("you can drag the shapes or the text") canvas.AddShape(text) # if you have an image file # you can also create a shape with the image image_file = 'victory.jpg' bmp = wx.Bitmap(image_file) picture = ogl.BitmapShape() picture.SetBitmap(bmp) picture.SetX(330) # center x picture.SetY(160) canvas.AddShape(picture) # use the custom class ... circle = DiamondShape(130, 100) # (w, h) circle.SetX(225.0) # center x circle.SetY(70.0) circle.SetPen(wx.BLACK_PEN) # use no fill ... circle.SetBrush(wx.TRANSPARENT_BRUSH) canvas.AddShape(circle) # all the shapes are in, so show them diagram.ShowAll(True) # use a sizer sizer = wx.BoxSizer(wx.VERTICAL) # canvas will grow as frame is stretched sizer.Add(canvas, 1, wx.GROW) self.SetSizer(sizer) class DiamondShape(ogl.PolygonShape): """create a diamond shaped object using a polygon""" def __init__(self, w=60.0, h=60.0): ogl.PolygonShape.__init__(self) points = [(0, -h/2.0), (w/2.0, 0), (0,h/2.0), (-w/2.0, 0)] self.Create(points) app = wx.App(0) ogl.OGLInitialize() MyFrame().Show() app.MainLoop()
Last edited by vegaseat : 21 Days Ago at 3:23 pm. Reason: notes
May 'the Google' be with you!
•
•
Join Date: Oct 2004
Location: Mojave Desert
Posts: 2,414
Reputation:
Rep Power: 9
Solved Threads: 173
To allow just one instance of your wxPython program to run, you need to modify your application class slightly ...
python Syntax (Toggle Plain Text)
# allow only one instance of a wxPython program to run import wx class MyFrame(wx.Frame): def __init__(self,parent, mytitle): wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle, size=(300, 90)) self.SetBackgroundColour("red") self.Centre() # more of your program code here ... class SingleApp(wx.App): def OnInit(self): name = "SingleApp-%s" % (wx.GetUserId()) self.instance = wx.SingleInstanceChecker(name) # create a title mytitle = name if self.instance.IsAnotherRunning(): message = "Another instance of %s is running" % mytitle wx.MessageBox(message, "Error") return False MyFrame(None, mytitle).Show() return True app = SingleApp() app.MainLoop()
May 'the Google' be with you!
•
•
Join Date: Oct 2004
Location: Mojave Desert
Posts: 2,414
Reputation:
Rep Power: 9
Solved Threads: 173
Radio buttons give you a fixed input, one choice at a time. If you have a series of radio buttons it's easiest to group them together with a wx.RadioBox(). The code example shows you how to do this, and also is a good example for the wx.BoxSizer() layout manager ...
python Syntax (Toggle Plain Text)
# test the wx.RadioBox() widget # wx.RadioBox(parent, id, label, pos, size, choices, majorDimension, style) # combines a wx.StaticBox() with a wx.RadioButton() # only one radiobutton can be selected at a time in the radiobox import wx class MyFrame(wx.Frame): def __init__(self, parent, mytitle): wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle)


