close

使用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()

absolute positioning 1

#-------------------------

(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()

absolute positioning 2

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()

Border around a panel

#-------------------------

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

Calculator

wx.FlexGridSizer

Review

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()

A simple menu example

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()

Simple toolbar

(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/

回主目錄

arrow
arrow
    全站熱搜

    stanley 發表在 痞客邦 留言(0) 人氣()