初步使用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文件夹的文件需要自己放置,任意放一些就可以显示效果。)