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()

Python_GUI学习笔记(3)wxPython的简单界面设计

【下面部分转载博主: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上显示一张照片。结果为:

Python_GUI学习笔记(3)wxPython的简单界面设计