wxPython基础

wxPython简介

wxPython是Python语言的一套优秀的GUI图形库,允许Python程序员创建完整的,功能健全的GUI用户界面。wxPython是作为优秀的跨平台GUI库wxWidgets的Python封装和Python模块的方式提供给用户的。

wxPython基本操作

作为图形用户界面开发工具包,wxPython主要提供了如下内容

  1. 窗口
  2. 控件
  3. 事件处理
  4. 布局管理

创建窗口

import wx

# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="第一个GUI程序!", size=(400, 300))
        self.Center()  # 设置窗口居中
        panel = wx.Panel(parent=self)

class App(wx.App):

    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True


if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

image-20200925190050395

事件处理

import wx

# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='事件处理', size=(300, 180))
        self.Center()  # 设置窗口居中
        panel = wx.Panel(parent=self)
        self.statictext = wx.StaticText(parent=panel, pos=(110, 15))
        #parent=panel表示把当前按钮放在面板中, id为当前按钮编号, label为按钮名, pos为按钮位置
        b1 = wx.Button(parent=panel, id=10, label='Button1', pos=(100, 45))
        b2 = wx.Button(parent=panel, id=11, label='Button2', pos=(100, 85))
        #将事件与事件处理函数绑定
        #EVT_BUTTON表示当前控件的时间类型, on_click表示触发该事件所调用的函数
        #id = 10, id2 = 20表示绑定id为10-20的控件
        self.Bind(wx.EVT_BUTTON, self.on_click, id=10, id2=20)


    def on_click(self, event):
		#获取当前事件的id号,根据id写对应的处理函数
        event_id = event.GetId()
        print(event_id)
        if event_id == 10:
            self.statictext.SetLabelText('Button1单击')
        else:
            self.statictext.SetLabelText('Button2单击')

class App(wx.App):
    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True

if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

image-20200925192103439

鼠标事件处理
import wx

# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="鼠标事件处理", size=(400, 300))
        self.Centre()  # 设置窗口居中
        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
        self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
        self.Bind(wx.EVT_MOTION, self.on_mouse_move)

    def on_left_down(self, evt):
        print('鼠标按下')

    def on_left_up(self, evt):
        print('鼠标释放')

    def on_mouse_move(self, event):
        #如果按住鼠标移动,返回当前位置
        if event.Dragging() and event.LeftIsDown():
            pos = event.GetPosition()
            print(pos)

class App(wx.App):

    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True

if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

布局管理器

Box布局器
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='StaticBox布局', size=(400, 300))
        self.Center()  # 设置窗口居中
        panel = wx.Panel(parent=self)
        # 创建垂直方向的Box布局管理器对象
        vbox = wx.BoxSizer(wx.VERTICAL)
        self.statictext = wx.StaticText(parent=panel, label='Button1单击')
        # 添加静态文本到Box布局管理器
        #proportion表示当前空间所占的比例, flag用来设置当前控件的位置,边框,尺寸参数, border表示边界的宽度
        vbox.Add(self.statictext, proportion=2, flag=wx.FIXED_MINSIZE | wx.TOP | wx.ALIGN_CENTER, border=10)
        
        b1 = wx.Button(parent=panel, id=10, label='Button1')
        b2 = wx.Button(parent=panel, id=11, label='Button2')
        self.Bind(wx.EVT_BUTTON, self.on_click, id=10, id2=20)

        # 创建静态框对象
        sb = wx.StaticBox(panel, label="按钮框")
        # 创建水平方向的StaticBox布局管理器
        hsbox = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
        # 添加b1到水平StaticBox布局管理
        hsbox.Add(b1, 0, wx.EXPAND | wx.BOTTOM, 5)
        # 添加b2到水平StaticBox布局管理
        hsbox.Add(b2, 0, wx.EXPAND | wx.BOTTOM, 5)

        # 添加hbox到vbox
        vbox.Add(hsbox, proportion=1, flag=wx.CENTER)
		
        #将布局管理器放入面板中
        panel.SetSizer(vbox)

    def on_click(self, event):
        event_id = event.GetId()
        print(event_id)
        if event_id == 10:
            self.statictext.SetLabelText('Button1单击')
        else:
            self.statictext.SetLabelText('Button2单击')


class App(wx.App):

    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True

if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

image-20200925194423581

FlexGrid布局器
import wx

# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='FlexGrid布局', size=(400, 200))
        self.Centre()  # 设置窗口居中
        panel = wx.Panel(parent=self)
		#创建3×2大小的网格管理器,边界大小为10
        fgs = wx.FlexGridSizer(3, 2, 10, 10)
		
        #
        title = wx.StaticText(panel, label="标题:")
        author = wx.StaticText(panel, label="作者名:")
        review = wx.StaticText(panel, label="内容:")

        tc1 = wx.TextCtrl(panel)
        tc2 = wx.TextCtrl(panel)
        #style代表窗口风格,TE_MULTILINE代表是多行格式的
        tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
		
        fgs.AddMany([title, (tc1, 1, wx.EXPAND),
                     author, (tc2, 1, wx.EXPAND),
                     review, (tc3, 1, wx.EXPAND)])
		
        #设置控件所占行和列的比例
        fgs.AddGrowableRow(0, 1)
        fgs.AddGrowableRow(1, 1)
        fgs.AddGrowableRow(2, 3)
        fgs.AddGrowableCol(0, 1)
        fgs.AddGrowableCol(1, 2)

        #把当前网格管理器放入一个水平Box管理器中,防止一些内容越界的问题,不是必要
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(fgs, proportion=1, flag=wx.ALL | wx.EXPAND, border=15)
		
        #将Box管理器放入面板中
        panel.SetSizer(hbox)


class App(wx.App):

    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True


if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

image-20200925200136950

常用控件

按钮
  • wx.Button 普通按钮
  • wx.ToggleButton 能进行状态切换的按钮,点一下就代表选中了
  • wx.BitmapButton 带有图标的按钮
# coding=utf-8
# 代码文件:chapter19/ch19.6.1.py

import wx


# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='静态文本和按钮', size=(300, 200))
        self.Center()  # 设置窗口居中
        panel = wx.Panel(parent=self)
        # 创建垂直方向的Box布局管理器
        vbox = wx.BoxSizer(wx.VERTICAL)

        self.statictext = wx.StaticText(parent=panel, label='锄禾日当午', style=wx.ALIGN_CENTRE_HORIZONTAL)
        #创建三种类型的按钮
        b1 = wx.Button(parent=panel,id = 1, label='OK')
        b2 = wx.ToggleButton(panel, id = 2, label = 'ToggleButton')
        bmp = wx.Bitmap('./images/flag/1.png', wx.BITMAP_TYPE_PNG)
        b3 = wx.BitmapButton(panel, id = 3, bitmap = bmp)
        self.Bind(wx.EVT_BUTTON, self.on_click, id = 1, id2 = 3)

        # 添加静态文本和按钮到Box布局管理器
        vbox.Add(100, 10, proportion=1, flag=wx.CENTER | wx.FIXED_MINSIZE) #填充空白
        vbox.Add(self.statictext, proportion=1, flag=wx.CENTER | wx.FIXED_MINSIZE)
        vbox.Add(b1, proportion=1, flag=wx.CENTER | wx.EXPAND)
        vbox.Add(b2, proportion=1, flag=wx.CENTER | wx.EXPAND)
        vbox.Add(b3, proportion=1, flag=wx.CENTER | wx.EXPAND)

        panel.SetSizer(vbox)

    def on_click(self, event):
        self.statictext.SetLabelText('汗滴禾下土')


class App(wx.App):

    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True


if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

image-20200925201308437

单选按钮和复选框
  • wx.RadioButton单选按钮
  • wx.CheckButton复选框
import wx

# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='复选框和单选按钮', size=(400, 130))
        self.Center()  # 设置窗口居中
        panel = wx.Panel(self)

        hbox1 = wx.BoxSizer(wx.HORIZONTAL)

        statictext = wx.StaticText(panel, label='选择你喜欢的编程语言:')
        cb1 = wx.CheckBox(panel, 1, 'Python')
        cb2 = wx.CheckBox(panel, 2, 'Java')
        cb3 = wx.CheckBox(panel, 3, 'C++')
        self.Bind(wx.EVT_CHECKBOX, self.on_checkbox_click, id=1, id2=3)

        hbox1.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
        hbox1.Add(cb1, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
        hbox1.Add(cb2, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
        hbox1.Add(cb3, 1, flag=wx.ALL | wx.FIXED_MINSIZE)

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)

        statictext = wx.StaticText(panel, label='选择性别:')
        #style = wx.RB_GROUP表示后续控件都归为1组
        radio1 = wx.RadioButton(panel, 4, '男', style=wx.RB_GROUP)
        radio2 = wx.RadioButton(panel, 5, '女')
        self.Bind(wx.EVT_RADIOBUTTON, self.on_radio1_click, id=4, id2=5)
		
        hbox2.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
        hbox2.Add(radio1, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
        hbox2.Add(radio2, 1, flag=wx.ALL | wx.FIXED_MINSIZE)

        hbox3 = wx.BoxSizer(wx.HORIZONTAL)

        statictext = wx.StaticText(panel, label='选择你最喜欢吃的水果:')
        radio3 = wx.RadioButton(panel, 6, '苹果', style=wx.RB_GROUP)
        radio4 = wx.RadioButton(panel, 7, '橘子')
        radio5 = wx.RadioButton(panel, 8, '香蕉')
        self.Bind(wx.EVT_RADIOBUTTON, self.on_radio2_click, id=6, id2=8)

        hbox3.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
        hbox3.Add(radio3, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
        hbox3.Add(radio4, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
        hbox3.Add(radio5, 1, flag=wx.ALL | wx.FIXED_MINSIZE)

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(hbox1, 1, flag=wx.ALL | wx.EXPAND, border=5)
        vbox.Add(hbox2, 1, flag=wx.ALL | wx.EXPAND, border=5)
        vbox.Add(hbox3, 1, flag=wx.ALL | wx.EXPAND, border=5)
        panel.SetSizer(vbox)

    def on_checkbox_click(self, event):
        #获取当前事件的对象
        cb = event.GetEventObject()
        #输出对应label 和 状态(是否被选择)
        print('选择 {0},状态{1}'.format(cb.GetLabel(), event.IsChecked()))

    def on_radio1_click(self, event):
        rb = event.GetEventObject()
        print('第一组 {0} 被选中'.format(rb.GetLabel()))

    def on_radio2_click(self, event):
        rb = event.GetEventObject()
        print('第二组 {0} 被选中'.format(rb.GetLabel()))

class App(wx.App):

    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True


if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

image-20200925203804860

下拉列表
  • wx.ComboBox 文本框可修改
  • wx.Choice 文本框不可修改
import wx
# 自定义窗口类MyFrame
class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='下拉列表', size=(400, 130))
        self.Center()  # 设置窗口居中
        panel = wx.Panel(self)
		
        #ComboBox下拉列表, 放到一个hbox中
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        statictext = wx.StaticText(panel, label='选择你喜欢的编程语言:')
        list1 = ['Python', 'C++', 'Java']
        #style = wx.CB_SORT 对列表进行排序
        ch1 = wx.ComboBox(panel, -1, choices=list1, style=wx.CB_SORT)
        self.Bind(wx.EVT_COMBOBOX, self.on_combobox, ch1)

        hbox1.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
        hbox1.Add(ch1, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
		
        #Choice下拉列表, 放到一个hbox中
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        statictext = wx.StaticText(panel, label='选择性别:')
        list2 = ['男', '女']
        ch2 = wx.Choice(panel, -1, choices=list2)
        self.Bind(wx.EVT_CHOICE, self.on_choice, ch2)

        hbox2.Add(statictext, 1, flag=wx.LEFT | wx.RIGHT | wx.FIXED_MINSIZE, border=5)
        hbox2.Add(ch2, 1, flag=wx.ALL | wx.FIXED_MINSIZE)
		
        #将两个hbox放到vbox中
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(hbox1, 1, flag=wx.ALL | wx.EXPAND, border=5)
        vbox.Add(hbox2, 1, flag=wx.ALL | wx.EXPAND, border=5)
        
        #vbox放入面板中
        panel.SetSizer(vbox)

    def on_combobox(self, event):
        print('选择 {0}'.format(event.GetString()))

    def on_choice(self, event):
        print('选择 {0}'.format(event.GetString()))


class App(wx.App):

    def OnInit(self):
        # 创建窗口对象
        frame = MyFrame()
        frame.Show()
        return True


if __name__ == '__main__':
    app = App()
    app.MainLoop()  # 进入主事件循环

image-20200925205122247

posted @ 2020-09-26 13:05  提笔书几行  阅读(434)  评论(0编辑  收藏  举报