初步使用wx.aui.AuiManager构建界面



在wxPython示例中,充分体验出AuiManager构建Layout的优势, 加以利用可以完全构建出类似visual studio的界面。



示例的布局太复杂……第一次使用,尝试构建一个简单一点的界面练习,如下图



只有2个部分,左侧和中间内容。实现代码:

#!/usr/bin/python
#
 coding=utf-8

import wx
import wx.aui;

class MainUIHelper(object):
    
    def __init__(self, frame):
        object.__init__(self);
        
        self.Frame = frame;
        frame.Helper = self;


    def CreateAuiManager(self, configs):
        if(len(configs) > 0):
            #制造Layout
            self.AuiManager = wx.aui.AuiManager();
            self.AuiManager.SetManagedWindow(self.Frame);
            for c in configs:
                self.AuiManager.AddPane(c.Control, c.PaneInfo);
            self.AuiManager.Update();
        
        

class AuiConfigModel(object):
    
    def __init__(self, control, paneInfo):
        object.__init__(self);
        self.Control = control;
        self.PaneInfo = paneInfo;        
 


MainUIHelper是一个界面的辅助类,主要有几句:
1、

self.AuiManager.SetManagedWindow(self.Frame);

告诉主界面,现在由AuiManager进行布局。
2、

self.AuiManager.AddPane(c.Control, c.PaneInfo);

为布局添加模块,第一个参数为模块容器中的控件,第二个参数是模块容器的属性。
3、

self.AuiManager.Update();

将所有的布局设置提交,类似数据库事务的Commit。

在主界面调用代码,如下图所示(只有部分):

#!/usr/bin/python
#
 coding=utf-8

import wx
import wx.aui;
import wx.grid;
import mainUIHelper;
import start;
import os;

class MainUIFrame(wx.Frame):
    
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "SqlQuery",pos=wx.DefaultPosition,
                                size = (500,400), 
                                style=wx.DEFAULT_FRAME_STYLE |wx.SUNKEN_BORDER |wx.CLIP_CHILDREN );
        #初始化
        mainUIHelper.MainUIHelper(self);
                
        #绘画布局
        self.Helper.CreateAuiManager([
            mainUIHelper.AuiConfigModel(self.CreateLeft(), wx.aui.AuiPaneInfo()
                                .Name("left").Caption("Script Folder").Left()
                                .CloseButton(False)
                                .MaximizeButton(True)), 
            mainUIHelper.AuiConfigModel(self.CreateGrid(), wx.aui.AuiPaneInfo()
                                .Name("gridContent").CenterPane())]);


其中self.CreateLeft()和self.CreateGrid()只是返回一些控件,注意的是后面的AuiPaneInfo对象。

设置它属性的方式如jquery的“链式代码”,如

wx.aui.AuiPaneInfo()
                                .Name("left").Caption("Script Folder").Left()
                                .CloseButton(False)
                                .MaximizeButton(True)

意思是
1、命名模块为"left"
2、标题为Script Folder
3、靠在布局的左边
4、不需要关闭模块按钮
5、显示最大化按钮

AuiPaneInfo还有很多属性可以设置,详细查看API。


遍历文件夹

用Python实现遍历一个文件夹里面的内容,为了方便演示,把文件夹的内容构建一个树控件输出。

Python有一个os.walk(path)的函数,方便遍历文件夹内的内容。

for root, dirs, files in os.walk('Script'):
    print root;
    print dirs;
    print files;
    print "---------";


walk循环返回的是维度为3的数组,分别为
root - 当前循环的文件夹
dirs  - 文件夹中有多少子文件夹
files  - 文件夹中有多少文件

walk会自动递归搜索出所有文件和文件夹信息,因此一般情况用这个函数就可以非常省事。

也由于walk太智能的关系,用walk没有办法按我们的意愿,有顺序的输出文件信息,因此无法构建出想要的树控件。

因此摈弃了walk函数,用一个递归文件夹的函数。

def listFile(path, action, level=0):
    if os.path.isdir(path):        
        action(path, True, level);
        
    for subPath in os.listdir(path):
        fullPath = os.path.join(path, subPath);
        if os.path.isdir(fullPath):
            listFile(fullPath, action, level + 1);
        else :            
            action(fullPath, False, level);


其中action是处理路径的方式,action有3个参数,第一个参数为路径;第二个参数为bool,True代表此路径为文件夹,False代表路径为文件;第三个参数是当前路径的相对层,设置根目录的层为0。

我们可以这样调用代码,输出文件夹文件。

def listFile(path, action, level=0):
    if os.path.isdir(path):        
        action(path, True, level);
        
    for subPath in os.listdir(path):
        fullPath = os.path.join(path, subPath);
        if os.path.isdir(fullPath):
            listFile(fullPath, action, level + 1);
        else :            
            action(fullPath, False, level);


def showPath(path, isdir, level):
    if isdir:
        print level * "     ""[D]:",path;
    else:
        print level * "     ","  " , "[F]:", os.path.basename(path);


listFile("Script", showPath);


输出的每个文件夹具有层次效果:


同理,我们可以构造创建树控件的action函数。

我们紧接着第一个AuiManager的示例,在左边的Module创建添加这样的树控件,因此我们下面实现CreateLeft函数:

def CreateLeft(self):
        s = "";
        #遍历文件夹
        defaultScriptFolder = os.path.join(start.GetExecutePath(),"script");
        if not os.path.exists(defaultScriptFolder):
            os.mkdir(defaultScriptFolder);        
                    
        self.scriptTree = wx.TreeCtrl(self, -1, (0,0), wx.DefaultSize,
                    wx.TR_DEFAULT_STYLE );       

        currentRoot = self.scriptTree.AddRoot(os.path.basename(defaultScriptFolder));
        
        #Key : path of folder
        #Node: TreeNode
        cacheNode = { defaultScriptFolder: currentRoot };
                
        def CreateNode(path, isdir, level):
            if path != defaultScriptFolder:
                parentDirName = os.path.dirname(path);
#                print parentDirName
                tempNode = self.scriptTree.AppendItem(cacheNode[parentDirName], 
                                        os.path.basename(path));
                if isdir:
                    cacheNode.setdefault(path, tempNode);
                else :
                    pass
            
        self.ListFile(defaultScriptFolder, CreateNode);

#        for k,y in cacheNode.items():
#
            print "%s: %s"%(k,y)

        #释放
        cacheNode.clear();
        
        return self.scriptTree;    


    def ListFile(self, path, action, level=0):
        if os.path.isdir(path):        
            action(path, True, level);
            
        for subPath in os.listdir(path):
            fullPath = os.path.join(path, subPath);
            if os.path.isdir(fullPath):
                self.ListFile(fullPath, action, level + 1);
            else :            
                action(fullPath, False, level);


创建了一个内部的函数,CreateNode,当作action参数传入ListFile递归调用。

效果如下图所示:




全部代码:/Files/seeyeah/SqlQuery.zip
(注:Script文件夹的文件需要自己放置,任意放一些就可以显示效果。)

 

posted @ 2013-10-14 10:52  springbarley  阅读(3363)  评论(0)    收藏  举报