22 Mar 2009

Python GUI学习之 - wxPython界面编程: QR Code

2009/11/18:
判断平台可以直接sys.platform

4月20日更新:
判断平台可以直接利用函数os.environ.get('OS')或者os.environ['OS']会返回操作系统名称.


4月1日更新:
使用os.sep,可以表示文件路径分隔符,Python会自动根据平台选择/(linux,unix)或者\\(windows)




这是为了学习wxPython而编写的一个QR Code Generator程序,
可以把输入的信息保存成图片(png,jpg,gif)格式。

QR Code目前已经有很多应用,下次买pepsi的时候看看上面有个黑色的方块就是了,没有注意coca是不是也有。
做成的大概样子就是左边的样子了:

代码如下:(很不幸,PyQrcodec模块在windows下工作不了,看了作者主页的解决方法,只在ubuntu下解决了)


-------------------------------------------
#!/usr/bin/env python
#
# QrGenerate.py
#
# Copyright 2009 daniel
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

import os
import wx
import PyQrcodec

ID_New = 101
ID_Encode = 102
ID_Decode = 103
ID_Exit = 104
ID_About = 201
ID_Help = 202

class QrGenerate(wx.App):

    def OnInit(self):
        frame = BasicFrame(None, -1, "QrGenerator - Generate QR Code for you")
        
        #~ frame.Show(True)
        frame.CentreOnScreen()
        frame.Show(True)
        
        #~ one way to bind menu items and event
        frame.Connect(ID_New, -1,
                      wx.wxEVT_COMMAND_MENU_SELECTED, frame.OnNew)
        frame.Connect(ID_Encode, -1,
                      wx.wxEVT_COMMAND_MENU_SELECTED, frame.OnEncode)
        frame.Connect(ID_Decode, -1,
                      wx.wxEVT_COMMAND_MENU_SELECTED, frame.OnDecode)
        frame.Connect(ID_Exit, -1,
                      wx.wxEVT_COMMAND_MENU_SELECTED, frame.OnExit)
        frame.Connect(ID_Help, -1,
                      wx.wxEVT_COMMAND_MENU_SELECTED, frame.OnHelp)
        frame.Connect(ID_About, -1,
                      wx.wxEVT_COMMAND_MENU_SELECTED, frame.OnAbout)
        
        self.SetTopWindow(frame)
        return True;
##---------------------------------------

