1. 程式人生 > >Python_GUI學習筆記(3)wxPython的簡單介面設計

Python_GUI學習筆記(3)wxPython的簡單介面設計

第一次接觸到wxpython,在網上找到一個簡單的介面顯示程式碼,複製到spyder3編輯中進行執行出現錯誤,(“module 'wx' has no attributte 'App'”),但在python3.6的IDLE編輯器上執行沒有錯誤。具體程式如下:

import wx
app = wx.App()
frame = wx.Frame(None,title="my GUI")
frame.Show(1)
app.MainLoop()

於是在網上找到一些解決方法:

1)wx.py 檔名與外掛wx 重名了;【命名py指令碼時,不要與python預留字,模組名等相同;刪除該庫的.pyc檔案(因為py指令碼每次執行時均會生成.pyc檔案;在已經生成.pyc檔案的情況下,若程式碼不更新,執行時依舊會走pyc,所以要刪除.pyc檔案),重新執行程式碼;或者找一個可以執行程式碼的環境,拷貝替換當前機器的.pyc檔案即可

解決:

把wx.py 改成 editor.py 執行成功彈出一個文字框,如附件截圖:

D:\ProgramFiles64\Anaconda36\Lib\site-packages\IPython\terminal\pt_inputhooks\wx.py檔案修改為editor.py,再執行。

2)有的說是版本問題;

我按方法1修改了之後,還是沒有成功,後來我將spyder重啟,並且所有設定恢復預設之後,再執行又沒有錯誤,具體原因在哪裡我還是沒有搞清楚。

下面我們來實現簡單介面設計:

最小的wxpython程式,叫它hello world程式吧。功能就是產生一個視窗,就像是我們VC中新建的一個單文件的MFC類似,不過沒有選單什麼的,只有一個框架視窗。其實嚴格來說,wxpython不叫這個為視窗,而是“frame”。實現

程式碼有如下幾種:

一>import wx
app = wx.PySimpleApp()
frame = wx.Frame(None, -1, "Hello World")
frame.Show()
app.MainLoop()

二>import wx
app = wx.App()
frame = wx.Frame(None, -1, "Hello World")
frame.Show()
app.MainLoop()

三>import wx
class MyApp(wx.App):
       def OnInit(self):
              frame=wx.Frame(parent=None,title='Hello wxpython')
              frame.Show()
              return True
app=MyApp()
app.MainLoop()

wxpython筆記(2)——從最簡單的開始

【下面部分轉載博主:http://blog.sina.com.cn/s/blog_4b5039210100eykc.html】

可以看到,frame上面什麼都沒有。但所謂麻雀雖小,五臟俱全,從這個最小的程式我們就能看出一個wxpython程式都包含哪些東西:

1 匯入wxpython庫,或者裡面的方法( import wx)

2 建立一個應用類的子類(繼承於wxpython中的App類,class MyApp(wx.App):)

3 定義應用子類初始化方法(OnInit())

4 建立應用類的例項

5 進入應用類的訊息迴圈 MainLoop

    我們主要看一下,應用類的OnInit函式,在這個初始化方法中,我們生成了一個wx.frame物件的一個例項,因為這個程式比較簡單,所以這個過程放到了OnInit方法中,一般情況下,我們都是定義一個繼承於wx..Frame的子類(類似於MyApp一樣),這個我們在以後會經常看到。

    還有一點,我們在App類初始化沒有呼叫__init__()這個方法,這意味著我們這個子類建立的過程中,按照類的繼承性,這個方法會被自動呼叫。當然我們可以重新定義這個方法,但是一定要在子類中呼叫一下基類的__init__()方法。例如:

class App(wx.App):

       def __init__(self):

              wx.App.__init__(self)

              #Do something here.....

    最後建立應用類例項和進入訊息迴圈和Tkinter差不多,就不說了。

    上面例子只是為了說明wxpython的基本用法,但是那個程式碼其實擴充套件性很差,那麼,作為一般wxpython程式應該怎麼寫呢?我們看下面的程式碼

#!/usr/bin/env Python

“”” hello.py is a starting point for a wxpython program”””

import wx

class Frame(wx.Frame):

       pass

class App(wx.App):

       def OnInit(self):

              self.frame=Frame(parent=None,title='Hello wxpython')

              self.frame.Show()

              self.SetTopWindow(self.frame)

              return True

if __name__=='__main__':

       app=App()

       app.MainLoop()

     第一行是註釋行,在windows中不是必須的,但是在linux中需要有,它告訴作業系統python直譯器在什麼地方,有了這個以後,我們就可以在linux命令列裡直接輸入檔名運行了。雖然windows中這個不是必須的,但是為了相容性跨平臺,這個一般還是要有的。

     第二行的三引號所夾內容就不說了。

    下面第一個類是繼承於wx..Frame的frame類。這裡我們什麼沒做,其實在這裡我們可以做很多事,比如建立一些元件(按鈕,文字框等待),這樣把frame單獨拿出來,為了使程式更清晰可讀。

第二個類是繼承於wx..App的App類。和第一個程式類似,只不過這裡的frame換成了呼叫Frame,例項化得物件。

     self.SetTopWindow(self.frame),這個其實是把self.frame作為了主frame,因為一個程式中可能會有多個frame。通過這個可以設定哪個frame是最頂層的主frame。

     最後的if語句就是這個程式的入口。

    下面,我們把上面的例子稍微擴充一點。

#!/usr/bin/env python     

""" Hello,wxPython program."""

import wx  #import the wxPackage

class Frame(wx.Frame):

       """Frame class that display an image."""

       def __init__(self,image,parent=None,id=-1,

                             pos=wx.DefaultPosition,

                             title='Hello wxPython'):

              temp=image.ConvertToBitmap()       #Displaying the image

              size=temp.GetWidth(),temp.GetHeight()

              wx.Frame.__init__(self,parent,id,title,pos,size)

              self.bmp=wx.StaticBitmap(parent=self,bitmap=temp)

class App(wx.App):

       """Application class."""

       def OnInit(self):

              image=wx.Image('wxpython.jpg',wx.BITMAP_TYPE_JPEG)

              self.frame=Frame(image)

              self.frame.Show()

              self.SetTopWindow(self.frame)

              return True

def main():

       app=App()

       app.MainLoop()

if __name__=='__main__':

       main()

     實現是在frame上顯示一張照片。結果為:

wxpython筆記(2)——從最簡單的開始