wxPython的布局
每一个程序都会有一个界面或者称之为layout、布局,在html中,我们可能使用div,在html5中,我们或许会使用header、footer标签。如果使用的是flex,或者可以用一个mx:VDividedBox。最方便的是C#,我们直接从工具箱里拖出一个splitcontainer或者一个tablelayoutpanel。那么在wxPython中,我们怎么做呢?
1、使用wx.SplitterWindow进行布局
我们当然可以使用wx.Panle进行布局,又或者自己写一个class myWindow(wx.Window),不过从我接触wxPython的短短的时间里,我觉得wx.SplitterWindow挺好用的
上图是一个简单的使用wx.SplitterWindow实现的布局,pyCrust的界面同样是使用了wx.SplitterWindow
以下是一个最简单的实现,需要注意的是,如果没有绑定事件wx.EVT_SIZE,点最大化出一个有趣的问题
# -*- coding:utf-8 -*-
'''
Created on 2013-1-6
@author: jincheng
'''
import wx
import com.jincheng.AbstractModel as jca
import com.jincheng.common as jcc
class myFrame(wx.Frame):
def __init__(self,parent,title,size):
wx.Frame.__init__(self,parent,-1,title,size = size)
self.SetBackgroundColour('white')
#布局 size
self.width = self.Size.width
self.height = self.Size.height
self.up = self.Size.height/3*2
self.down = self.Size.height/3
self.left = self.Size.width/4
self.right = self.Size.width/4*3
#上下结构
self.spltUD = wx.SplitterWindow(self,size = size)
self.winUp = wx.Window(self.spltUD,-1,(0,0),(self.width,self.up))
self.winUp.SetBackgroundColour('red')
self.winDown = wx.Window(self.spltUD,-1,(0,self.up),(self.width,self.down))
self.winDown.SetBackgroundColour('black')
self.spltUD.SplitHorizontally(self.winUp,self.winDown,-10)
#左右结构
self.spltLF = wx.SplitterWindow(self.winUp,size = (self.width,self.up))
self.winLeft = wx.Window(self.spltLF,-1,(0,0),(self.left,self.up))
self.winLeft.SetBackgroundColour('yellow')
self.winRight = wx.Window(self.spltLF,-1,(0,self.left),(self.right,self.up))
self.winRight.SetBackgroundColour('green')
self.spltLF.SplitVertically(self.winLeft,self.winRight,-10)
#事件绑定
self.Bind(wx.EVT_SIZE,self.OnSize)
def OnSize(self,event):
size = event.Size
self.spltUD.Size=event.Size
self.spltLF.Size=(size.width,size.height - self.winDown.Size.height)
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = myFrame(None,'title',(800,600))
frame.Show(True)
app.MainLoop()
2、喜欢重构不是我的错-> _ ->
上面的代码虽然已经能够得到我预期的结果,但是代码实在有够不便。虽然我的水平很菜,但还是会忍不住要重构一下啊!!
创建一个spltOpera类用于创建splitterWindow及构成splt的两个窗口,这两个窗口会被放在self.windows里,以便于在frame中使用
spltOpera类可以作为一个common类被不断地重用
# -*- coding:utf-8 -*-
'''
Created on 2012-12-25
@author: jincheng
@name:com.jincheng.common
'''
import wx
class spltOpera():
def __init__(self,parent,size):
self.parent = parent
self.windows = []
self.splt = wx.SplitterWindow(self.parent,size = size)
def _winBuild(self,pos,size):
win = wx.Window(self.splt,-1,pos,size)
self.windows.append(win)
def spltBuild(self,winData,bHorizon=True,sashPosition=10):
'''
winData = (((0,0),(800,600)),
(0,600),(800,200))
'''
self.winData = winData
for windata in winData:
self._winBuild(windata[0],windata[1])
if bHorizon:
self.splt.SplitHorizontally(self.windows[0],self.windows[1],sashPosition)
else:
self.splt.SplitVertically(self.windows[0],self.windows[1],sashPosition)
self.parent.Bind(wx.EVT_SIZE,self.OnSize)
return self.splt
def OnSize(self,event):
#size = event.Size
self.splt.Size = self.parent.Size
创建一个layout类,用于构建独属于本次实例的layout,同时在frame中调用
# -*- coding:utf-8 -*-
'''
Created on 2013-1-6
@author: jincheng
'''
import wx
import com.jincheng.AbstractModel as jca
import com.jincheng.common as jcc
class layout():
def __init__(self,parent):
self.parent = parent
self.windows = []
def layoutBuild(self):
#布局 size
self.width = self.parent.Size.width
self.height = self.parent.Size.height
self.up = self.parent.Size.height/3*2
self.down = self.parent.Size.height/3
self.left = self.parent.Size.width/4
self.right = self.parent.Size.width/4*3
winDataUD = (((0,0),(self.width,self.up)),
((0,self.up),(self.width,self.down)))
spltOUD = jcc.spltOpera(self.parent,self.parent.Size)
self.spltUD = spltOUD.spltBuild(winDataUD)
self.windows.append(spltOUD.windows)
winDataLR = (((0,0),(self.left,self.up)),
((self.left,0),(self.right,self.up)))
spltOLR = jcc.spltOpera(spltOUD.windows[0],(self.width,self.up))
self.spltLR = spltOLR.spltBuild(winDataLR,False,-10)
self.windows.append(spltOLR.windows)
class myFrame(wx.Frame):
def __init__(self,parent,title,size):
wx.Frame.__init__(self,parent,-1,title,size = size)
_layout = layout(self)
_layout.layoutBuild()
self.winUp = _layout.windows[0][0]
self.winUp.SetBackgroundColour('green')
self.winDown = _layout.windows[0][1]
self.winDown.SetBackgroundColour('yellow')
self.winLeft = _layout.windows[1][0]
self.winLeft.SetBackgroundColour('red')
self.winRight = _layout.windows[1][1]
self.winRight.SetBackgroundColour('pink')
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = myFrame(None,'title',(800,600))
frame.Show(True)
app.MainLoop()
源码push不到github……那就不传了吧……
3、通过wx.Notebook添加选项卡
在C#中,我们通过拖一个TabControl完成添加选项卡的工作,在flex我们选择mx:TabNavigator标签。在wxPython中,可以使用wx.Notebook
wx.Notebook的init需要一个parent,一个pos,还有一个size,在这个例子中,我选择将notebook放在winRight中
class myFrame(wx.Frame):
def __init__(self,parent,title,size):
wx.Frame.__init__(self,parent,-1,title,size = size)
_layout = layout(self)
_layout.layoutBuild()
self.winUp = _layout.windows[0][0]
self.winUp.SetBackgroundColour('green')
self.winDown = _layout.windows[0][1]
self.winDown.SetBackgroundColour('yellow')
self.winLeft = _layout.windows[1][0]
self.winLeft.SetBackgroundColour('red')
self.winRight = _layout.windows[1][1]
self.winRight.SetBackgroundColour('pink')
#ntoebook
self.notebook = wx.Notebook(self.winRight,id = -1,pos = (0,0),size = self.winRight.Size)
self.txtwork = wx.TextCtrl(self.notebook)
self.notebook.AddPage(self.txtwork,'workspace',True)
#menubar
menuO = jcc.menuOpera(self)
menuO.menubarBuild(None)
#statusbar
statusBar = self.CreateStatusBar()