使用wxPython 模組去記錄視窗程式設計-第二篇(位置篇)
目前使用的環境:windows 7、Portable Python 2.7.6.1、wxPython 3.0
這章將加入更多元件例子,我只寫程式碼,複製程式碼執行可以看到測試結果,
如此方便學習及加速開發程式時間,但更多說明要自己參考下面的參考文件。
(1) Layout management
Layout 管理在是視窗程式設計不容易的,有兩種方式使用絕對位置及可大小變化的相對位置
(1.1)使用絕對位置視窗
# -*- coding: big5 -*-
#-------------------------------------------------------------------------------
# absolute.py
import wx
class absolute(wx.Frame):
def __init__(self, parent, title):
super(absolute, self).__init__(parent, title='絕對位置視窗',
size=(260, 180))
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
panel = wx.Panel(self, -1)
menubar = wx.MenuBar()
filem = wx.Menu()
editm = wx.Menu()
helpm = wx.Menu()
menubar.Append(filem, '&檔案')
menubar.Append(editm, '&編輯')
menubar.Append(helpm, '&幫助')
self.SetMenuBar(menubar)
wx.TextCtrl(panel, pos=(3, 3), size=(250, 150))
if __name__ == '__main__':
app = wx.App()
absolute(None, title='')
app.MainLoop()
#-------------------------
(1.2)使用.wx.frame內建的相對位置
# -*- coding: big5 -*-
#-------------------------
# sizer.py
#-------------------------
import wx
class Example(wx.Frame):
def __init__(self, parent, title):
super(Example, self).__init__(parent, title='相對位置視窗',
size=(260, 180))
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
menubar = wx.MenuBar()
filem = wx.Menu()
editm = wx.Menu()
helpm = wx.Menu()
menubar.Append(filem, '&檔案')
menubar.Append(editm, '&編輯')
menubar.Append(helpm, '&幫助')
self.SetMenuBar(menubar)
wx.TextCtrl(self)
if __name__ == '__main__':
app = wx.App()
Example(None, title='')
app.MainLoop()
Using sizers
- wx.BoxSizer
- wx.StaticBoxSizer
- wx.GridSizer
- wx.FlexGridSizer
- wx.GridBagSizer
-------------------------
(1.3)使用wx.BoxSizer 相對位置視窗
# -*- coding: big5 -*-
#-------------------------
# box = wx.BoxSizer(integer orient)
# box.Add(wx.Window window, integer proportion=0, integer flag = 0, integer border = 0)
#-------------------------
# border.py
# Border around a panel
import wx
class Example(wx.Frame):
def __init__(self, parent, title):
super(Example, self).__init__(parent, title=title,
size=(260, 180))
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
panel = wx.Panel(self)
panel.SetBackgroundColour('#4f5049') #設定大panel背景顏色
vbox = wx.BoxSizer(wx.VERTICAL) #方向可以是 wx.VERTICAL or wx.HORIZONTAL
midPan = wx.Panel(panel)
midPan.SetBackgroundColour('#ededed') #設定小panel背景顏色
vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 20) # 20 px border around a midPan panel.
panel.SetSizer(vbox) # flag = wx.EXPAND| wx.ALL 組合邊界至四個邊
if __name__ == '__main__':
app = wx.App()
Example(None, title='Border')
app.MainLoop()
#-------------------------
Box = wx.BoxSizer(wxHORIZONTAL) Box = wx.BoxSizer(wxVERTICAL) Box.Add(control, proportion, flag, border)
Alignment Flags
wx.ALIGN_TOP |
wx.ALIGN_BOTTOM |
wx.ALIGN_LEFT |
wx.ALIGN_RIGHT |
wx.ALIGN_CENTER_VERTICAL |
wx.ALIGN_CENTER_HORIZONTAL |
Border Flags
wx.TOP |
wx.BOTTOM |
wx.LEFT |
wx.RIGHT |
wx.ALL |
Behavior Flags
S.N. | Behavior Flags & Description |
---|---|
1 |
wx.EXPAND Item will expand to fill the space provided to it (wx.GROW is the same) |
2 |
wx.SHAPED Similar to EXPAND but maintains the item's aspect ratio |
3 |
wx.FIXED_MINSIZE Does not let the item become smaller than its initial minimum size |
4 |
wx.RESERVE_SPACE_EVEN_IF_ HIDDEN Does not allow the sizer to reclaim an item's space when it is hidden |
另一個例子
class BoxSizerPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super(BoxSizerPanel, self).__init__(*args, **kwargs)
# Attributes
self._field1 = wx.TextCtrl(self)
self._field2 = wx.TextCtrl(self)
# Layout
self._DoLayout()
def _DoLayout(self):
vsizer = wx.BoxSizer(wx.VERTICAL)
field1_sz = wx.BoxSizer(wx.HORIZONTAL)
field2_sz = wx.BoxSizer(wx.HORIZONTAL)
# 兩個 labels
field1_lbl = wx.StaticText(self, label="Field 1:")
field2_lbl = wx.StaticText(self, label="Field 2:")
# label and field 加至第一個水平box
field1_sz.AddSpacer(50) #增加50 px 空白
field1_sz.Add(field1_lbl) #加入label 1
field1_sz.AddSpacer(5) #增加 5px 空白
field1_sz.Add(self._field1) #加入field 1
field1_sz.AddSpacer(50)
# label and field 加至第二個水平box
field2_sz.AddSpacer(50)
field2_sz.Add(field2_lbl)
field2_sz.AddSpacer(5)
field2_sz.Add(self._field2)
field2_sz.AddSpacer(50)
# 增加二個水平box 至一個較大的直box
vsizer.AddSpacer(50)
vsizer.Add(field1_sz)
vsizer.AddSpacer(15)
vsizer.Add(field2_sz)
vsizer.AddSpacer(50)
# 指定主要外層box 至panel
self.SetSizer(vsizer)
更多位置管理請參考 http://zetcode.com/wxpython/layout/
https://www.tutorialspoint.com/wxpython/wx_boxsizer.htm
wx.GridSizer
wx.FlexGridSizer
wx.GridBagSizer
(2) Menus and toolbars
# -*- coding: big5 -*-
#-------------------------
import wx
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
menubar = wx.MenuBar() #增加一個 menubar類別
fileMenu = wx.Menu() #增加一個 submenu類別
fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application') #subitem 內容
menubar.Append(fileMenu, '&File') # submenu 內容
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
self.SetSize((300, 200))
self.SetTitle('Simple menu')
self.Centre()
self.Show(True)
def OnQuit(self, e):
self.Close()
def main():
ex = wx.App()
Example(None)
ex.MainLoop()
if __name__ == '__main__':
main()
Toolbars
import wx
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
toolbar = self.CreateToolBar()
qtool = toolbar.AddLabelTool(wx.ID_ANY, 'Quit', wx.Bitmap('texit.png'))
toolbar.Realize()
self.Bind(wx.EVT_TOOL, self.OnQuit, qtool)
self.SetSize((250, 200))
self.SetTitle('Simple toolbar')
self.Centre()
self.Show(True)
def OnQuit(self, e):
self.Close()
def main():
ex = wx.App()
Example(None)
ex.MainLoop()
if __name__ == '__main__':
main()
(3)Simple Events
事件處理步驟
(1) 事件類型
(2) 事件處理程式
(3) 連結事件型和事件處理程式
(3.1) Simple Events 設定及動作
# -*- coding: big5 -*-
#-------------------------
import wx
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.InitUI()
def InitUI(self):
wx.StaticText(self, label='x:', pos=(10,10))
wx.StaticText(self, label='y:', pos=(10,30))
self.st1 = wx.StaticText(self, label='', pos=(30, 10))
self.st2 = wx.StaticText(self, label='', pos=(30, 30))
self.Bind(wx.EVT_MOVE, self.OnMove) # 事件監聽(event type, event handle)
self.SetSize((250, 180))
self.SetTitle('Move event')
self.Centre()
self.Show(True)
def OnMove(self, e):
x, y = e.GetPosition()
self.st1.SetLabel(str(x))
self.st2.SetLabel(str(y))
def main():
ex = wx.App()
Example(None)
ex.MainLoop()
if __name__ == '__main__':
main()
(3.2)Events 傳遞 in wxPython
事件有二種類型,基本事件及命令事件,基本事件不會傳遞,命令事件會從子類別傳給父類別,祖類別直到有事件處理者接手才會停止傳遞
另外 Veto()
method 可以停止Event, Skip()
method 可以跳開傳遞
# -*- coding: big5 -*-
#-------------------------
import wx
class MyPanel(wx.Panel):
def __init__(self, *args, **kw):
super(MyPanel, self).__init__(*args, **kw)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
def OnButtonClicked(self, e):
print 'event reached panel class'
e.Skip()
class MyButton(wx.Button):
def __init__(self, *args, **kw):
super(MyButton, self).__init__(*args, **kw)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked) # 事件監聽
def OnButtonClicked(self, e):
print 'event reached button class'
e.Skip()
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.InitUI()
def InitUI(self):
mpnl = MyPanel(self)
MyButton(mpnl, label='Ok', pos=(15, 15))
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
self.SetTitle('Propagate event')
self.Centre()
self.Show(True)
def OnButtonClicked(self, e):
print 'event reached frame class'
e.Skip()
def main():
ex = wx.App()
Example(None)
ex.MainLoop()
if __name__ == '__main__':
main()
#-----------------------------
這個應用程式有 app ->frame -> Panel -> Button , 所以事件發生在 button, button 事件處理者傳遞事件,所以傳遞路徑是 button-> panel -> frame
#---------------------------
參考資料
http://zetcode.com/wxpython/
留言列表