软件综合实验课程要求设计一个数据库管理小软件,在上次的使用C语言开发失败后(被字符处理给搞得头大了),这次决定使用Python开发,正好也逼迫自己学习一下Python.由于作业要求开发一个图形管理软件,所以选择了wxPython来做GUI.数据库操作部分使用MySQLdb.整个软件有1644行,数据库使用MySQL 5.5.18-log Community.Python版本为2.7.2.wxPython版本没注意,应该是2.8版本.整个软件实现以下功能:添加/修改数据库,实现了基本的编号自动生成功能.没有制作的是查找功能.不会制作的是报表生成功能.下面总结此次作业中的重点代码.
0.编码统一
这是及其重要的一部分,因为wxPython默认使用ANCII编码。
#coding=UTF-8 #指定Python使用UTF-8编码
import sys
reload(sys) #重载sys库。不然下面一条setdefaultcoding会提示无这个函数
sys.setdefaultcoding(‘utf-8′) #指定系统使用utf-8编码,这样wxPython也会使用utf-8,而不是ancii
1.数据库操作
数据库的操作使用MySQLdb库来编写.给我的感觉是该库是一个C语言MySQL函数库的Python实现.唯一的区别是select语句返回结果,C语言中是数组,Python中Tuple.(其实两者区别不大.)
conn=MySQLdb.connect(host,username,passwd,db) #连接数据库
cur=conn.cursor() #实例化一个游标
cur.execute(sql) #执行sql语句
#如果是select操作,那么使用以下方法获取结果
results=cur.fetchall() #结果返回的是一个Tuple类型的数据
#如果是create/update/delete等操作,需要以下方法使sql操作生效
conn.commit()
cur.close() #关闭游标
conn.close() #关闭连接
2.GUI设计
i.初始化wxPython APP
不论是何种wxPython,都需要先实例化wxPython,在程序最外层全局初始化:
app=wx.App(False)
app.MainLoop()
ii.底层Frame窗口
wxPython中的wx.Frame是一个窗口画布控件,一般用它来作GUI的底层,主界面的其他元素都应该画制在Frame层之上。可以简单的只是创建一个wx.Frame的实例化对象,也可以写一个类来继承wx.Frame类,并且重构__init__()函数来创建自己的Frame模板。下面是一个简单的自定义的wx.Frame继承类:
class MainWindow(wx.Frame):
def __init__(self,parent,titile): #实例化MainWindow时做的初始化操作
wx.Frame.__init__(self,parent,titile) #调用wx.Frame的初始化函数
这样一个简单的自定义的wx.Frame继承类就完成了。你可以在Frame中放置许多元素。wx.Frame也拥有一些自己特有的元素。下面是制作一个简单的MenuBar和StatusBar代码应该放置在MainWindow类的初始化函数中:
self.CreateStatusBar() #在Frame中创建一个StatusBar。wxPython会自动将其放置在窗口最底部
FileMenu=wx.Menu() #创建一个File下拉菜单
exitMenu=FileMenu.Append(wx.ID_EXIT,”Exit”,”Exit”) #在File菜单中附加一个Exit退出按钮
MenuBar=wx.MenuBar() #创建一个MenuBar
MenuBar.Append(FileMenu,”File”) #将File菜单附加到MenuBar中
self.SetMenuBar(MenuBar) #将MenuBar添加到MainWindow中。
一个带MenuBar和StatusBar的Frame类就创建完成了。不过还没完事呢,还需要给exitMenu按钮绑定事件才行:
self.Bind(wx.EVT_MENU,self.OnExit,exitMenu)
还需要写一个事件函数:
def OnExit(self,e):
self.close()
完成的MainWindow类如下:
class MainWindow(wx.Frame):
def __init__(self,parent,titile): #实例化MainWindow时做的初始化操作
wx.Frame.__init__(self,parent,titile) #调用wx.Frame的初始化函数
self.CreateStatusBar() #在Frame中创建一个StatusBar。wxPython会自动将其放置在窗口最底部
FileMenu=wx.Menu() #创建一个File下拉菜单
exitMenu=FileMenu.Append(wx.ID_EXIT,”Exit”,”Exit”) #在File菜单中附加一个Exit退出按钮
MenuBar=wx.MenuBar() #创建一个MenuBar
MenuBar.Append(FileMenu,”File”) #将File菜单附加到MenuBar中
self.SetMenuBar(MenuBar) #将MenuBar添加到MainWindow中。
self.Bind(wx.EVT_MENU,self.OnExit,exitMenu)
def OnExit(self,e):
self.close()
iii.Panel画布控件
wx.Panel画布控件,其实它并没有任何内容,仅仅是一张画布,让开发者可以将其他控件放置在上面。它不能独立工作,必须有一个父窗口,比如wx.Frame。通过它可以将不同功能分区设计。它不能放置MenuBar和StatusBar之类的控件,不过它还是可以放置很多其他GUI控件的。后面要提到的Grid控件,Button控件,BoxSizer控件等都可以放置其中。
class MainPanel(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self,parent)
iv.Button控件
和上面提到的ExitMenu一样,Button控件工作也需要一次实例化,一次事件绑定,一个事件函数:
BuExit=wx.Button()
self.Bind(wx.EVT_BUTTON,self.OnBuExit,BuExit)
def OnBuExit(self,e):
self.close()
v.Grid控件
Grid是一种网格控件。它是wxPython的一部分,不过仅仅import wxPython不够,基本的wxPython库不包含Grid控件。需要import wxPython.grid才行。
wxPython.grid库是一个包含所有wxWidget.grid控件的库。这次我只使用了wxPython.grid.Grid控件,其它更高级的控件并没有使用到。
self.grid=wx.grid.Grid(self) #实例化一个GRID
self.grid.CreateGrid(rowlen,collen) #创建Grid网格,rowlen,collen为行列数目,即创建一个rowlen行collen列的网格
self.grid.SetColLabelValue(colnum,string) #设定列名。colnum为列号,string为列名
self.grid.SetRowLabelValue(rownum,string) #设定行名。
self.grid.SetCellValue(rownum,colnum,string) #设定单元格的值。
vi.BoxSizer控件
BoxSizer控件是帮助开发者排列其他控件元素的工具。它是非常有用的工具。BoxSizer有两种样式,分别是HORIZONTAL和VERTICAL,放置在同一个BoxSizer中的元素以指定样式排列。BoxSizer可以嵌套排列,所以在一个布局中,开发者会创建多个BoxSizer来排列各种元素。
abox=wx.BoxSizer(VERTICAL) #竖排样式的BoxSizer
bbox=wx.BoxSizer(HORIZONTAL) #横排样式的BoxSizer
abox.Add(Button1,flag=CENTER,border=5) #将Button1添加入abox中
abox.Add(Button2,flag=CENTER,border=5)
bbox.Add(abox,border=5) #BoxSizer的嵌套。
bbox.Add(self.grid,border=5) #将grid添加入bbox中。
self.SetSizer(box) #记得要设定BoxSizer,否则BoxSizer不生效。
vii.ComboBox/StaticText/TextCtrl控件
这三个控件的代码很少,所以放一起讲。
st1=wx.StaticText(self,label=”test”,size=(-1,-1)) #创建一个StaticText
txt1=wx.TextCtrl(self,size) #创建一个TextCtrl
txt1.SetValue(string) #设定txt1的内容。不设定则为空。
val=txt1.GetValue() #获取txt1中的内容
cb1=wx.ComboBox(self,value,choices=list(val),style) #此处value指ComboBox的选项条数,choices为选项内容,必须为list类型,style为可选项。
viii.Dialog控件
wx.Dialog控件可以看成是一个特殊的Frame控件,它可以独立工作,而不需要父窗口的依赖。它也是一个画布,没有内容的Dialog就是一个空空的窗口。下面是一个wx.Dialog的自定义继承类:
class Dialog(wx.Dialog):
def __init__(self,parent,title):
wx.Dialog.__init__(self,parent,title) #调用wx.Dialog初始化函数
self.ShowModal() #别忘记让它显示出来。不然Dialog即使激活,也是不显示任何窗口的。
ix.MessageDialog控件
从控件名就可以看出它是一个消息提示框。这并不是一个很难的控件。
dlg=wx.MessageDialog(self,para,title,style) #para为消息提示内容,title为框口标题。style为窗口类型,比如一个带ok按钮的窗口。
dlg.ShowModal() #显示dlg
dlg.DestroyModal() #如在按下ok键后销毁。
以上就是这次实验中的控件和库函数的使用简介。至于怎样调用数据库进行操作,各位看官的心中应该早已有方法了,在此不做说明了。整个程序还有很多不足之处,很多方法还可以继续抽象出来,进行程序优化。功能上也还有未实现的部分以及功能的不足。
参考资料:
下面是本次实验的全部代码下载: