Python-wxPython


wxPython

  • Python中的图形用户界面开发库
    • Tkinter是Python官方提供的图形用户界面开发库, 用于封装Tk GUI工具包.
    • PyQt是非Python官方提供的图形用户界面开发库, 用于封装Qt工具包.
    • wxPython是非Python官方提供的图形用户界面开发库.

程序结构

若要构建一个wxPython程序, 至少需要一个应用对象和一个窗口对象.

import wx

# 创建应用程序对象
app = wx.App()
# 创建窗口对象, 第一个参数表示所在父窗口
frm = wx.Frame(parent=None, title="第一个程序", size=(400, 300), pos=(100, 100))
# 显示窗口
frm.Show()
# 应用程序进入主事件循环中
app.MainLoop()

自定义窗口类

import wx


# 自定义窗口类
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="第一个程序", size=(400, 300), pos=(100, 100))
        # 你的代码...(控件)
        # 创建面板对象
        panel = wx.Panel(parent=self)
        # 创建静态文本对象
        statictext = wx.StaticText(parent=panel, label="Hello World! ", pos=(10, 10))


app = wx.App()
frm = MyFrame()
frm.Show()
app.MainLoop()

事件处理

  • 事件: wxPython中的事件被封装为事件类wx.Event及其子类.

    ​ 例如按钮事件类wx.CommandEvent, 鼠标事件类wx.MoveEvent.

  • 事件源: 事件发生的场所, 就是各个控件.

  • 事件处理程序: 一个响应用户事件的方法.

    import wx
    
    
    # 自定义窗口类
    class MyFrame(wx.Frame):
        def __init__(self):
            super().__init__(parent=None, title="事件处理", size=(300, 180))
            panel = wx.Panel(parent=self)
            # 创建静态文本对象
            self.statictext = wx.StaticText(parent=panel, label="请单击OK按钮", pos=(110, 20))
            # 创建按钮对象
            b = wx.Button(parent=panel, label="OK", pos=(100, 50))
            # 绑定事件, wx.EVT_BUTTON是事件类型, 即按钮单击事件; self.on_click是事件处理程序; b是事件源, 即按钮对象
            self.Bind(wx.EVT_BUTTON, self.on_click, b)
            
        # 定义事件处理程序
        def on_click(self, event):  # event:事件对象
            self.statictext.SetLabelText("Hello, World! ")
    
    
    app = wx.App()
    frm = MyFrame()
    frm.Show()
    app.MainLoop()
    

布局管理

  • wx.BoxSizer: 盒子布局管理器是最常用的布局管理器, 它可以让其中的子窗口(或控件)沿垂直或水平方向布局.

    1. 创建盒子布局管理器对象, 默认水平方向布局: wx.BoxSizer(wx.HORIZONTAL/wx.VERTICAL)

    2. 添加子窗口(或控件)到父窗口的方法: Add(window, proportion=0, flag=0, border=0)

      添加到另外一个布局对象, 用于布局嵌套: Add(sizer, proportion=0, flag=0, border=0)

      flag对齐标志 说明
      wx.ALIGN_TOP 顶对齐
      wx.ALIGN_BUTTOM 底对齐
      wx.ALIGN_LEFT 左对齐
      wx.ALIGN_RIGHT 右对齐
      wx.ALIGN_CENTER (CENTRE) 居中对齐
      wx.ALIGN_CENTER_VERTICAL 垂直居中对齐
      wx.ALIGN_CENTER_HORIZONTAL 水平居中对齐
      flag边框标志 说明
      wx.TOP 设置有顶部边框, 边框的宽度通过Add()方法的border参数设置
      wx.BOTTOM 设置有底部边框
      wx.LEFT 设置有左边框
      wx.RIGHT 设置有右边框
      wx.ALL 设置4面有边框
      flag调整尺寸标志 说明
      wx.EXPAND 调整子窗口(或控件)完全填满有效空间
      wx.SHAPED 调整子窗口(或控件)填充有效空间, 但保存高宽比
      wx.FIXED_MINSIZE 调整子窗口(或控件)为最小尺寸
      wx.RESERVE_SPACE_EVEN_IF_HIDDEN 设置此标志后, 子窗口(或控件)如果被隐藏, 则所占空间保留
      import wx
      
      
      class MyFrame(wx.Frame):
          def __init__(self):
              super().__init__(parent=None, title="事件处理", size=(300, 180))
              panel = wx.Panel(parent=self)
              self.statictext = wx.StaticText(parent=panel, label="请单击OK按钮", pos=(110, 20))
              b = wx.Button(parent=panel, label="OK", pos=(100, 50))
              self.Bind(wx.EVT_BUTTON, self.on_click, b)
              # 创建垂直方向的盒子布局管理器对象
              vbox = wx.BoxSizer(wx.VERTICAL)
              # 添加静态文本到vbox布局管理器
              vbox.Add(self.statictext, proportion=1,
                       flag=wx.ALIGN_CENTER | wx.TOP, border=30)
              # 添加按钮b到vbox布局管理器
              vbox.Add(b, proportion=1,
                       flag=wx.ALIGN_CENTER | wx.SHAPED | wx.BOTTOM, border=30)
              # 设置面板采用vbox布局管理器
              panel.SetSizer(vbox)
      
          def on_click(self, event):
              self.statictext.SetLabelText("Hello, World! ")
      
      
      app = wx.App()
      frm = MyFrame()
      frm.Show()
      app.MainLoop()
      
  • 盒子布局管理器嵌套示例

    import wx
    
    
    class MyFrame(wx.Frame):
        def __init__(self):
            super(MyFrame, self).__init__(parent=None, title="来自主神的消息", size=(300, 120), pos=(500, 200))
            panel = wx.Panel(parent=self)
            self.statictext = wx.StaticText(parent=panel, label="想明白生命的意义吗? ")
            b1 = wx.Button(parent=panel, id=10, label="确认")
            b2 = wx.Button(parent=panel, id=11, label="Yes")
            # 将id为10~20的控件绑定到按钮单击事件
            self.Bind(wx.EVT_BUTTON, self.on_click, id=10, id2=20)
            # 创建包含两个按钮的盒子布局管理器对象
            box1 = wx.BoxSizer(wx.HORIZONTAL)
            box1.Add(b1, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
            box1.Add(b2, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
            # 创建包含静态文本和box1的盒子布局管理器对象
            box2 = wx.BoxSizer(wx.VERTICAL)
            box2.Add(self.statictext, proportion=1, flag=wx.ALIGN_CENTER | wx.TOP, border=10)
            box2.Add(box1, proportion=1, flag=wx.ALIGN_CENTER | wx.SHAPED)
            panel.SetSizer(box2)
    
        def on_click(self, event):
            event_id = event.GetId()
            if event_id == 10:
                self.statictext.SetLabelText("你是这次来的人里素质最好的一个. ")
            else:
                self.statictext.SetLabelText("Hello World! ")
    
    
    app = wx.App()
    frm = MyFrame()
    frm.Show()
    app.MainLoop()
    

控件

  • 文本输入控件

    • 普通文本
    • 密码
    • 多行文本
    import wx
    
    
    class MyFrame(wx.Frame):
        def __init__(self):
            super(MyFrame, self).__init__(parent=None, title="文本输入", size=(300, 260), pos=(500, 200))
            panel = wx.Panel(parent=self)
    
            tc1 = wx.TextCtrl(panel, style=0, value="Khru")
            # tc1.SetValue("Khru")
            print(tc1.GetValue())
            tc2 = wx.TextCtrl(panel, style=wx.TE_PASSWORD)
            tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
    
            userid = wx.StaticText(panel, label="用户ID: ")
            pwd = wx.StaticText(panel, label="密码: ")
            content = wx.StaticText(panel, label="多行文本: ")
    
            vbox = wx.BoxSizer(orient=wx.VERTICAL)
            vbox.Add(userid, flag=wx.EXPAND | wx.LEFT | wx.TOP, border=10)
            vbox.Add(tc1, flag=wx.FIXED_MINSIZE | wx.ALL, border=10)
            vbox.Add(pwd, flag=wx.EXPAND | wx.LEFT, border=10)
            vbox.Add(tc2, flag=wx.FIXED_MINSIZE | wx.ALL, border=10)
            vbox.Add(content, flag=wx.EXPAND | wx.LEFT, border=10)
            vbox.Add(tc3, flag=wx.EXPAND | wx.ALL, border=10)
            panel.SetSizer(vbox)
    
    
    app = wx.App()
    frm = MyFrame()
    frm.Show()
    app.MainLoop()
    
  • 单选按钮和复选框控件

    import wx
    
    
    class MyFrame(wx.Frame):
        def __init__(self):
            super().__init__(parent=None, title="单选按钮和复选框", size=(330, 120), pos=(500, 200))
            panel = wx.Panel(parent=self)
            
            st1 = wx.StaticText(panel, label="您的性别: ")
            rb1 = wx.RadioButton(panel, id=1, label="男", style=wx.RB_GROUP)
            rb2 = wx.RadioButton(panel, id=2, label="女")
            # 在下一个wx.RB_GROUP之前的单选按钮都是一组的
            self.Bind(wx.EVT_RADIOBUTTON, self.on_rb_click, id=1, id2=2)
            
            hbox1 = wx.BoxSizer()
            hbox1.Add(st1, flag=wx.LEFT | wx.RIGHT, border=5)
            hbox1.Add(rb1)
            hbox1.Add(rb2)
            
            st2 = wx.StaticText(panel, label="您喜欢的编程语言: ")
            cb1 = wx.CheckBox(panel, id=3, label="Python")
            cb2 = wx.CheckBox(panel, id=4, label="Java")
            cb3 = wx.CheckBox(panel, id=5, label="C++")
            cb1.SetValue(True)  # 默认状态为未选中, True表示选中
            self.Bind(wx.EVT_CHECKBOX, self.on_cb_click, id=3, id2=5)
            
            hbox2 = wx.BoxSizer()
            hbox2.Add(st2, flag=wx.LEFT | wx.RIGHT, border=5)
            hbox2.Add(cb1)
            hbox2.Add(cb2)
            hbox2.Add(cb3)
            
            vbox = wx.BoxSizer(orient=wx.VERTICAL)
            vbox.Add(hbox1, flag=wx.ALL, border=10)
            vbox.Add(hbox2, flag=wx.ALL, border=10)
            
            panel.SetSizer(vbox)
            
        # 事件处理程序将在每次事件源被选中或取消时调用
        def on_rb_click(self, event):
            rb = event.GetEventObject()  # 从事件对象中取出事件源对象
            print("性别为{}".format(rb.GetLabel()))
        
        def on_cb_click(self, event):
            cb = event.GetEventObject()
            print("{0} is checked? {1}".format(cb.GetLabel(), event.IsChecked()))
            # print("{0} is checked? {1}".format(cb.GetLabel(), cb.Get3StateValue()))
            # Gets the state of a 3-state checkbox.
            
            
    app = wx.App()
    frm = MyFrame()
    frm.Show()
    app.MainLoop()
    
  • 列表

    import wx
    
    
    class MyFrame(wx.Frame):
        def __init__(self):
            super().__init__(parent=None, title="列表", size=(350, 175), pos=(500, 200))
            panel = wx.Panel(parent=self)
    
            st1 = wx.StaticText(panel, label="选择你最喜欢的编程语言: ")
            lb1 = wx.ListBox(panel, choices=["Python", "Java", "C++"], style=wx.LB_SINGLE)
            self.Bind(event=wx.EVT_LISTBOX, handler=self.on_lb1, source=lb1)
    
            hbox1 = wx.BoxSizer()
            hbox1.Add(st1, proportion=1, flag=wx.LEFT | wx.RIGHT, border=5)
            hbox1.Add(lb1, proportion=1, flag=wx.SHAPED)
    
            st2 = wx.StaticText(panel, label="选择你喜欢的水果: ")
            lb2 = wx.ListBox(panel, choices=["苹果", "橘子", "香蕉"], style=wx.LB_EXTENDED)
            self.Bind(event=wx.EVT_LISTBOX, handler=self.on_lb2, source=lb2)
    
            hbox2 = wx.BoxSizer()
            hbox2.Add(st2, proportion=1, flag=wx.LEFT | wx.RIGHT, border=5)
            hbox2.Add(lb2, proportion=1, flag=wx.SHAPED)
    
            vbox = wx.BoxSizer(wx.VERTICAL)
            vbox.Add(hbox1, flag=wx.EXPAND | wx.ALL, border=5)
            vbox.Add(hbox2, flag=wx.EXPAND | wx.ALL, border=5)
    
            panel.SetSizer(vbox)
    
        def on_lb1(self, event):
            listbox = event.GetEventObject()
            print("最喜欢的编程语言是: {}".format(listbox.GetSelection()))
    
        def on_lb2(self, event):
            listbox = event.GetEventObject()
            print("喜欢的水果是: {}".format(listbox.GetSelections()))
    
    
    app = wx.App()
    frm = MyFrame()
    frm.Show()
    app.MainLoop()
    
  • 静态图片控件

    import wx
    
    
    class MyFrame(wx.Frame):
        def __init__(self):
            super().__init__(parent=None, title="静态图片控件", size=(500, 500), pos=(500, 200))
            self.panel = wx.Panel(parent=self)  # 这里面板是MyFrame类的实例变量
    
            # 创建wx.Bitmap对象的列表
            self.bmps = [wx.Bitmap(name="images/python.jpg", type=wx.BITMAP_TYPE_JPEG),
                         wx.Bitmap(name="images/sin.gif", type=wx.BITMAP_TYPE_GIF),
                         wx.Bitmap(name="images/ml.png", type=wx.BITMAP_TYPE_PNG)]
            # 创建静态图片控件对象, 显示的图片是self.bmps[0]
            self.sb = wx.StaticBitmap(self.panel, bitmap=self.bmps[0])
    
            b1 = wx.Button(self.panel, id=1, label="Button1")
            b2 = wx.Button(self.panel, id=2, label="Button2")
            b3 = wx.Button(self.panel, id=3, label="Button3")
            self.Bind(event=wx.EVT_BUTTON, handler=self.on_click, id=1, id2=3)
    
            vbox = wx.BoxSizer(wx.VERTICAL)
            vbox.Add(b1, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
            vbox.Add(b2, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
            vbox.Add(b3, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
            vbox.Add(self.sb, proportion=3, flag=wx.EXPAND | wx.ALL, border=10)
    
            self.panel.SetSizer(vbox)
    
        def on_click(self, event):
            event_id = event.GetId()
            if event_id == 1:
                self.sb.SetBitmap(self.bmps[0])
            elif event_id == 2:
                self.sb.SetBitmap(self.bmps[1])
            else:
                self.sb.SetBitmap(self.bmps[2])
            self.panel.Layout()  # 重新设置panel面板布局
    
    
    app = wx.App()
    frm = MyFrame()
    frm.Show()
    app.MainLoop()
    

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/python/288056.html

(0)
上一篇 2022年9月7日 01:38
下一篇 2022年9月7日 02:56

相关推荐

发表回复

登录后才能评论