guidata库使用手记:快速定制科学计算程序的图形界面
本帖最后由 Rainyboy 于 2011-9-3 11:44 编辑和大多数的Python库一样,guidata有自己的技术支持页面和实例完善的帮助文档,然而文档毕竟是死的,只有使用起来更能体会其中的奇技淫巧。
完整文档:http://packages.python.org/guidata/
概述(译自 guidata documentation/overview)
对于科学计算软件的开发,从最基本的模块直至最复杂的应用程序,开发者都需要灵活地方便地操纵数据(例如,数据处理时输入的参数)。这些数据由多种类型组成:实数(如一些物理量),整数(如数组的索引),字符串(如文件名),布尔值(如某个选项的开关)等等。大多数时候,这类软件需满足如下需求:
1)允许用户在图形界面上输入每一个参数的值,即通过一些控件来对应特定数据类型的输入(例如,一个单选框/一组复选框对应于单选或复选操作)
2)输入的数据必须在程序中由于之对应的方式储存(例如,对于单元数据的储存,难道不应当储存选项的说明字符串和整个选择列表的索引么?)
3)该储存方式同时应当易于使用(例如,在后续的数据处理中易于访问)
4)通过图形界面向用户展示参数的设置,同样,需要使用与数据相对应控件
一个例子:选择指定的实验数据进行对比
需求:
1)用户在图形界面上选择要进行对比的数据组(多选)
2)根据用户的选择绘出指定的实验数据曲线(这一部分工作有Matplotlab完成)
3)当用户完成选择后回显以确认
完整的代码见附件,这里需要说明的是上述需求1)和3)的实现全在函数editFromGUI(fnameList)中:
def editFromGUI(fnameList):
#_app = guidata.qapplication()
class ParameterUGI(dt.DataSet):
choice = di.MultipleChoiceItem("Select files to plot", fnameList)
param = ParameterUGI()
while(True):
param.edit()
if len(param.choice)!=0:
break
param.view()
return param.choice
参照文档这个函数并不难理解,那么guidata是如何体现“储存的数据易于使用”的呢?见函数main():
def main():
_app = guidata.qapplication()
fnameList = ['OnAxis_R.txt','OnAxis_Z.txt','OnBox_Box.txt',
'OnGear_1.txt','OnGear_2.txt']
colorList = ['blue','green','black','red','purple']
markerList =
lineList = [[],[]]
labelList = []
l = editFromGUI(fnameList)
initPlot()
for i in l:
line1,line2=PlotSingleFile(fnameList,colorList,markerList)
lineList.append(line1)
lineList.append(line2)
labelList.append(fnameList)
plt.figure(1)
plt.subplot(2,1,1)
plt.legend(lineList,labelList,5)
plt.subplot(2,1,2)
plt.legend(lineList,labelList,5)
plt.show()
_app.exec_()
其中,l = editFromGUI(fnameList) 说明 l 引用的正是在函数 editFromGUI中定义param.choice的,显然,这是一个类型为di.MultipleChoiceItem的对象。而在main()函数中,完成对editFromGUI调用后,出现了 for i in l: ,这意味着l同时具有了可遍历的功能(即,l具有list对象对具有的基本访问功能),在这里完全可以当作一个list使用,这正是概述中“3)该储存方式同时应当易于使用”的完美体现!
这个例子运行起来时,会先展示这样一个窗口:
可以选择几项:
点击确定,出现这个窗口:
点击确定后,根据所选读取文件数据并绘制图形:
奇技淫巧:如何让你的对象表现得像个具有特性功能的list
(当然,这里对象的意思是instance,不是marriage partner)
class rainyboy:
__index = -1
def __init__(self,a,b):
self.list = range(a,b,2)
def __getitem__(self,key):
return self.list
def __str__(self):
return repr(self.list)
def __len__(self):
return len(self.list)
def __call__(self):
return 'rainyboy'
def __iter__(self):
return iter(self.list)
return self
def next(self):
self.__index = self.__index + 1
if self.__index == len(self):
raise StopIteration
return self.list
对于上面这个类,执行这样的代码:
if __name__ == '__main__':
c = rainyboy(1,20)
print c,c,c,len(c)
print c()
for i in c:
print i
会输出:
1 3 10
rainyboy
1
3
5
7
9
11
13
15
17
19
怎么样?C是一个Rainyboy类的对象,C可以像list那样被整个print出来,也可以单独按索引值访问,还可以返回数据的长度,还可以像函数那样被调用,甚至可以迭代访问!这些功能得益于重写或定义了如下函数:
可以像list那样被print出来: __str__
可以按索引值访问:__getitem__
可以求得数据区的长度:__len__
可以像函数那样被调用:__call__
可以迭代访问:__iter__ , next
使用感受
正如guidata在review中所言,这确实是一款适合为科学计算定制数据输入界面的库类——使用该库类的人只需要关注很少量的图形界面知识,甚至没有定义任何的消息-响应映射。布局(layout)是图形界面设计中很重要的一环,在guidata中甚至也不用刻意设置——前提是你接受它默认的样子。当然,布局是可以设置的,更多的例子可以运行它的示例:
from guidata import tests
tests.run()
你真是一个执着的人 回复 2 # smtmobly 的帖子
见笑了,边用边学而已。。。
好久没见你出现了,近况如何? 开学了,最近挺好,谢谢哈!有空我常来看的,但是python好久不用了 挺好,谢谢哈!
页:
[1]