Just an experiment with box sizers and panels to get a desired layout ...
# use a wx.BoxSizer() for multisizer widget layout
# wx.VERTICAL = stacked vertically
# wx.HORIZONTAL = stacked horizontally
# add widget with Add() --> has options ...
# proportion=0 no vertical stretch with frame stretch in sizer_v
# proportion=1 stretch with frame stretch
# proportion=2 fill remaining space proportional (eg. 1:2)
# proportion=3 fill remaining space proportional (eg. 1:3)
# border=n use a n pixel wide border
# wx.ALL puts the specified border on all sides
# (also has wx.LEFT wx.RIGHT wx.TOP and wx.BOTTOM)
# flag=wx.EXPAND --> expand to fit frame
# flag=wx.SHAPED --> change size preserving original aspect ratio
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle, mysize):
wx.Frame.__init__(self, parent, -1, mytitle, size=mysize)
panel1 = wx.Panel(self, -1, style=wx.SUNKEN_BORDER)
panel2 = wx.Panel(self, -1, style=wx.SUNKEN_BORDER)
panel3 = wx.Panel(self, -1, style=wx.SUNKEN_BORDER)
panel1.SetBackgroundColour("blue")
panel2.SetBackgroundColour("red")
panel3.SetBackgroundColour("green")
# use two different BoxSizer() to layout the controls
# in this case the vertical sizer will be the main sizer
sizer_v = wx.BoxSizer(wx.VERTICAL)
sizer_h = wx.BoxSizer(wx.HORIZONTAL)
# add widgets to horizontal sizer
# proportions are set to fill space ratio 1:2
# keeps ratio on frame stretch
sizer_h.Add(panel1, proportion=1, flag=wx.EXPAND)
sizer_h.Add(panel2, proportion=2, flag=wx.EXPAND)
# now add to vertical sizer in order
sizer_v.Add(panel3, proportion=1, flag=wx.EXPAND)
sizer_v.Add(sizer_h, proportion=3, flag=wx.EXPAND)
# set the main sizer only
self.SetSizer(sizer_v)
app = wx.App(0)
# create a MyFrame instance and show the frame
MyFrame(None, "Multi BoxSizer() Test", (300, 250)).Show()
app.MainLoop() This shows you how to add transparency to the wx.PaintDC canvas ...
# a simple wx drawing surface (canvas) using wx.PaintDC
# draw two overlapping circles
# transparency added with wx.GCDC
# tested with Python26 and wxPython28 by vegaseat
import wx
def on_paint(event):
dc = wx.PaintDC(event.GetEventObject())
dc.Clear()
# wx.GCDC gives realistic transparency
gcdc = wx.GCDC(dc)
# set pen (border) colour
# wx.Pen(colour, width=1, style=wx.SOLID)
gcdc.SetPen(wx.Pen('red', 1))
# alpha tranparency value 0 to 255
# play with alpha to see the effect
alpha = 175
# rgb for red
r, g, b = 255, 0, 0
brushcolour1 = wx.Colour(r, g, b, alpha)
# rgb for yellow
r, g, b = 255, 255, 0
brushcolour2 = wx.Colour(r, g, b, alpha)
# set fill colour and draw circle1
gcdc.SetBrush(wx.Brush(brushcolour1))
# DrawCircle(x, y, r)
# center coordinates (x, y) and radius r
gcdc.DrawCircle(120, 120, 100)
# set fill colour and draw circle2
gcdc.SetBrush(wx.Brush(brushcolour2))
# DrawCircle(x, y, r)
# center coordinates (x, y) and radius r
gcdc.DrawCircle(280, 120, 100)
app = wx.App(0)
frame = wx.Frame(None, -1, "wx canvas with circles", size=(410, 280))
frame.SetBackgroundColour('white')
# create the canvas
wx.EVT_PAINT(frame, on_paint)
# center the frame and show it
frame.Center(True)
frame.Show(True)
app.MainLoop() Since many days I was looking for simple text editor program using wxPython and didn't get to find anywhere but finally I found here. This is really a great thread to get information regarding to wxPython.
... and you are spamming what in your signature? Stop it, it's rude!
Just experimented putting red text in a listbox:
# load, sort, clear and add to wxPython's
# wx.ListBox(parent, id, pos, size, choices, style, name)
# choices is a list of strings
#
# style -->
# wx.LB_SINGLE single-selection list (default)
# wx.LB_MULTIPLE multiple-selection list, the user can toggle
# multiple items on and off
# wx.LB_EXTENDED extended-selection list, the user can select multiple
# items using the SHIFT key, the mouse or special key combinations
# wx.LB_HSCROLL create horizontal scrollbar if contents are too wide
# (Windows only)
# wx.LB_ALWAYS_SB always show a vertical scrollbar
# wx.LB_NEEDED_SB Only create a vertical scrollbar if needed (default)
# wx.LB_SORT The listbox contents are sorted in alphabetical order
# source from: Sneekula 2008
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle, name_list):
wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle)
self.SetBackgroundColour("brown")
self.name_list = list(name_list)
self.listbox = wx.ListBox(self, wx.ID_ANY, choices=[],
style=wx.LB_EXTENDED)
self.listbox.Bind(wx.EVT_LISTBOX, self.listboxClick)
# optional text color for the list box
self.listbox.SetForegroundColour("red")
# create buttons
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")
self.add_button = wx.Button(self, wx.ID_ANY, "add to 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)
self.add_button.Bind(wx.EVT_BUTTON, self.add_buttonClick)
# create an output widget
s1 = "load the list box ...\n"
s2 = "to select a single item left click on the item\n"
s3 = "to select a range of items shift click items\n"
s4 = "to select multiple items ctrl click on items"
self.text_out = wx.TextCtrl(self, wx.ID_ANY,
value=(s1+s2+s3+s4), size=(300, 95),
style=wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY)
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)
sizer.Add(self.add_button, pos=(0, 1), 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.text_out, pos=(8, 0), span=(2, 2),
flag=wx.ALL, border=5)
self.SetSizer(sizer)
# size the frame so all the widgets fit
self.Fit()
def add_buttonClick(self, event):
"""add another item to the listbox"""
text = wx.GetTextFromUser('Enter new item', 'Add to listbox')
if text != '':
self.listbox.Append(text)
def load_buttonClick(self, event):
"""load the name list into the bistbox"""
# use self.listbox.Set(self.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.text_out.ChangeValue("")
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(s)"""
"""
# for single item select use this ...
selected_item = self.listbox.GetStringSelection()
s = "You selected " + selected_item
self.label.SetLabel(s)
"""
name_list = self.listbox.GetItems()
# for multiple and single item select use this ...
pos_tuple = self.listbox.GetSelections()
selected_list = []
for pos in pos_tuple:
selected_list.append(name_list[pos])
s = "You selected " + str(selected_list)
self.text_out.ChangeValue(s)
name_list = [
"Erich",
"Udo",
"Jens",
"Bjorn",
"Heidrun",
"Klaus",
"Ulla",
"Volger",
"Helmut",
"Freja",
"Larry",
"Andreas",
"Harry"
]
app = wx.App(0)
# create the MyFrame instance and then show the frame
MyFrame(None, 'wx.ListBox ops', name_list).Show()
app.MainLoop() Just experimented putting red text in a listbox:
# load, sort, clear and add to wxPython's
# wx.ListBox(parent, id, pos, size, choices, style, name)
# choices is a list of strings
#
# style -->
# wx.LB_SINGLE single-selection list (default)
# wx.LB_MULTIPLE multiple-selection list, the user can toggle
# multiple items on and off
# wx.LB_EXTENDED extended-selection list, the user can select multiple
# items using the SHIFT key, the mouse or special key combinations
# wx.LB_HSCROLL create horizontal scrollbar if contents are too wide
# (Windows only)
# wx.LB_ALWAYS_SB always show a vertical scrollbar
# wx.LB_NEEDED_SB Only create a vertical scrollbar if needed (default)
# wx.LB_SORT The listbox contents are sorted in alphabetical order
# source from: Sneekula 2008
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle, name_list):
wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle)
self.SetBackgroundColour("brown")
self.name_list = list(name_list)
self.listbox = wx.ListBox(self, wx.ID_ANY, choices=[],
style=wx.LB_EXTENDED)
self.listbox.Bind(wx.EVT_LISTBOX, self.listboxClick)
# optional text color for the list box
self.listbox.SetForegroundColour("red")
# create buttons
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")
self.add_button = wx.Button(self, wx.ID_ANY, "add to 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)
self.add_button.Bind(wx.EVT_BUTTON, self.add_buttonClick)
# create an output widget
s1 = "load the list box ...\n"
s2 = "to select a single item left click on the item\n"
s3 = "to select a range of items shift click items\n"
s4 = "to select multiple items ctrl click on items"
self.text_out = wx.TextCtrl(self, wx.ID_ANY,
value=(s1+s2+s3+s4), size=(300, 95),
style=wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY)
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)
sizer.Add(self.add_button, pos=(0, 1), 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.text_out, pos=(8, 0), span=(2, 2),
flag=wx.ALL, border=5)
self.SetSizer(sizer)
# size the frame so all the widgets fit
self.Fit()
def add_buttonClick(self, event):
"""add another item to the listbox"""
text = wx.GetTextFromUser('Enter new item', 'Add to listbox')
if text != '':
self.listbox.Append(text)
def load_buttonClick(self, event):
"""load the name list into the bistbox"""
# use self.listbox.Set(self.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.text_out.ChangeValue("")
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(s)"""
"""
# for single item select use this ...
selected_item = self.listbox.GetStringSelection()
s = "You selected " + selected_item
self.label.SetLabel(s)
"""
name_list = self.listbox.GetItems()
# for multiple and single item select use this ...
pos_tuple = self.listbox.GetSelections()
selected_list = []
for pos in pos_tuple:
selected_list.append(name_list[pos])
s = "You selected " + str(selected_list)
self.text_out.ChangeValue(s)
name_list = [
"Erich",
"Udo",
"Jens",
"Bjorn",
"Heidrun",
"Klaus",
"Ulla",
"Volger",
"Helmut",
"Freja",
"Larry",
"Andreas",
"Harry"
]
app = wx.App(0)
# create the MyFrame instance and then show the frame
MyFrame(None, 'wx.ListBox ops', name_list).Show()
app.MainLoop() Oh darn, those accidental duplicate posts in DaniWeb!
To get individual lines coloured, you need to use the wx.ListCtrl():
# exploring wxPython's
# wx.ListCtrl(parent, id, pos, size, style)
# a fancier list box with a lot of mix-in options
# some of the styles =
# wx.LC_REPORT report mode
# wx.LC_HRULES draws horizontal rules between rows in report mode
# wx.LC_VRULES draws vertical rules between columns in report mode
# some methods =
# InsertColumn(col, heading, format=wx.LIST_FORMAT_LEFT, width=-1)
# Original Source: zoe
# explore SetItemTextColour(item, colour) to colour individual lines
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, data):
# use default size and position
wx.Frame.__init__(self, parent, wx.ID_ANY,
'Test the wx.ListCtrl()',
size=(400, 220))
self.SetBackgroundColour("yellow")
# make data available to the instance
self.data = data
# create the list control
self.lc = wx.ListCtrl(self, wx.ID_ANY, size=(-1, 120),
style=wx.LC_REPORT|wx.SUNKEN_BORDER|wx.LC_HRULES)
# select an item (left mouse click on it) and bind to an action
self.lc.Bind(wx.EVT_LIST_ITEM_SELECTED,self.onAction)
self.loadList()
# set text color of items/lines 1, 3, 5 in list to red
# needs style wx.LC_REPORT
# do this after the list is loaded
self.lc.SetItemTextColour(1, 'red')
self.lc.SetItemTextColour(3, 'red')
self.lc.SetItemTextColour(5, 'red')
# create an output widget
self.label = wx.StaticText(self, wx.ID_ANY, "Select a name")
# use a vertical boxsizer for the widget placement
sizer_v = wx.BoxSizer(wx.VERTICAL)
sizer_v.Add(self.lc, 1, flag=wx.ALL|wx.EXPAND, border=10)
sizer_v.Add(self.label, 0, flag=wx.ALL|wx.EXPAND, border=10)
self.SetSizer(sizer_v)
def loadList(self):
# first the columns with header titles
self.lc.InsertColumn(col=0,heading="Name",width=200)
#self.lc.SetColumnWidth(0, 200)
self.lc.InsertColumn(col=1,heading="Age",format=wx.LIST_FORMAT_RIGHT)
self.lc.InsertColumn(col=2,heading="Weight",format=wx.LIST_FORMAT_RIGHT)
# now each data row
for key, val in self.data.items():
# set max_rows, change if need be
max_rows = 1000
# also sets/updates row index starting at 0
index = self.lc.InsertStringItem(max_rows, val[0])
self.lc.SetStringItem(index, 1, val[1])
self.lc.SetStringItem(index, 2, val[2])
# needed by GetItemData()
self.lc.SetItemData(index, key)
def onAction(self, event):
""" some action code"""
# -1 --> get the first item that matches the specified flags
# wx.LIST_NEXT_ALL search for subsequent item by index
# wx.LIST_STATE_SELECTED get the selected item
ix_selected = self.lc.GetNextItem(item=-1,
geometry=wx.LIST_NEXT_ALL,
state=wx.LIST_STATE_SELECTED)
# get the value of the key in dictionary self.data
data_value = self.data[self.lc.GetItemData(ix_selected)]
# pick the name (first item in the value tuple)
name = ' --> ' + data_value[0]
self.label.SetLabel(str(data_value) + name)
# testing --> index and name only
ix = self.lc.GetFirstSelected()
print ix, self.lc.GetItemText(ix)
# data to load the listctrl in the form of a dictionary
# the header is ('Name', 'Age', 'Weight')
data = {
1 : ('Heidi Kalumpa', '36', '127'),
2 : ('Frank Maruco', '27', '234'),
3 : ('Larry Pestraus', '19', '315'),
4 : ('Serge Romanowski', '59', '147'),
5 : ('Carolus Arm', '94', '102'),
6 : ('Michel Sargnagel', '21', '175')
}
app = wx.App(0)
# create a MyFrame instance and show the frame
MyFrame(None, data).Show()
app.MainLoop() The wx.StyledTextCtrl allows for line numbering, code folding and syntax highlighting. Here is a simple example of this somewhat complex widget ...
# wxstc_basics1.py
# styled text using wxPython's
# wx.StyledTextCtrl(parent, id, pos, size, style, name)
# used the scintilla programming editor for guidance
# set up for line numbers, folding and Python code highlighting
# tested with Python26 and wxPython28 by vegaseat
import wx
import wx.stc as stc
import keyword
if wx.Platform == '__WXMSW__':
# for windows OS
faces = {
'times': 'Times New Roman',
'mono' : 'Courier New',
'helv' : 'Courier New',
# temporary switch
#'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 10,
'size2': 8,
}
else:
faces = {
'times': 'Times',
'mono' : 'Courier',
'helv' : 'Helvetica',
'other': 'new century schoolbook',
'size' : 12,
'size2': 10,
}
class MySTC(stc.StyledTextCtrl):
"""
set up for folding and Python code highlighting
"""
def __init__(self, parent):
stc.StyledTextCtrl.__init__(self, parent, wx.ID_ANY)
self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
# use Python code highlighting
self.SetLexer(stc.STC_LEX_PYTHON)
self.SetKeyWords(0, " ".join(keyword.kwlist))
self.SetProperty("fold", "1")
#self.SetProperty("tab.timmy.whinge.level", "1")
self.SetMargins(0, 0)
self.SetViewWhiteSpace(False)
#self.SetBufferedDraw(False)
#self.SetViewEOL(True)
#self.SetEOLMode(stc.STC_EOL_CRLF)
#self.SetUseAntiAliasing(True)
self.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
self.SetEdgeColumn(78)
# setup a margin to hold fold markers
#self.SetFoldFlags(16)
self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
self.SetMarginSensitive(2, True)
self.SetMarginWidth(2, 12)
# fold markers use square headers
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,
stc.STC_MARK_BOXMINUS, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDER,
stc.STC_MARK_BOXPLUS, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,
stc.STC_MARK_VLINE, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,
stc.STC_MARK_LCORNER, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,
stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID,
stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL,
stc.STC_MARK_TCORNER, "white", "#808080")
self.Bind(stc.EVT_STC_UPDATEUI, self.onUpdateUI)
self.Bind(stc.EVT_STC_MARGINCLICK, self.onMarginClick)
self.Bind(wx.EVT_KEY_DOWN, self.onKeyPressed)
# make some general styles ...
# the lexer defines what each style is used for
# global default styles for all languages
self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
"face:%(helv)s,size:%(size)d" % faces)
# reset all to be like the default
self.StyleClearAll()
# global default styles for all languages
self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
"face:%(helv)s,size:%(size)d" % faces)
self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,
"back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR,
"face:%(other)s" % faces)
self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
"fore:#FFFFFF,back:#0000FF,bold")
self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
"fore:#000000,back:#FF0000,bold")
# make the Python styles ...
# Default
self.StyleSetSpec(stc.STC_P_DEFAULT,
"fore:#000000,face:%(helv)s,size:%(size)d" % faces)
# Comments
self.StyleSetSpec(stc.STC_P_COMMENTLINE,
"fore:#007F00,face:%(other)s,size:%(size)d" % faces)
# Number
self.StyleSetSpec(stc.STC_P_NUMBER,
"fore:#007F7F,size:%(size)d" % faces)
# String
self.StyleSetSpec(stc.STC_P_STRING,
"fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
# Single quoted string
self.StyleSetSpec(stc.STC_P_CHARACTER,
"fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
# Keyword
self.StyleSetSpec(stc.STC_P_WORD,
"fore:#00007F,bold,size:%(size)d" % faces)
# Triple quotes
self.StyleSetSpec(stc.STC_P_TRIPLE,
"fore:#7F0000,size:%(size)d" % faces)
# Triple double quotes
self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
"fore:#7F0000,size:%(size)d" % faces)
# Class name definition
self.StyleSetSpec(stc.STC_P_CLASSNAME,
"fore:#0000FF,bold,underline,size:%(size)d" % faces)
# Function or method name definition
self.StyleSetSpec(stc.STC_P_DEFNAME,
"fore:#007F7F,bold,size:%(size)d" % faces)
# Operators
self.StyleSetSpec(stc.STC_P_OPERATOR,
"bold,size:%(size)d" % faces)
# Identifiers
self.StyleSetSpec(stc.STC_P_IDENTIFIER,
"fore:#000000,face:%(helv)s,size:%(size)d" % faces)
# Comment-blocks
self.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
"fore:#7F7F7F,size:%(size)d" % faces)
# End of line where string is not closed
self.StyleSetSpec(stc.STC_P_STRINGEOL,
"fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d"\
% faces)
self.SetCaretForeground("BLUE")
# register some images for use in the AutoComplete box
self.RegisterImage(1,
wx.ArtProvider.GetBitmap(wx.ART_TIP, size=(16,16)))
self.RegisterImage(2,
wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16)))
self.RegisterImage(3,
wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16)))
def onKeyPressed(self, event):
if self.CallTipActive():
self.CallTipCancel()
key = event.GetKeyCode()
if key == 32 and event.ControlDown():
pos = self.GetCurrentPos()
# tips
if event.ShiftDown():
self.CallTipSetBackground("yellow")
self.CallTipShow(pos,
'lots of of text: blah, blah, blah\n\n'
'show some suff, maybe parameters..\n\n'
'fubar(param1, param2)')
# code completion
else:
'''
lst = []
for x in range(50000):
lst.append('%05d' % x)
st = " ".join(lst)
print len(st)
self.AutoCompShow(0, st)
'''
kw = keyword.kwlist[:]
kw.append("zzzzzz?2")
kw.append("aaaaa?2")
kw.append("__init__?3")
kw.append("zzaaaaa?2")
kw.append("zzbaaaa?2")
kw.append("this_is_a_longer_value")
#kw.append("this_is_a_much_much_longer_value")
# Python sorts are case sensitive
kw.sort()
# so this needs to match
self.AutoCompSetIgnoreCase(False)
# images are specified with a appended "?type"
for i in range(len(kw)):
if kw[i] in keyword.kwlist:
kw[i] = kw[i] + "?1"
self.AutoCompShow(0, " ".join(kw))
else:
event.Skip()
def onUpdateUI(self, evt):
# check for matching braces
braceAtCaret = -1
braceOpposite = -1
charBefore = None
caretPos = self.GetCurrentPos()
if caretPos > 0:
charBefore = self.GetCharAt(caretPos - 1)
styleBefore = self.GetStyleAt(caretPos - 1)
# check before
if charBefore and chr(charBefore) in "[]{}()"\
and styleBefore == stc.STC_P_OPERATOR:
braceAtCaret = caretPos - 1
# check after
if braceAtCaret < 0:
charAfter = self.GetCharAt(caretPos)
styleAfter = self.GetStyleAt(caretPos)
if charAfter and chr(charAfter) in "[]{}()"\
and styleAfter == stc.STC_P_OPERATOR:
braceAtCaret = caretPos
if braceAtCaret >= 0:
braceOpposite = self.BraceMatch(braceAtCaret)
if braceAtCaret != -1 and braceOpposite == -1:
self.BraceBadLight(braceAtCaret)
else:
self.BraceHighlight(braceAtCaret, braceOpposite)
#pt = self.PointFromPosition(braceOpposite)
#self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
#print pt
#self.Refresh(False)
def onMarginClick(self, evt):
# fold and unfold as needed
if evt.GetMargin() == 2:
if evt.GetShift() and evt.GetControl():
self.foldAll()
else:
lineClicked = self.LineFromPosition(evt.GetPosition())
if self.GetFoldLevel(lineClicked) &\
stc.STC_FOLDLEVELHEADERFLAG:
if evt.GetShift():
self.SetFoldexpanded(lineClicked, True)
self.expand(lineClicked, True, True, 1)
elif evt.GetControl():
if self.GetFoldexpanded(lineClicked):
self.SetFoldexpanded(lineClicked, False)
self.expand(lineClicked, False, True, 0)
else:
self.SetFoldexpanded(lineClicked, True)
self.expand(lineClicked, True, True, 100)
else:
self.ToggleFold(lineClicked)
def foldAll(self):
lineCount = self.GetLineCount()
expanding = True
# find out if folding or unfolding
for lineNum in range(lineCount):
if self.GetFoldLevel(lineNum) &\
stc.STC_FOLDLEVELHEADERFLAG:
expanding = not self.GetFoldexpanded(lineNum)
break;
lineNum = 0
while lineNum < lineCount:
level = self.GetFoldLevel(lineNum)
if level & stc.STC_FOLDLEVELHEADERFLAG and \
(level & stc.STC_FOLDLEVELNUMBERMASK) ==\
stc.STC_FOLDLEVELBASE:
if expanding:
self.SetFoldexpanded(lineNum, True)
lineNum = self.expand(lineNum, True)
lineNum = lineNum - 1
else:
lastChild = self.GetLastChild(lineNum, -1)
self.SetFoldexpanded(lineNum, False)
if lastChild > lineNum:
self.HideLines(lineNum+1, lastChild)
lineNum = lineNum + 1
def expand(self, line, doexpand, force=False, visLevels=0, level=-1):
lastChild = self.GetLastChild(line, level)
line = line + 1
while line <= lastChild:
if force:
if visLevels > 0:
self.ShowLines(line, line)
else:
self.HideLines(line, line)
else:
if doexpand:
self.ShowLines(line, line)
if level == -1:
level = self.GetFoldLevel(line)
if level & stc.STC_FOLDLEVELHEADERFLAG:
if force:
if visLevels > 1:
self.SetFoldexpanded(line, True)
else:
self.SetFoldexpanded(line, False)
line = self.expand(line, doexpand, force, visLevels-1)
else:
if doexpand and self.GetFoldexpanded(line):
line = self.expand(line, True, force, visLevels-1)
else:
line = self.expand(line, False, force, visLevels-1)
else:
line = line + 1;
return line
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle, mysize):
wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle, size=mysize)
stc_edit = MySTC(self)
# open a Python code file you have in the working folder
# or give full path name
py_file = "wxstc_basics1.py"
stc_edit.SetText(open(py_file).read())
stc_edit.EmptyUndoBuffer()
stc_edit.Colourise(0, -1)
# line numbers in the margin
stc_edit.SetMarginType(1, stc.STC_MARGIN_NUMBER)
stc_edit.SetMarginWidth(1, 25)
app = wx.App(0)
# create a MyFrame instance and show the frame
mytitle = 'wx.StyledTextCtrl (rightclick for menu)'
MyFrame(None, mytitle, (800, 500)).Show()
app.MainLoop() I would like to suggest to change this class little:
Add import in beginning:
import sys and define MyFrame:
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle, mysize, filename=None):
wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle, size=mysize)
stc_edit = MySTC(self)
# open a Python code file you have in the working folder
# or give full path name
if not filename: self.filename=sys.argv[0]
else: self.filename = filename
stc_edit.SetText(open(self.filename).read())
stc_edit.EmptyUndoBuffer()
stc_edit.Colourise(0, -1)
# line numbers in the margin
stc_edit.SetMarginType(1, stc.STC_MARGIN_NUMBER)
stc_edit.SetMarginWidth(1, 25) Then it is not sensitive to filename the program is using, and it is possible to set the filename from programme.
@tonyjv
Kind of poor to use commandline arguments in a GUI environment. If you want to swell the code given, it would be best to use wxPython's excellent wx.FileDialog widget.
It is not using command line, only prevent hard coding of programs name by reading it from argv[0] instead of literal string.
This is just a quick example of how i use empty wx.BoxSizer() to hold spaces for borders ect. It makes the layout much easier to controll the borders, widgets ect on multiple panels as the programs i design get much bigger and more complicated. There is probably a much easier, faster and simpler way to do this, but this is the method i came up with as i dont know any other.
import wx
class SpacerExample(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title = "Spacer example", size = (350, 370))
panel = wx.Panel(self)
font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL, False, "Mangal")
title = wx.StaticText(panel, label = "Border using sizers", style = wx.ALIGN_CENTRE)
title.SetFont(font)
set1text = wx.StaticText(panel, label = "Please enter something")
set1box = wx.TextCtrl(panel)
set2text = wx.StaticText(panel , label = "Please enter something else")
set2box = wx.TextCtrl(panel)
set3text = wx.StaticText(panel, label = "Please enter something else again")
set3box = wx.TextCtrl(panel)
save = wx.Button(panel, label = "Save")
cancel = wx.Button(panel, label = "Cancel")
#these are my spaces in the main column
topspace = wx.BoxSizer()
vertspc1 = wx.BoxSizer()
vertspc2 = wx.BoxSizer()
vertspc3 = wx.BoxSizer()
vertspc4 = wx.BoxSizer()
vertspc5 = wx.BoxSizer()
#these spacers are my right and left borders
hzlspc1 = wx.BoxSizer()
hzlspc2 = wx.BoxSizer()
#this is the space between my buttons
hzlspc3 = wx.BoxSizer()
buttonarr = wx.BoxSizer()
buttonarr.Add(cancel, proportion = 3, flag = wx.EXPAND)
buttonarr.Add(hzlspc3, proportion = 1)
buttonarr.Add(save, proportion = 3, flag = wx.EXPAND)
#this organises the main column of my programme
mainsizer = wx.BoxSizer(wx.VERTICAL)
mainsizer.Add(topspace, proportion = 1)
mainsizer.Add(title, proportion = 4, flag = wx.EXPAND)
mainsizer.Add(vertspc1, proportion = 1)
mainsizer.Add(set1text, proportion = 2)
mainsizer.Add(set1box, proportion = 2, flag = wx.EXPAND)
mainsizer.Add(vertspc2, proportion = 2)
mainsizer.Add(set2text, proportion = 2)
mainsizer.Add(set2box, proportion = 2, flag = wx.EXPAND)
mainsizer.Add(vertspc3, proportion = 2)
mainsizer.Add(set3text, proportion = 2)
mainsizer.Add(set3box, proportion = 2, flag = wx.EXPAND)
mainsizer.Add(vertspc4, proportion = 2)
mainsizer.Add(buttonarr, proportion = 2, flag = wx.EXPAND)
mainsizer.Add(vertspc5, proportion = 2)
#this adds the left and right border
layout = wx.BoxSizer()
layout.Add(hzlspc1, proportion = 1)
layout.Add(mainsizer, proportion = 8)
layout.Add(hzlspc2, proportion = 1)
#this sets the sizers in action, i only need to set the top one
panel.SetSizer(layout)
app = wx.App(redirect=False)
window = SpacerExample()
window.Show()
app.MainLoop() I like to keep my code minimalistic, and i will admit this way of doing things can get hectic when multiple panels/botton arrangements are involved but this is the only way i know how to do this and get my desired results, i hope this helps and i hope someone more experienced can show you the perfect method.
Here is example of simple wx program using functions to set common options to widgets, see http://www.daniweb.com/forums/post1374954.html#post1374954
Program is missing the final action and progress bar part, it is exercise for the reader. Not so much comments in the program, also.
import os
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Remote Administrator v1.0", (500,500), (425,280))
self.font = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL, 0, 'Microsoft Sans Serif')
self.dictcomputers={
u"Atel": [(u'PC%i' % n) for n in range(1,1+12)],
u"Sint-Andries": [(u'PC%i' % n) for n in range(1,1+8)],
u"Permee": [(u'PC%i' % n) for n in range(1,1+5)] }
self.panel = wx.Panel(self, wx.ID_ANY)
self.listcomputers = wx.ListBox(self.panel, 1, (8,16), (120, 150),
[], wx.LB_MULTIPLE)
self.listcomputers.SetBackgroundColour(wx.Colour(255, 255, 255))
self.font_and_cursor(self.listcomputers)
self.listcomputers.Bind(wx.EVT_LISTBOX, self.onlistcomputers)
start = wx.Button(self.panel, -1, 'Start', (8, 176), (75, 23))
start.Bind(wx.EVT_BUTTON, self.onStart)
self.timer = wx.Slider(self.panel, -1, 0, 0, 10,
(136, 48), (104, 45),
wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_BOTTOM |
wx.SL_RIGHT | wx.SL_LABELS)
self.timer.Bind(wx.EVT_SLIDER, self.onAdjust)
label = wx.StaticText(self.panel, -1, 'Timer:', (144,32), (100, 23))
self.font_and_cursor(label)
radios = (self.make_radio('Shutdown', 88), self.make_radio('Logoff', 112), self.make_radio('Reboot', 136))
self.CreateStatusBar()
loc = wx.ComboBox(self.panel, -1, 'Select Location',
(269, 21), (121, 21), self.dictcomputers.keys())
loc.SetBackgroundColour(wx.Colour(255, 255, 255))
self.font_and_cursor(loc)
loc.Bind(wx.EVT_COMBOBOX, self.onLocation)
self.progressbar = wx.Gauge(self.panel, -1, 100,
(264, 128), (137, 17))
self.font_and_cursor(self.progressbar)
self.progressbar.SetValue(0)
def font_and_cursor(self, widget):
widget.SetFont(self.font)
widget.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
def make_radio(self, label, pos):
Radio = wx.RadioButton(self.panel, -1, label, (136, pos), (104, 24))
Radio.SetFont(self.font)
Radio.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
Radio.SetValue(0)
Radio.Bind(wx.EVT_RADIOBUTTON, self.onRadio)
return Radio
def onLocation(self, event):
self.location = event.GetEventObject().GetValue()
self.Hide()
self.Update()
self.Refresh()
self.Show()
self.SetStatusText(self.location)
self.listcomputers.Set(self.dictcomputers[self.location])
self.pclst = []
def onlistcomputers(self, event):
self.pclst = [event.GetEventObject().GetItems()[pc] for pc in event.GetEventObject().GetSelections()]
self.SetStatusText("Selected Computers: %s" % ', '.join(self.pclst))
def onAdjust(self, event):
self.SetStatusText("Timer set to: %s " % (event.GetEventObject().GetValue()))
def onRadio(self, event):
action = event.GetEventObject().GetLabel()
self.action = action
self.SetStatusText("Selected " + action)
def onStart(self, event):
if event.GetEventObject().GetLabel() == "Start":
try:
if not self.pclst[0]:
raise IndexError
message = ("Doing %s %s at %s, computer%s: %s" %
(self.action,
'in %s seconds' % self.timer.GetValue() if self.timer.GetValue() else 'immediately',
self.location,
's' if len(self.pclst)>1 else '',
', '.join(self.pclst) ) )
except AttributeError:
self.SetStatusText("Failed starting actions")
wx.MessageBox('Not all required fields are filled in!\nPlease correct this and try again.', 'Error')
except IndexError:
self.SetStatusText("Failed starting actions")
wx.MessageBox('No PC selected!\nPlease correct this and try again.', 'Error')
else:
self.SetStatusText(message)
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop() I like personally the wx.FlexGridSizer than all the sizers.
with FlexGridSizer and the normal wx.BoxSizer you can make layouts that you realy desire.
;)
One way to create a rainbow effect:
# explore wxPython's
# GradientFillLinear(rect, initialColour, destColour, nDirection=EAST)
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle, mysize):
wx.Frame.__init__(self, parent, -1, mytitle, size=mysize)
self.SetBackgroundColour('black')
# bind the frame to the paint event canvas
wx.EVT_PAINT(self, self.onPaint)
def onPaint(self, event=None):
# the wxPython drawing canvas
dc = wx.PaintDC(self)
# create rainbow effect in three adjoining sections
# section1, color gradient from red to yellow
dc.GradientFillLinear((10, 10, 200, 100), 'red', 'yellow')
# section2, color gradient from yellow to green
dc.GradientFillLinear((210, 10, 200, 100), 'yellow', 'green')
# section3, color gradient from green to blue
dc.GradientFillLinear((410, 10, 200, 100), 'green', 'blue')
app = wx.App(0)
mytitle = "GradientFillLinear() Rainbow"
width = 630
height = 155
MyFrame(None, mytitle, (width, height)).Show()
app.MainLoop() Creating a small LED clock with wxPython:
# wxPython's wx.gizmos.LEDNumberCtrl() widget
# can be used for an LED clock
import wx
import wx.gizmos
import time
class LedClock(wx.Frame):
"""
create an LED clock showing the current time
"""
def __init__(self, parent=None):
wx.Frame.__init__(self, parent, -1, title='LED Clock',
size=(320, 100))
# default colors are green on black
self.led = wx.gizmos.LEDNumberCtrl(self, -1,
style=wx.gizmos.LED_ALIGN_CENTER)
# set up a timer
self.timer = wx.Timer(self, -1)
# update clock digits every second (1000ms)
self.timer.Start(1000)
# bind the timer to a method
self.Bind(wx.EVT_TIMER, self.update_clock)
def update_clock(self, event):
# get the current time tuple from the computer
current = time.localtime(time.time())
# time string can have characters 0..9, -, period, or space
ts = time.strftime("%H %M %S", current)
self.led.SetValue(ts)
app = wx.App(0)
LedClock().Show()
app.MainLoop() A moving image can be created this way with wxPython ...
# show a moving image using a wx.ClientDC() canvas on a panel
# tested with Python27 and wxPython28 by vegaseat
import wx
class CanvasPanel(wx.Panel):
""" create a panel with a canvas to draw on"""
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
# pick a small .jpg, .png, .gif, or .bmp image file
# you have in the working folder or give full path
image_file = 'Duck3.jpg'
self.bmp = wx.Bitmap(image_file)
# initial x position of image
self.x = 0
# this small delay may be needed to
# allow initial loading of large images
#wx.FutureCall(50, self.create_canvas)
# now create the canvas
wx.EVT_SIZE(self, self.create_canvas)
self.timer = wx.Timer(self)
# Start(int milliseconds, oneShot=False)
# lower timer interval gives faster speed
self.timer.Start(30)
# bind EVT_TIMER event to self.onTimer()
self.Bind(wx.EVT_TIMER, self.onTimer)
def onTimer(self, event):
self.canvas.Clear()
# DrawBitmap(bitmap, x, y, bool transparent)
# x, y are upper left corner coordinates of image location
self.canvas.DrawBitmap(self.bmp, self.x, 10, True)
# increment x to start moving
self.x += 1
# optional continuous movement
# experiment with wrap around values
if self.x > 500:
self.x = -250
# print(self.x) # test
def create_canvas(self, event=None):
"""create the paint canvas"""
self.canvas = wx.ClientDC(self)
app = wx.App(0)
frame = wx.Frame(None, -1, "Watch the duck move", size=(500, 400))
# will fill the frame
CanvasPanel(frame)
frame.Show(True)
app.MainLoop() This seems to be a relatively easy way to create a timed alert message in your wxPython program.
The wx.SplashScreen() widget takes is message as an image file, so let's create that first ...
# create an alert image for a wx.SplashScreen()
# and safe it to an image file eg. alert007.jpg
import wx
class MyFrame(wx.Frame):
def __init__(self, parent=None, id=-1, title=None):
wx.Frame.__init__(self, parent, id, title, size=(320, 200))
self.draw_image()
self.save_image()
def draw_image(self):
# select the width and height of the blank bitmap
# should fit the client frame
w, h = 280, 80
# create the blank bitmap as a draw background
draw_bmp = wx.EmptyBitmap(w, h)
# create the canvas on top of the draw_bmp
canvas_dc = wx.MemoryDC(draw_bmp)
# make the canvas yellow
canvas_dc.SetBackground(wx.Brush('yellow'))
canvas_dc.Clear()
face = u'Comic Sans MS'
font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, face)
canvas_dc.SetFont(font)
canvas_dc.SetTextForeground('red')
s1 = 'The host name should be superman.'
s2 = 'Closing this window in 3 seconds ...'
canvas_dc.DrawText(s1, x=10, y=10)
canvas_dc.DrawText(s2, x=10, y=40)
self.stat_bmp = wx.StaticBitmap(self)
# now put the canvas drawing into a bitmap to
# display and later save it to an image file
# (remember the canvas is on top of draw_bmp)
self.stat_bmp.SetBitmap(draw_bmp)
def save_image(self):
"""save the drawing that is on the bitmap"""
finished_image = self.stat_bmp.GetBitmap()
finished_image.SaveFile("alert007.jpg", wx.BITMAP_TYPE_JPEG)
app = wx.App(0)
MyFrame(title='canvas draw text and save').Show()
app.MainLoop() Now we can insert the splash scrren into the program, something like this will do ...
# using a wx.SplashScreen() to splash a timed alert message
import wx
import os
class Frame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(400, 300))
host = os.system('hostname')
if host != 'superman':
# pick a splash image file you have in the working folder
image_file = 'alert007.jpg'
bmp = wx.Bitmap(image_file)
duration = 3000 # milliseconds
# covers the parent frame self
wx.SplashScreen(bmp,
wx.SPLASH_CENTRE_ON_PARENT|wx.SPLASH_TIMEOUT,
duration,
self,
wx.ID_ANY)
else:
self.Center()
#self.Show()
app = wx.App(0)
frame = Frame(None, -1, 'Splash')
# for testing
frame.Show()
app.MainLoop() I am experimenting with overlapping transparent images using wxPython. Here is something I came up with (used one of vegaseat's images):
# use wx.Image() to create two overlapping transparent images
import wx
class ImagePanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, wx.ID_ANY)
self.parent = parent
# pick 2 image files you have in the working folder
# (or give the full path)
image_file1 = 'Duck_right.jpg'
image_file2 = 'Duck_left.jpg'
# default is type=wx.BITMAP_TYPE_ANY
self.image1 = wx.Image(image_file1)
self.image2 = wx.Image(image_file2)
# need this ...
self.image1.InitAlpha()
self.image2.InitAlpha()
# call on_paint() to create the canvas
wx.EVT_PAINT(self, self.on_paint)
def on_paint(self, event):
dc = wx.PaintDC(self)
# reduces flicker
#dc = wx.BufferedDC(dc)
# set the canvas background color to a light grey
dc.SetBackground(wx.Brush("#D0D0D0"))
#dc.SetBackground(wx.Brush("white")) # if you like
dc.Clear()
# adjust r g b and alpha (transparency) of image
# AdjustChannels(fr, fg, fb, fa)
# adjust alphas from 0.0 to 1.0 to see the effects
alpha1 = 0.5
alpha2 = 0.7
if self.image1.HasAlpha():
image1 = self.image1.AdjustChannels(1.0, 1.0, 1.0, alpha1)
image2 = self.image2.AdjustChannels(1.0, 1.0, 1.0, alpha2)
else:
image1 = self.image1
image2 = self.image2
self.parent.SetTitle("no alpha")
# required to draw images on canvas
bmp1 = wx.BitmapFromImage(image1)
bmp2 = wx.BitmapFromImage(image2)
# now draw the images
dc.DrawBitmap(bmp2, 180, 10, True)
dc.DrawBitmap(bmp1, 20, 70, True)
app = wx.App(0)
mytitle = "wx.Image transparent overlapping images"
mysize = (500, 400)
frame = wx.Frame(None, wx.ID_ANY, title=mytitle, size=mysize)
ImagePanel(frame)
frame.Show(True)
app.MainLoop() Shows you how to use the Python module threading with wxPython:
# -*- coding: utf-8 -*-
###########################################################################
## Python code partially generated with wxFormBuilder (version Apr 10 2012)
## http://www.wxformbuilder.org/
###########################################################################
import wx
import threading
import time
class MyFrame( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Seconds Counter",
pos = wx.DefaultPosition, size = wx.Size( 236,173 ),
style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
self.SetBackgroundColour( wx.Colour( 0, 0, 255 ) )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
self.m_textCtrl = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition,
wx.DefaultSize, 0 )
self.m_textCtrl.SetFont( wx.Font( 20, 74, 90, 92, False, "Comic Sans MS" ) )
bSizer1.Add( self.m_textCtrl, 0, wx.ALL, 5 )
self.m_button_start = wx.Button( self, wx.ID_ANY, u"Start", wx.DefaultPosition,
wx.DefaultSize, 0 )
bSizer1.Add( self.m_button_start, 0, wx.ALL, 5 )
self.m_button_stop = wx.Button( self, wx.ID_ANY, u"Stop", wx.DefaultPosition,
wx.DefaultSize, 0 )
bSizer1.Add( self.m_button_stop, 0, wx.ALL, 5 )
self.SetSizer( bSizer1 )
self.Layout()
# Connect Events
self.m_button_start.Bind( wx.EVT_LEFT_DOWN, self.m_button_startOnLeftDown )
self.m_button_stop.Bind( wx.EVT_LEFT_DOWN, self.m_button_stopOnLeftDown )
def m_button_startOnLeftDown( self, event ):
self.counter = Counter(0, 1, self.m_textCtrl)
self.counter.start()
pass
def m_button_stopOnLeftDown( self, event ):
count = self.counter.finish()
print(count) # test
pass
class Counter(threading.Thread):
"""
create a thread object that will do the counting in a separate thread
"""
def __init__(self, value, increment, display_widget):
# init the thread
threading.Thread.__init__(self)
# initial value
self.value = value
# amount to increment
self.increment = increment
# controls the while loop in the run command
self.alive = False
# display widget
self.display = display_widget
def run(self):
"this will run in a separate thread"
self.alive = True
while self.alive:
# delay for 1 second
time.sleep(1)
self.value += self.increment
print(self.value) # test
self.display.SetValue(str(self.value))
def peek(self):
"return the current value"
return self.value
def finish(self):
"close the thread, return final value"
# stop the while loop in 'run'
self.alive = False
return self.value
app = wx.App(0)
# create a MyFrame instance and show the frame
frame = MyFrame(None)
frame.Center()
frame.Show()
app.MainLoop()
# set up your wx application this way
# allows you to check if same app instance is already running
import wx
class MyApp(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
self.frame = wx.Frame(parent=None, id=-1, size=(400,300),
pos=(150,150), title=mytitle)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
if __name__ == '__main__':
# error redirection=0 to console
app = MyApp(0)
app.MainLoop()