Ross Wan's World!

Python, Ajax, PHP and Linux.

wxPython:完整实例

Posted by Ross Wan 于 2008/05/06

       在这个章节里,我们将展示一些完整的实例程序(以往的实例仅实现了程序外观,并没有现实程序的实质性功能),包括了编程的不同领域。你们将会发现,使用 Python 编程,wxPython 比其它的 toolkits 更为容易。

Tom邮件发送程序

       这是一个简单的邮件发送程序。

#!/usr/bin/python
# Tom

import wx
import smtplib

class Tom(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, size=(400, 420))

        panel = wx.Panel(self, -1)
        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        hbox3 = wx.BoxSizer(wx.HORIZONTAL)

        st1 = wx.StaticText(panel, -1, ‘From’)
        st2 = wx.StaticText(panel, -1, ‘To ‘)
        st3 = wx.StaticText(panel, -1, ‘Subject’)

        self.tc1 = wx.TextCtrl(panel, -1, size=(180, -1))
        self.tc2 = wx.TextCtrl(panel, -1, size=(180, -1))
        self.tc3 = wx.TextCtrl(panel, -1, size=(180, -1))

        self.write = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
        button_send = wx.Button(panel, 1, ‘Send’)

        hbox1.Add(st1, 0, wx.LEFT, 10)
        hbox1.Add(self.tc1, 0, wx.LEFT, 35)
        hbox2.Add(st2, 0, wx.LEFT, 10)
        hbox2.Add(self.tc2, 0, wx.LEFT, 50)
        hbox3.Add(st3, 0, wx.LEFT, 10)
        hbox3.Add(self.tc3, 0, wx.LEFT, 20)
        vbox.Add(hbox1, 0, wx.TOP, 10)
        vbox.Add(hbox2, 0, wx.TOP, 10)
        vbox.Add(hbox3, 0, wx.TOP, 10)
        vbox.Add(self.write, 1, wx.EXPAND | wx.TOP | wx.RIGHT | wx.LEFT, 15)
        vbox.Add(button_send, 0, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 20)

        self.Bind(wx.EVT_BUTTON, self.OnSend, id=1)
        panel.SetSizer(vbox)

        self.Centre()
        self.ShowModal()
        self.Destroy()

    def OnSend(self, event):
        sender = self.tc1.GetValue()
        recipient = self.tc2.GetValue()
        subject = self.tc3.GetValue()
        text = self.write.GetValue()
        header = ‘From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n’ % (sender, recipient, subject)
        message = header + text

        try:
            server = smtplib.SMTP(‘mail.chello.sk’)
            server.sendmail(sender, recipient, message)
            server.quit()
            dlg = wx.MessageDialog(self, ‘Email was successfully sent’, ‘Success’,
        wx.OK | wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()

        except smtplib.SMTPException, error:
            dlg = wx.MessageDialog(self, ‘Failed to send email’, ‘Error’, wx.OK | wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()

app = wx.App()
Tom(None, -1, ‘Tom’)
app.MainLoop()

import smtplib

       使用 smtp 模块来处理邮件,这是 Python 内建的一个模块。

header = ‘From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n’ % (sender, recipient, subject)

       邮件头部必须遵循 RFC 821 规范。

server = smtplib.SMTP(‘mail.chello.sk’)
server.sendmail(sender, recipient, message)
server.quit()

       这里,我们建立一个 SMTP 连接。你可从 ISP 里得到 pop 和 smtp 服务器的名字,我这里是“mail.chello.sk”。发送邮件通过调用方法 sendmail()。最后使用 quit() 方法断开与服务器的连接。

Editor文本编辑器

#!/usr/bin/python
# Editor

import wx
import os

class Editor(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(600, 500))

        # variables
        self.modify = False
        self.last_name_saved = ”
        self.replace = False

        # setting up menubar
        menubar = wx.MenuBar()

        file = wx.Menu()
        new = wx.MenuItem(file, 101, ‘&New\tCtrl+N’, ‘Creates a new document’)
        new.SetBitmap(wx.Bitmap(‘icons/stock_new-16.png’))
        file.AppendItem(new)

        open = wx.MenuItem(file, 102, ‘&Open\tCtrl+O’, ‘Open an existing file’)
        open.SetBitmap(wx.Bitmap(‘icons/stock_open-16.png’))
        file.AppendItem(open)
        file.AppendSeparator()

        save = wx.MenuItem(file, 103, ‘&Save\tCtrl+S’, ‘Save the file’)
        save.SetBitmap(wx.Bitmap(‘icons/stock_save-16.png’))
        file.AppendItem(save)

        saveas = wx.MenuItem(file, 104, ‘Save &As…\tShift+Ctrl+S’,
        ‘Save the file with a different name’)
        saveas.SetBitmap(wx.Bitmap(‘icons/stock_save_as-16.png’))
        file.AppendItem(saveas)
        file.AppendSeparator()

        quit = wx.MenuItem(file, 105, ‘&Quit\tCtrl+Q’, ‘Quit the Application’)
        quit.SetBitmap(wx.Bitmap(‘icons/stock_exit-16.png’))
        file.AppendItem(quit)

        edit = wx.Menu()
        cut = wx.MenuItem(edit, 106, ‘&Cut\tCtrl+X’, ‘Cut the Selection’)
        cut.SetBitmap(wx.Bitmap(‘icons/stock_cut-16.png’))
        edit.AppendItem(cut)

        copy = wx.MenuItem(edit, 107, ‘&Copy\tCtrl+C’, ‘Copy the Selection’)
        copy.SetBitmap(wx.Bitmap(‘icons/stock_copy-16.png’))
        edit.AppendItem(copy)

        paste = wx.MenuItem(edit, 108, ‘&Paste\tCtrl+V’, ‘Paste text from clipboard’)
        paste.SetBitmap(wx.Bitmap(‘icons/stock_paste-16.png’))
        edit.AppendItem(paste)

        delete = wx.MenuItem(edit, 109, ‘&Delete’, ‘Delete the selected text’)
        delete.SetBitmap(wx.Bitmap(‘icons/stock_delete-16.png’,))

        edit.AppendItem(delete)
        edit.AppendSeparator()
        edit.Append(110, ‘Select &All\tCtrl+A’, ‘Select the entire text’)

        view = wx.Menu()
        view.Append(111, ‘&Statusbar’, ‘Show StatusBar’)

        help = wx.Menu()
        about = wx.MenuItem(help, 112, ‘&About\tF1’, ‘About Editor’)
        about.SetBitmap(wx.Bitmap(‘icons/stock_about-16.png’))
        help.AppendItem(about)

        menubar.Append(file, ‘&File’)
        menubar.Append(edit, ‘&Edit’)
        menubar.Append(view, ‘&View’)
        menubar.Append(help, ‘&Help’)
        self.SetMenuBar(menubar)

        self.Bind(wx.EVT_MENU, self.NewApplication, id=101)
        self.Bind(wx.EVT_MENU, self.OnOpenFile, id=102)
        self.Bind(wx.EVT_MENU, self.OnSaveFile, id=103)
        self.Bind(wx.EVT_MENU, self.OnSaveAsFile, id=104)
        self.Bind(wx.EVT_MENU, self.QuitApplication, id=105)
        self.Bind(wx.EVT_MENU, self.OnCut, id=106)
        self.Bind(wx.EVT_MENU, self.OnCopy, id=107)
        self.Bind(wx.EVT_MENU, self.OnPaste, id=108)
        self.Bind(wx.EVT_MENU, self.OnDelete, id=109)
        self.Bind(wx.EVT_MENU, self.OnSelectAll, id=110)
        self.Bind(wx.EVT_MENU, self.ToggleStatusBar, id=111)
        self.Bind(wx.EVT_MENU, self.OnAbout, id=112)

        # setting up toolbar
        self.toolbar = self.CreateToolBar( wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT
        | wx.TB_TEXT )
        self.toolbar.AddSimpleTool(801, wx.Bitmap(‘icons/stock_new.png’), ‘New’, ”)
        self.toolbar.AddSimpleTool(802, wx.Bitmap(‘icons/stock_open.png’), ‘Open’, ”)
        self.toolbar.AddSimpleTool(803, wx.Bitmap(‘icons/stock_save.png’), ‘Save’, ”)
        self.toolbar.AddSeparator()

        self.toolbar.AddSimpleTool(804, wx.Bitmap(‘icons/stock_cut.png’), ‘Cut’, ”)
        self.toolbar.AddSimpleTool(805, wx.Bitmap(‘icons/stock_copy.png’), ‘Copy’, ”)
        self.toolbar.AddSimpleTool(806, wx.Bitmap(‘icons/stock_paste.png’), ‘Paste’, ”)
        self.toolbar.AddSeparator()

        self.toolbar.AddSimpleTool(807, wx.Bitmap(‘icons/stock_exit.png’), ‘Exit’, ”)
        self.toolbar.Realize()

        self.Bind(wx.EVT_TOOL, self.NewApplication, id=801)
        self.Bind(wx.EVT_TOOL, self.OnOpenFile, id=802)
        self.Bind(wx.EVT_TOOL, self.OnSaveFile, id=803)
        self.Bind(wx.EVT_TOOL, self.OnCut, id=804)
        self.Bind(wx.EVT_TOOL, self.OnCopy, id=805)
        self.Bind(wx.EVT_TOOL, self.OnPaste, id=806)
        self.Bind(wx.EVT_TOOL, self.QuitApplication, id=807)

        self.text = wx.TextCtrl(self, 1000, ”, size=(-1, -1), style=wx.TE_MULTILINE
        | wx.TE_PROCESS_ENTER)
        self.text.SetFocus()
        self.text.Bind(wx.EVT_TEXT, self.OnTextChanged, id=1000)
        self.text.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

        self.Bind(wx.EVT_CLOSE, self.QuitApplication)

        self.StatusBar()

        self.Centre()
        self.Show(True)

    def NewApplication(self, event):
        editor = Editor(None, -1, ‘Editor’)
        editor.Centre()
        editor.Show()

    def OnOpenFile(self, event):
        file_name = os.path.basename(self.last_name_saved)
        if self.modify:
            dlg = wx.MessageDialog(self, ‘Save changes?’, ”, wx.YES_NO | wx.YES_DEFAULT |
     wx.CANCEL | wx.ICON_QUESTION)
            val = dlg.ShowModal()
            if val == wx.ID_YES:
                self.OnSaveFile(event)
                self.DoOpenFile()
            elif val == wx.ID_CANCEL:
                dlg.Destroy()
            else:
                self.DoOpenFile()
        else:
            self.DoOpenFile()

    def DoOpenFile(self):
        wcd = ‘All files (*)|*|Editor files (*.ef)|*.ef|’
        dir = os.getcwd()
        open_dlg = wx.FileDialog(self, message=’Choose a file’, defaultDir=dir, defaultFile=”,
            wildcard=wcd, style=wx.OPEN|wx.CHANGE_DIR)
        if open_dlg.ShowModal() == wx.ID_OK:
            path = open_dlg.GetPath()

            try:
                file = open(path, ‘r’)
                text = file.read()
                file.close()
                if self.text.GetLastPosition():
                    self.text.Clear()
                self.text.WriteText(text)
                self.last_name_saved = path
                self.statusbar.SetStatusText(”, 1)
                self.modify = False

            except IOError, error:
                dlg = wx.MessageDialog(self, ‘Error opening file\n’ + str(error))
                dlg.ShowModal()

            except UnicodeDecodeError, error:
                dlg = wx.MessageDialog(self, ‘Error opening file\n’ + str(error))
                dlg.ShowModal()

        open_dlg.Destroy()

    def OnSaveFile(self, event):
        if self.last_name_saved:

            try:
                file = open(self.last_name_saved, ‘w’)
                text = self.text.GetValue()
                file.write(text)
                file.close()
                self.statusbar.SetStatusText(os.path.basename(self.last_name_saved) + ‘ saved’, 0)
                self.modify = False
                self.statusbar.SetStatusText(”, 1)

            except IOError, error:
                dlg = wx.MessageDialog(self, ‘Error saving file\n’ + str(error))
                dlg.ShowModal()
        else:
            self.OnSaveAsFile(event)

    def OnSaveAsFile(self, event):
        wcd=’All files(*)|*|Editor files (*.ef)|*.ef|’
        dir = os.getcwd()
        save_dlg = wx.FileDialog(self, message=’Save file as…’, defaultDir=dir, defaultFile=”,
            wildcard=wcd, style=wx.SAVE | wx.OVERWRITE_PROMPT)
        if save_dlg.ShowModal() == wx.ID_OK:
            path = save_dlg.GetPath()

            try:
                file = open(path, ‘w’)
                text = self.text.GetValue()
                file.write(text)
                file.close()
                self.last_name_saved = os.path.basename(path)
                self.statusbar.SetStatusText(self.last_name_saved + ‘ saved’, 0)
                self.modify = False
                self.statusbar.SetStatusText(”, 1)

            except IOError, error:
                dlg = wx.MessageDialog(self, ‘Error saving file\n’ + str(error))
                dlg.ShowModal()
        save_dlg.Destroy()

    def OnCut(self, event):
        self.text.Cut()

    def OnCopy(self, event):
        self.text.Copy()

    def OnPaste(self, event):
        self.text.Paste()

    def QuitApplication(self, event):
        if self.modify:
            dlg = wx.MessageDialog(self, ‘Save before Exit?’, ”, wx.YES_NO | wx.YES_DEFAULT |
            wx.CANCEL | wx.ICON_QUESTION)
            val = dlg.ShowModal()
            if val == wx.ID_YES:
                self.OnSaveFile(event)
                if not self.modify:
                    wx.Exit()
            elif val == wx.ID_CANCEL:
                dlg.Destroy()
            else:
                self.Destroy()
        else:
            self.Destroy()

    def OnDelete(self, event):
        frm, to = self.text.GetSelection()
        self.text.Remove(frm, to)

    def OnSelectAll(self, event):
        self.text.SelectAll()

    def OnTextChanged(self, event):
        self.modify = True
        self.statusbar.SetStatusText(‘ modified’, 1)
        event.Skip()

    def OnKeyDown(self, event):
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_INSERT:
            if not self.replace:
                self.statusbar.SetStatusText(‘INS’, 2)
                self.replace = True
            else:
                self.statusbar.SetStatusText(”, 2)
                self.replace = False
        event.Skip()

    def ToggleStatusBar(self, event):
        if self.statusbar.IsShown():
            self.statusbar.Hide()
        else:
            self.statusbar.Show()

    def StatusBar(self):
        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetFieldsCount(3)
        self.statusbar.SetStatusWidths([-5, -2, -1])

    def OnAbout(self, event):
        dlg = wx.MessageDialog(self, ‘\tEditor\t\n Another Tutorial\njan bodnar 2005-2006’,
                                ‘About Editor’, wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

app = wx.App()
Editor(None, -1, ‘Editor’)
app.MainLoop()

KikaFTP 程序

       这是一个简单的 FTP 服务器连接程序(并没有文件浏览、上传和下载等功能),当成功连接时,会在状态栏显示一个已连接的图标,否则会显示一个已断开的连接的图标。程序使用了 ftplib 模块,这是 Python 的标准库。注:如果你没有一个 ftp 帐号的话,可以登录到一个匿名 ftp 站点。

#!/usr/bin/python
# kika.py

from ftplib import FTP, all_errors
import wx

class MyStatusBar(wx.StatusBar):
    def __init__(self, parent):
        wx.StatusBar.__init__(self, parent)

        self.SetFieldsCount(2)
        self.SetStatusText(‘Welcome to Kika’, 0)
        self.SetStatusWidths([-5, -2])
        self.icon = wx.StaticBitmap(self, -1, wx.Bitmap(‘icons/disconnected.png’))
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.PlaceIcon()

    def PlaceIcon(self):
        rect = self.GetFieldRect(1)
        self.icon.SetPosition((rect.x+3, rect.y+3))

    def OnSize(self, event):
        self.PlaceIcon()

class Kika(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 270))

        wx.StaticText(self, -1, ‘Ftp site’, (10, 20))
        wx.StaticText(self, -1, ‘Login’, (10, 60))
        wx.StaticText(self, -1, ‘Password’, (10, 100))

        self.ftpsite = wx.TextCtrl(self, -1, ”,  (110, 15), (120, -1))
        self.login = wx.TextCtrl(self, -1, ”,  (110, 55), (120, -1))
        self.password = wx.TextCtrl(self, -1, ”,  (110, 95), (120, -1), style=wx.TE_PASSWORD)

        self.ftp = None

        con = wx.Button(self, 1, ‘Connect’, (10, 160))
        discon = wx.Button(self, 2, ‘DisConnect’, (120, 160))

        self.Bind(wx.EVT_BUTTON, self.OnConnect, id=1)
        self.Bind(wx.EVT_BUTTON, self.OnDisConnect, id=2)

        self.statusbar = MyStatusBar(self)
        self.SetStatusBar(self.statusbar)
        self.Centre()
        self.Show()

    def OnConnect(self, event):
        if not self.ftp:
            ftpsite = self.ftpsite.GetValue()
            login = self.login.GetValue()
            password = self.password.GetValue()

            try:
                self.ftp = FTP(ftpsite)
                var = self.ftp.login(login, password)
                self.statusbar.SetStatusText(‘User connected’)
                self.statusbar.icon.SetBitmap(wx.Bitmap(‘icons/connected.png’))

            except AttributeError:
                self.statusbar.SetForegroundColour(wx.RED)
                self.statusbar.SetStatusText(‘Incorrect params’)
                self.ftp = None

            except all_errors, err:
                self.statusbar.SetStatusText(str(err))
                self.ftp = None

    def OnDisConnect(self, event):
        if self.ftp:
            self.ftp.quit()
            self.ftp = None
            self.statusbar.SetStatusText(‘User disconnected’)
            self.statusbar.icon.SetBitmap(wx.Bitmap(‘icons/disconnected.png’))

app = wx.App()
Kika(None, -1, ‘Kika’)
app.MainLoop()

def PlaceIcon(self):
    rect = self.GetFieldRect(1)
    self.icon.SetPosition((rect.x+3, rect.y+3))

       每当窗口大小改变时,我们必须重新放置“连接/断开”图标到新的位置。

Puzzle(拼图游戏程序)

#!/usr/bin/python
# puzzle.py

import wx
import random

class Puzzle(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title)

        images = [‘images/one.jpg’, ‘images/two.jpg’, ‘images/three.jpg’, ‘images/four.jpg’,
        ‘images/five.jpg’, ‘images/six.jpg’, ‘images/seven.jpg’, ‘images/eight.jpg’]

        self.pos = [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ]

        self.sizer = wx.GridSizer(3, 3, 0, 0)

        numbers = [0, 1, 2, 3, 4, 5, 6, 7]
        random.shuffle(numbers)

        for i in numbers:
                button = wx.BitmapButton(self, i, wx.Bitmap(images[i]))
                button.Bind(wx.EVT_BUTTON, self.OnPressButton, id=button.GetId())
                self.sizer.Add(button)

        self.panel = wx.Button(self, -1, size=(112, 82))
        self.sizer.Add(self.panel)

        self.SetSizerAndFit(self.sizer)
        self.Centre()
        self.ShowModal()
        self.Destroy()

    def OnPressButton(self, event):

        button = event.GetEventObject()
        sizeX = self.panel.GetSize().x
        sizeY = self.panel.GetSize().y

        buttonX = button.GetPosition().x
        buttonY = button.GetPosition().y
        panelX = self.panel.GetPosition().x
        panelY = self.panel.GetPosition().y
        buttonPosX = buttonX / sizeX
        buttonPosY = buttonY / sizeY

        buttonIndex = self.pos[buttonPosY][buttonPosX]
        if (buttonX == panelX) and (panelY – buttonY) == sizeY:
            self.sizer.Remove(self.panel)
            self.sizer.Remove(button)
            self.sizer.Insert(buttonIndex, self.panel)
            self.sizer.Insert(buttonIndex+3, button)
            self.sizer.Layout()

        if (buttonX == panelX) and (panelY – buttonY) == -sizeY:
            self.sizer.Remove(self.panel)
            self.sizer.Remove(button)
            self.sizer.Insert(buttonIndex-3, button)
            self.sizer.Insert(buttonIndex, self.panel)
            self.sizer.Layout()

        if (buttonY == panelY) and (panelX – buttonX) == sizeX:
            self.sizer.Remove(self.panel)
            self.sizer.Remove(button)
            self.sizer.Insert(buttonIndex, self.panel)
            self.sizer.Insert(buttonIndex+1, button)
            self.sizer.Layout()

        if (buttonY == panelY) and (panelX – buttonX) == -sizeX:
            self.sizer.Remove(self.panel)
            self.sizer.Remove(button)
            self.sizer.Insert(buttonIndex-1, button)
            self.sizer.Insert(buttonIndex, self.panel)
            self.sizer.Layout()

app = wx.App()
Puzzle(None, -1, ‘Puzzle’)
app.MainLoop()

 images = [‘images/one.jpg’, ‘images/two.jpg’, ‘images/three.jpg’, ‘images/four.jpg’,  ‘images/five.jpg’, ‘images/six.jpg’, ‘images/seven.jpg’, ‘images/eight.jpg’]

       利用 Gimp 等图像处理软件,将图片切割成9份,每份大小为 100×70,每幅小图片被处置在一个按钮控件上。

numbers = [0, 1, 2, 3, 4, 5, 6, 7]
random.shuffle(numbers)

       利用 shuffle() 弄乱图片的次序。

 self.panel = wx.Button(self, -1, size=(112, 82))
 self.sizer.Add(self.panel)

       这是一个没有图片的按钮,用于跟其它按钮互调位置。

Advertisements

一条回应 to “wxPython:完整实例”

  1. Ross Wan said

    翻译自:The wxPython tutorial

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

 
%d 博主赞过: