欢迎订阅公众号 数据分析那些事儿
前言
Python的GUI开发有很多的第三方库,wxPython、Qt和Gtk+等等。关于他们的对比网络上有很多的文章,在易用性、跨平台、稳定性等方面都有详细的比较,本文就不再赘述了。但是有一个共识是,如果你只是做一个非商业化的窗口程序,那么wxPython对于新手来说是一个非常好的选择。
wxPython函数传递机制
不同于Qt,wxWidgets是一个事件驱动的,对于触发的事件,需要给它挂上相应的事件处理函数。wxPytong函数的形式是这样的:
wx.Frame.Bind(self, event, handler, source=None, id=-1, id2=-1)
在一般使用时,我们基本上只会给定event、handler和source,event是事件的名称,handler是处理函数,source是事件的发生者,比如一个Button1被单击而发生了EVT_BUTTON事件,如果我们用self.OnButton1()来处理,会这么写:
self.Bind(wx.EVT_BUTTON, self.OnButton1, self.Button1)
这里self是一个Frame(wxPython中的窗体这样的东西),而Button1是放在这个Frame下面的一个Button,self.OnButton1就是事件处理函数。而wxPython定死了事件处理函数的形式:
def handler(self,event):
...
事件处理函数只能接受两个参数,一个还是self。event是那个发生的事件。
学习记录APP
先看个效果
代码
#-*- coding: utf-8 -*-
import wx
import sys, os
from openpyxl import Workbook
from openpyxl import load_workbook
APP_TITLE = u'学习记录APP'
DEST_FILENAME = '学习汇总.xlsx'
class mainFrame(wx.Frame):
'''程序主窗口类,继承自wx.Frame'''
f = open("study.txt","r")
ls_blank = [None]*11
def __init__(self, parent):
'''构造函数'''
wx.Frame.__init__(self, parent, -1, APP_TITLE)
self.SetBackgroundColour(wx.Colour(224, 224, 224))
self.SetSize((800, 600))
self.Center()
BaseX=40
BaseY=70
BaseSize=150
wx.StaticText(self, -1, u'编号', pos=(BaseX, BaseY), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'姓名', pos=(BaseX, BaseY+30), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容1',pos=(BaseX, BaseY+60), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容2',pos=(BaseX, BaseY+90), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容3',pos=(BaseX, BaseY+120), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容4',pos=(BaseX, BaseY+150), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容5',pos=(BaseX, BaseY+180), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容6',pos=(BaseX, BaseY+210), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容7',pos=(BaseX, BaseY+240), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容8',pos=(BaseX, BaseY+270), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
wx.StaticText(self, -1, u'内容9',pos=(BaseX, BaseY+300), size=(BaseSize, -1), style=wx.ALIGN_LEFT)
self.tip = wx.StaticText(self, -1, u'请点击下一条学习!', pos=(145, 20), size=(500, -1), style=wx.ALIGN_CENTER)
self.tc1 = wx.TextCtrl(self, -1, '', pos=(250, BaseY), size=(300, -1), name='TC01', style=wx.TE_CENTER)
self.tc2 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+30), size=(300, -1), name='TC02', style=wx.TE_CENTER)
self.tc3 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+60), size=(300, -1), name='TC03', style=wx.TE_CENTER)
self.tc4 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+90), size=(300, -1), name='TC04', style=wx.TE_CENTER)
self.tc5 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+120), size=(300, -1), name='TC05', style=wx.TE_CENTER)
self.tc6 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+150), size=(300, -1), name='TC06', style=wx.TE_CENTER)
self.tc7 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+180), size=(300, -1), name='TC07', style=wx.TE_CENTER)
self.tc8 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+210), size=(300, -1), name='TC08', style=wx.TE_CENTER)
self.tc9 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+240), size=(300, -1), name='TC09', style=wx.TE_CENTER)
self.tc10 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+270), size=(300, -1), name='TC10', style=wx.TE_CENTER)
self.tc11 = wx.TextCtrl(self, -1, '', pos=(250, BaseY+300), size=(500, 150), name='TC11', style=wx.TE_CENTER)
btn_next = wx.Button(self, -1, u'下一条', pos=(650, 20), size=(100, 25))
btn_save = wx.Button(self, -1, u'保存', pos=(650, 80), size=(100, 25))
# 控件事件
self.tc1.Bind(wx.EVT_TEXT, self.EvtText)
self.tc2.Bind(wx.EVT_TEXT, self.EvtText)
self.tc3.Bind(wx.EVT_TEXT, self.EvtText)
self.tc4.Bind(wx.EVT_TEXT, self.EvtText)
self.tc5.Bind(wx.EVT_TEXT, self.EvtText)
self.tc6.Bind(wx.EVT_TEXT, self.EvtText)
self.tc7.Bind(wx.EVT_TEXT, self.EvtText)
self.tc8.Bind(wx.EVT_TEXT, self.EvtText)
self.tc9.Bind(wx.EVT_TEXT, self.EvtText)
self.tc10.Bind(wx.EVT_TEXT, self.EvtText)
self.tc11.Bind(wx.EVT_TEXT, self.EvtText)
self.Bind(wx.EVT_BUTTON, self.DisNext, btn_next)
self.Bind(wx.EVT_BUTTON, self.SaveInfo, btn_save)
# 系统事件
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_SIZE, self.On_size)
def EvtText(self, evt):
'''输入框事件函数'''
obj = evt.GetEventObject()
objName = obj.GetName()
text = evt.GetString()
if objName == 'TC01':
self.ls_blank[0] = text
elif objName == 'TC02':
self.ls_blank[1] = text
elif objName == 'TC03':
self.ls_blank[2] = text
elif objName == 'TC04':
self.ls_blank[3] = text
elif objName == 'TC05':
self.ls_blank[4] = text
elif objName == 'TC06':
self.ls_blank[5] = text
elif objName == 'TC07':
self.ls_blank[6] = text
elif objName == 'TC08':
self.ls_blank[7] = text
elif objName == 'TC09':
self.ls_blank[8] = text
elif objName == 'TC10':
self.ls_blank[9] = text
elif objName == 'TC11':
self.ls_blank[10] = text
def On_size(self, evt):
'''改变窗口大小事件函数'''
self.Refresh()
evt.Skip()
def OnClose(self, evt):
'''关闭窗口事件函数'''
dlg = wx.MessageDialog(None, u'确定要关闭本窗口?', u'操作提示', wx.YES_NO | wx.ICON_QUESTION)
if(dlg.ShowModal() == wx.ID_YES):
self.Destroy()
def DisNext(self, evt):
'''下一条触发事件函数'''
'''读出一条'''
line = self.f.readline()
if line:
self.tip.SetLabel(line)
else:
self.tip.SetLabel(u'已经学完!!!')
def SaveInfo(self, evt):
'''保存事件函数'''
'''读取目的表格'''
wb = Workbook()
ws = wb.active
for i in range(len(self.ls_blank)):
_ = ws.cell(column=i+1, row=1, value=self.ls_blank[i])
wb.save(filename = DEST_FILENAME)
dlg = wx.MessageDialog(None, u'保存成功!')
if(dlg.ShowModal() == wx.ID_YES):
self.Destroy()
class mainApp(wx.App):
def OnInit(self):
self.SetAppName(APP_TITLE)
self.Frame = mainFrame(None)
self.Frame.Show()
return True
if __name__ == "__main__":
app = mainApp()
app.MainLoop()