class BasicFrame(wx.Frame):

    def __init__(self, parent, ID, title):
        wx.Frame.__init__(self, parent, ID, title,
        wx.DefaultPosition, wx.Size(450,300))
        self.CreateStatusBar()
        self.SetStatusText("QrGenerator - Generate QR Code for you")

        #~ menus start here
        menu1 = wx.Menu()
        menu1.Append(ID_New,
                     "&New", "Create new QR Code picture")
        menu1.Append(ID_Encode,
                     "E&ncode", "Generate the QR picture with current string")
        menu1.Append(ID_Decode,
                     "&Decode", "Decode the information from a picture file")
        menu1.AppendSeparator()
        menu1.Append(ID_Exit,
                     "&Exit", "Terminate program")

        #~ add it to the menubar
        menuBar = wx.MenuBar()
        menuBar.Append(menu1, "&File")

        #~ add another menu
        menu2 = wx.Menu()
        menu2.Append(ID_Help,
                     "&Help", "See more about the usage...")
        menu2.AppendSeparator()
        menu2.Append(ID_About,
                     "&About", "More information about this program")
        menuBar.Append(menu2, "&Help")

        #~ set menubar
        self.SetMenuBar(menuBar)
        #~ another way to bind menu items and event
        #~ wx.EVT_MENU(self, ID_ABOUT, self.OnAbout)
        #~ ...

        #~ set textbox
        self.TxtInfo = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE)
        #~ set buttons
        self.buttons = []
        self.buttons.append(wx.Button(self, id=1, label="&Clear"))
        self.Bind(wx.EVT_BUTTON, self.OnClear,self.buttons[len(self.buttons)-1])
        self.buttons[len(self.buttons)-1].SetToolTip(wx.ToolTip('Clear the input aera'))
        
        self.buttons.append(wx.Button(self, id=2, label="&Encode"))
        self.Bind(wx.EVT_BUTTON, self.OnEncode,self.buttons[len(self.buttons)-1])
        self.buttons[len(self.buttons)-1].SetToolTip(wx.ToolTip('Generate the QR picture with current string'))
        
        self.buttons.append(wx.Button(self, id=3, label="&Decode"))
        self.Bind(wx.EVT_BUTTON, self.OnDecode,self.buttons[len(self.buttons)-1])
        self.buttons[len(self.buttons)-1].SetToolTip(wx.ToolTip('Decode the information from a picture file'))
        
        self.buttons.append(wx.Button(self, id=4, label="&Exit"))
        self.Bind(wx.EVT_BUTTON, self.OnExit,self.buttons[len(self.buttons)-1])
        self.buttons[len(self.buttons)-1].SetToolTip(wx.ToolTip('Terminate program'))
        
        #~ set sizer
        self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
        for i in self.buttons:
            self.sizer2.Add(i,1,wx.EXPAND)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.TxtInfo,1,wx.EXPAND)
        self.sizer.Add(self.sizer2,0,wx.EXPAND)
        #~ Layout sizers
        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        #~ self.sizer.Fit(self)

    def OnNew(self, event):
        if len(self.TxtInfo.GetValue())!=0:
            dlg = wx.MessageDialog(self, """The input aera is not empty,\nare you sure?""",
                                   'QrGenerator',wx.YES_NO | wx.ICON_QUESTION)
            if dlg.ShowModal()==wx.ID_YES: #choose OK
                self.TxtInfo.Clear()
        else:
            self.TxtInfo.Clear()

    def OnClear(self, event):
        self.TxtInfo.Clear()

    def OnEncode(self, event):
        if len(self.TxtInfo.GetValue())!=0:
            dlg = wx.FileDialog(self,'Please specify the file name:',
                                '','','*.jpg;*.gif;*.png', wx.SAVE)
            if dlg.ShowModal() == wx.ID_OK:
                #~ default format png, you can choose from png or jpg or gif
                self.filename = ('.' in dlg.GetFilename()) \
                                and dlg.GetFilename() or dlg.GetFilename()+'.png'
                self.dirname = (dlg.GetDirectory()[len(dlg.GetDirectory())-1]=='/') \
                               and dlg.GetDirectory() or dlg.GetDirectory()+'/'
                size, image = PyQrcodec.encode(self.TxtInfo.GetValue())
                image.save(self.dirname+'/'+self.filename)
                #~ print '%s, %s' % (self.TxtInfo.GetValue(), self.dirname+'/'+self.filename)
                self.SetStatusText("Image has been saved")

    def OnDecode(self, event):
        dlg = wx.FileDialog(self, 'Please specify the file name:',
                            '','','*.jpg;*.gif;*png', wx.OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            if len(dlg.GetFilename())!=0:
                self.filename = dlg.GetFilename()
                self.dirname = (dlg.GetDirectory()[len(dlg.GetDirectory())-1]=='/') \
                               and dlg.GetDirectory() or dlg.GetDirectory()+'/'
                print self.dirname+self.filename
                #~ choose file
                status, string = PyQrcodec.decode(self.dirname+self.filename)
                if status:
                    self.TxtInfo.SetValue(string)
##                    dlg = wx.MessageDialog(self, string,
##                                           "QR Code Information", wx.OK | wx.ICON_INFORMATION)
##                    dlg.ShowModal()
##                    dlg.Destroy()
                    self.SetStatusText("Information has been decoded")
                else:
                    dlg = wx.MessageDialog(self, "There's an ERROR happened!",
                                           "QR Code Information", wx.OK | wx.ICON_ERROR)
                    dlg.ShowModal()
                    dlg.Destroy()

    def OnExit(self, event):
        self.Close(True)

    def OnHelp(self, event):
        dlg = wx.MessageDialog(self, "If you want to know more about QR Code, \
Please visit: \nhttp://en.wikipedia.org/wiki/QR_Code","QrGenerator - Help", wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def OnAbout(self, event):
        dlg = wx.MessageDialog(self, "This is a simple programme for generating QR code as a picture.\nFor more information \
about QR code, please visit wetsite: \n\nhttp://en.wikipedia.org/wiki/QR_Code",
        "About QrGenerator", wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()


#~ main loop
app = QrGenerate(0)
app.MainLoop()

No comments :

Post a Comment