用Python創建一個Doubletalk浏覽器
Ok, 現在讓我們做些有用的東西,用這種方法學習更多關於wXPython框架的知識。就象其它的GUI工具包所展示的,我們將創建一個小型的應用程序,圍繞著D oubletalk類庫(它允許浏覽和編輯交易)。
MDI框架
我們打算實現一個多文檔界面(譯注,即MDI),子框架除了為獨立的“文檔”外,其中還包含著交易數據的不同視圖。如同前面的例子,要做的第一件事就是創建一個應用程序類,並且在它的O nInit方法中創
建一個主框架:
from wxPython.wx import *
class DoubleTalkBrowserApp(wxApp):
def OnInit(self):
frame = MainFrame(NULL)
frame.Show(true)
self.SetTopWindow(frame)
return true
app = DoubleTalkBrowserApp(0)
app.MainLoop()
因為我們正在使用MDI,所以需要一個特別的類用來做為框架的基本類。這裡的給出主程序框架的初始化方法的代碼:
class MainFrame(wxMDIParentFrame):
title = "Doubletalk Browser - wxPython Edition"
def __init__(self, parent):
wxMDIParentFrame.__init__(self, parent, -1, self.title)
self.bookset = None
self.views = []
if wxPlatform == ’__WXMSW__’:
self.icon = wxIcon(’chart7.ico’, wxBITMAP_TYPE_ICO)
self.SetIcon(self.icon)
# 創建一個狀態條,在右邊顯示時間和日期
sb = self.CreateStatusBar(2)
sb.SetStatusWidths([-1, 150])
self.timer = wxPyTimer(self.Notify)
self.timer.Start(1000)
self.Notify()
menu = self.MakeMenu(false)
self.SetMenuBar(menu)
menu.EnableTop(1, false)
EVT_MENU(self, ID_OPEN, self.OnMenuOpen)
EVT_MENU(self, ID_CLOSE, self.OnMenUClose)
EVT_MENU(self, ID_SAVE, self.OnMenuSave)
EVT_MENU(self, ID_SAVEAS,self.OnMenuSaveAs)
EVT_MENU(self, ID_EXIT, self.OnMenuExit)
EVT_MENU(self, ID_ABOUT, self.OnMenuAbout)
EVT_MENU(self, ID_ADD, self.OnAddTrans)
EVT_MENU(self, ID_JRNL, self.OnViewJournal)
EVT_MENU(self, ID_DTAIL, self.OnViewDetail)
EVT_CLOSE(self, self.OnCloseWindow)
圖4顯示了到現在應用程序的狀態。
圖4. 第一個MDI wxPython程序
很明顯,我們沒有展示全部的代碼,但是隨著我們一點一點地學習,我們將最終將其變得完整。
注意,使用wxMDIParentFrame作為MainFrame的基類。通過使用這個類,你會自動地獲得為實現MDI應用程序的所有需要的東西,不需要關心在外表後面發生了什麼。w xMDIParentFrame 類有著與wxFrame類同樣的接口,只是擁有一些額外的方法。通常將一個單文檔接口程序改為一個多文檔程序只是象改變應用程序派生類的基類一樣容易。對於w xMDIParentFrame 類,存在相對應的wxMDIChildFrame類,用於作文檔窗口,在後面就會看到。如果你需要處理MDI父窗口的客戶區域(或背景區域),你可以使用 w xMDIClientWindow類。你可以使用它來在所有子窗口的後面放置一個背景圖像。
在文件對話框成功完成之後,要做的第一件事就是詢問對話框被選中的路徑名是什麼,然後使用這個路徑來修改框架的標題,然後打開一個B ookSet文件。
看一下後面一行。它重新使BookSet菜單有效,因為現在已經存在一個打開文件了。它實際是兩行語句合成一句,相當於這兩行:
menu = self.GetMenuBar()
menu.EnableTop(1, true)
因為當用戶打開一個文件時,讓他們確實地看到一些東西是有意義的,你應該創建並且顯示其中一個視圖,用上面的OnMenuOpen處理函數中最後幾行代碼。在下面,我們會看到。
wxListCtrl
日志視圖是由wxListCtrl組成,其中每一個交易都有一個單行的小計。這個控件放置在wxMDIChildFrame中,並且因為它是框架中唯一的東西,所以不用擔心設置或維護大小,框架會自動維護它。(不幸地是,因為某些平台在不同的時間發送第一個改變大小(r esize)事件,有時候窗口顯示時,它的子窗口大小會不正確。)
class JournalView(wxMDIChildFrame):
def __init__(self, parent, bookset, editID):
wxMDIChildFrame.__init__(self, parent, -1, "")
self.bookset = bookset
self.parent = parent
tID = wxNewId()
self.lc = wxListCtrl(self, tID, wxDefaultPosition,
wxDefaultSize, wxLC_REPORT)
## Forces a resize event to get around a minor bug...
self.SetSize(self.GetSize())
self.lc.InsertColumn(0, "Date")
self.lc.InsertColumn(1, "Comment")
self.lc.InsertColumn(2, "Amount")
self.currentItem = 0
EVT_LIST_ITEM_SELECTED(self, tID, self.OnItemSelected)
EVT_LEFT_DCLICK(self.lc, self.OnDoubleClick)
menu = parent.MakeMenu(true)
self.SetMenuBar(menu)
EVT_MENU(self, editID, self.OnEdit)
EVT_CLOSE(self, self.OnCloseWindow)
self.UpdateView()
圖6 顯示出應用程序處理的很好,並且看上去象一個正規的Windows應用程序。
self.lc = wxListCtrl(self, tID, wxDefaultPosition,
wxDefaultSize, wxLC_REPORT)
## Forces a resize event to get around a minor bug...
self.SetSize(self.GetSize())
self.lc.InsertColumn(0, "Date")
self.lc.InsertColumn(1, "Comment")
self.lc.InsertColumn(2, "Amount")
self.currentItem = 0
EVT_LIST_ITEM_SELECTED(self, tID, self.OnItemSelected)
EVT_LEFT_DCLICK(self.lc, self.OnDoubleClick)
menu = parent.MakeMenu(true)
self.SetMenuBar(menu)
EVT_MENU(self, editID, self.OnEdit)
EVT_CLOSE(self, self.OnCloseWindow)
self.UpdateView()
圖6 顯示出應用程序處理的很好,並且看上去象一個正規的Windows應用程序。