wxPython簡(jiǎn)介
wxPython是一個(gè)用于創(chuàng)建桌面GUI應(yīng)用程序的跨平臺(tái)工具包壶硅。wxPython的主要作者是Robin Dunn场躯。使用wxPython剩蟀,開(kāi)發(fā)人員可以在Windows,Mac和各種Unix系統(tǒng)上創(chuàng)建應(yīng)用程序猖辫。wxPython是wxWidgets的包裝器,它是一個(gè)成熟的跨平臺(tái)C ++庫(kù)砚殿。
wxPython API文檔:https://docs.wxpython.org/
安裝wxPython
pip 是 Python 的包管理工具啃憎,該工具提供了對(duì)Python 包的查找、下載似炎、安裝辛萍、卸載的功能。在Python官網(wǎng)下載較新版本的Python羡藐,就會(huì)自帶pip贩毕。
輸入命令行指令:
pip install wxpython
wxFormBuilder
wxFormBuilder是一款基于wxWidgets的GUI可視化編輯工具,可用于Python的GUI設(shè)計(jì)仆嗦。
wxFormBuilder項(xiàng)目GitHUb:www.wxformbuilder.org/
第一個(gè)wxPython程序
接下來(lái)辉阶,我們借助wxFormBuiler來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的文本編輯器以此來(lái)熟悉wxPython的使用。
- 第一步,打開(kāi)wxFormBuilder谆甜,可見(jiàn)到如下界面垃僚。
界面主要分為四大區(qū):項(xiàng)目區(qū)Object Tree、控件區(qū)Component Palette规辱、編輯區(qū)Editor谆棺、屬性區(qū)Object Properties。
在控件區(qū)里點(diǎn)擊添加需要的控件罕袋,這些控件的效果會(huì)在編輯區(qū)里實(shí)時(shí)顯示改淑,并在屬性區(qū)顯示這些控件的屬性,項(xiàng)目區(qū)用于顯示控件間的層級(jí)關(guān)系浴讯。
- 第二步,讓我們開(kāi)始創(chuàng)建一個(gè)GUI的基礎(chǔ)框架溅固,先從控件區(qū)里的Forms中添加一個(gè)Frame,這是GUI的輪廓基礎(chǔ):
*第三步是在Frame下添加一個(gè)Layout中的wxBoxSizer兰珍,后續(xù)所有控件均是放在wxBoxSizer里的侍郭。
如果你覺(jué)得單個(gè)wxBoxSizer里的控件布局太單調(diào),你可以嵌套使用wxBoxSizer掠河,這是實(shí)現(xiàn)GUI界面控件布局多樣化的關(guān)鍵亮元。
本次編寫(xiě)的文本編輯器就嵌套了wxBoxSizer,需要在第一個(gè)wxBoxSizer中再添加一個(gè)wxBoxSizer:
接著在右側(cè)的屬性區(qū)修改其相關(guān)的屬性唠摹,將bSizer2的orient改為wxHORIZONTZL爆捞,proportion改為0。
這樣bSizer2中的控件就變成水平排列的了勾拉,而且bSizer2在bSizer1中的比例為保持bSizer2中的控件大小煮甥,具體的效果會(huì)在后面顯示出來(lái):
- 第四步,在bSizer2中添加Common中的1個(gè)wxTextCtrl藕赞,2個(gè)wxButton:
現(xiàn)在就能看到第三步中對(duì)bSizer2的orient和proportion屬性設(shè)置的效果了成肘,三個(gè)控件依次水平排列,且整個(gè)bSizer2的高度是與其中控件高度有關(guān)的斧蜕。
接下來(lái)分別修改m_textCtrl1双霍、m_button和m_button2的屬性,將其name依次改名為filePath批销、open和save洒闸,將textCtrl的proportion改為1,兩個(gè)button的label改為“打開(kāi)”和“保存”均芽,最終效果為:
- 第五步丘逸,在bSizer1下再添加一個(gè)wxTextCtrl,并將name修改為content掀宋,proportion改為1深纲,flag下勾選wx.EXPAND羞反,其效果為:
flag=wx.EXAPND和proportion=1使得整個(gè)文本框填充了bSizer1的剩余空間,這樣一個(gè)文本編輯框的UI就初步完成了囤萤。
接下點(diǎn)擊Editor下的Python標(biāo)簽昼窗,就能看到UI對(duì)應(yīng)的源碼了,將其復(fù)制起來(lái):
打開(kāi)你的python IDE涛舍,創(chuàng)建一個(gè)project澄惊,將源碼粘貼到里面。
為MyFrame1
添加兩個(gè)方法富雅,分別用來(lái)打開(kāi)和保存文本掸驱,需傳入event來(lái)綁定按鍵:
def open(self, event): # 打開(kāi)文件
# 彈出文件選擇對(duì)話框
dlg = wx.FileDialog(self, u'選擇要打開(kāi)的txt文件', style=wx.DD_DEFAULT_STYLE)
if dlg.ShowModal() == wx.ID_OK:
# 按下OK后的邏輯
self.fileName.SetValue(dlg.GetPath()) # 將選擇文件的路徑輸出到fileName里
file = open(self.fileName.GetValue()) # 以只讀打開(kāi)選中文件
self.textEdit.SetValue(file.read()) # 將文件中的文本輸出到textEdit里
file.close() # 關(guān)閉文件
dlg.Destroy() # 關(guān)閉對(duì)話框
def save(self, event): # 保存文件
file = open(self.fileName.GetValue(), 'w') # 打開(kāi)選中文件,可編輯
file.write(self.textEdit.GetValue()) # 將textEdit中的文本寫(xiě)入文件
file.close() # 關(guān)閉文件
在MyFrame1.__init__()
下為兩個(gè)方法綁定對(duì)應(yīng)按鍵:
self.openFile.Bind(wx.EVT_BUTTON, self.open)
self.saveFile.Bind(wx.EVT_BUTTON, self.save)
在此python文件下添加以下代碼:
if __name__ == '__main__':
app = wx.App() # 創(chuàng)建一個(gè)應(yīng)用程序?qū)ο竺挥印C總€(gè)wxPython程序必須有一個(gè)應(yīng)用程序?qū)ο蟆?
frame = MyFrame1(None) # 創(chuàng)建一個(gè)MyFrame1對(duì)象
frame.Show() # 調(diào)用該對(duì)象的 Show()方法以在屏幕上實(shí)際顯示它
# 進(jìn)入主循環(huán)毕贼。主循環(huán)是一個(gè)無(wú)盡的循環(huán)。它捕獲并發(fā)送應(yīng)用程序生命周期中存在的所有事件蛤奢。
app.MainLoop()
到此鬼癣,一個(gè)文本編輯器就寫(xiě)完了,運(yùn)行效果如下:
源碼
# -*- coding: utf-8 -*-
import wx
###########################################################################
## Class MyFrame1
###########################################################################
class MyFrame1(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=u"文本編輯器", pos=wx.DefaultPosition, size=wx.Size(600, 400),
style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
bSizer1 = wx.BoxSizer(wx.VERTICAL)
bSizer2 = wx.BoxSizer(wx.HORIZONTAL)
self.fileName = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
bSizer2.Add(self.fileName, 1, wx.ALL, 5)
self.openFile = wx.Button(self, wx.ID_ANY, u"打開(kāi)", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer2.Add(self.openFile, 0, wx.ALL, 5)
self.saveFile = wx.Button(self, wx.ID_ANY, u"保存", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer2.Add(self.saveFile, 0, wx.ALL, 5)
bSizer1.Add(bSizer2, 0, wx.EXPAND, 5)
bSizer3 = wx.BoxSizer(wx.VERTICAL)
self.textEdit = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
bSizer3.Add(self.textEdit, 1, wx.ALL | wx.EXPAND, 5)
bSizer1.Add(bSizer3, 1, wx.EXPAND, 5)
self.SetSizer(bSizer1)
self.Layout()
self.Centre(wx.BOTH)
self.openFile.Bind(wx.EVT_BUTTON, self.open)
self.saveFile.Bind(wx.EVT_BUTTON, self.save)
def __del__(self):
pass
def open(self, event): # 打開(kāi)文件
# 彈出文件選擇對(duì)話框
dlg = wx.FileDialog(self, u'選擇要打開(kāi)的txt文件', style=wx.DD_DEFAULT_STYLE)
if dlg.ShowModal() == wx.ID_OK: # 按下OK后的邏輯
self.fileName.SetValue(dlg.GetPath()) # 將選擇文件的路徑輸出到fileName里
file = open(self.fileName.GetValue()) # 以只讀打開(kāi)選中文件
self.textEdit.SetValue(file.read()) # 將文件中的文本輸出到textEdit里
file.close() # 關(guān)閉文件
dlg.Destroy() # 關(guān)閉對(duì)話框
def save(self, event): # 保存文件
file = open(self.fileName.GetValue(), 'w') # 打開(kāi)選中文件啤贩,可編輯
file.write(self.textEdit.GetValue()) # 將textEdit中的文本寫(xiě)入文件
file.close() # 關(guān)閉文件
if __name__ == '__main__':
app = wx.App()
frame = MyFrame1(None)
frame.Show()
app.MainLoop()