关于WxPython的学习

最开始跟着B站的视频学的,看不太懂。

然后跟着学习的网站(本文相当于学习这篇博客中的小拓展与思考,学习wxpython的话还是得看这篇博客为主):wxPython入门中文版 (Getting Started with wxPython)-CSDN博客

做点笔记,记录学习过程中的疑问:

1.wx.Button, wx.StaticText, wx.TextCtrl 和 wx.ComboBox的作用:

  1. wx.Button

    • wx.Button 用于创建一个按钮控件。用户可以点击按钮来触发事件,例如提交表单或调用一个函数。
    • 按钮控件通常用于接收用户的操作指令。
  2. wx.StaticText

    • wx.StaticText 用于显示不可编辑的文本,例如标签或提示信息。
    • 与文本编辑框不同,静态文本控件不支持用户输入。
  3. wx.TextCtrl

    • wx.TextCtrl 是一个文本编辑框,允许用户输入和编辑文本。
    • 它可以是单行或多行(通过设置 wx.TE_MULTILINE 样式)。
    • wx.TextCtrl 可用于接收用户输入的文本数据。
  4. wx.ComboBox

    • wx.ComboBox 是一个下拉列表控件,结合了文本输入和选择列表的功能。
    • 用户可以从列表中选择一个选项,或者在允许编辑的情况下输入文本。
    • 它适用于提供有限选项集供用户选择。

以下是如何在 wxPython 应用程序中使用这些组件的简单示例:在这个示例中,我们创建了一个包含静态文本、文本输入框、下拉列表和按钮的简单窗口。每个控件都放置在窗口的面板上,并设置了合适的位置。按钮绑定了一个事件处理函数 on_button_click,当按钮被点击时,将打印一条消息。

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        super(MyFrame, self).__init__(parent, title=title, size=(350, 250))

        # 创建一个面板,以便在窗口中加入其他控件
        panel = wx.Panel(self)

        # 创建静态文本
        static_text = wx.StaticText(panel, label="请输入文本:", pos=(20, 20))

        # 创建文本输入框
        text_ctrl = wx.TextCtrl(panel, pos=(100, 20))

        # 创建下拉列表
        combo_box = wx.ComboBox(panel, pos=(100, 50), choices=["选项1", "选项2", "选项3"])
        
        # 创建按钮
        button = wx.Button(panel, label="提交", pos=(20, 100))
        # 绑定按钮点击事件
        button.Bind(wx.EVT_BUTTON, self.on_button_click)

    def on_button_click(self, event):
        print("按钮被点击了!")

app = wx.App(False)
frame = MyFrame(None, "wxPython 控件示例")
frame.Show(True)
app.MainLoop()

2.wx.Panel的作用

wx.PanelwxPython 中的一个类,它提供了一个容器,用于在其中放置其他控件,如按钮、文本框、标签等。使用 wx.Panel 可以创建复杂的用户界面布局,并且可以作为其他控件的父级容器。

以下是 wx.Panel 的一些关键特性和用法:

  1. 容器wx.Panel 可以包含其他GUI控件,如 wx.Buttonwx.StaticTextwx.TextCtrl 等。

  2. 布局管理wx.Panel 可以利用 wxPython 的布局管理器(如 wx.BoxSizerwx.GridSizer 等)来自动管理其子控件的布局。

  3. 样式和颜色:可以为 wx.Panel 设置背景颜色、边框样式等属性。

  4. 事件处理wx.Panel 可以处理各种事件,如鼠标点击、键盘输入等。

  5. 绘图:可以在 wx.Panel 上进行自定义绘图,通过重写其 OnPaint 事件处理函数。

  6. 子控件管理wx.Panel 提供了方法来添加、移除和查询子控件。

使用示例:

在这个示例中,我们创建了一个 wx.Frame 和一个 wx.Panel。然后在 wx.Panel 中添加了一个 wx.Button,并使用 wx.BoxSizer 来管理按钮的布局。我们还设置了 wx.Panel 的背景颜色,以区分它与主窗口的边界。

使用 wx.Panel 是组织和管理复杂GUI应用程序中控件的一种有效方式,它提供了灵活性和强大的布局选项。

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        super(MyFrame, self).__init__(parent, title=title, size=(350, 250))
        self.panel = wx.Panel(self)  # 创建 Panel 实例
        self.panel.SetBackgroundColour(wx.Colour(225, 236, 255))  # 设置背景颜色

        # 在 Panel 中创建其他控件
        self.button = wx.Button(self.panel, label="点击我", pos=(50, 50))
        self.button.Bind(wx.EVT_BUTTON, self.on_button_click)

        # 使用布局管理器
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.button, 0, wx.ALL, 10)
        self.panel.SetSizer(sizer)

    def on_button_click(self, event):
        print("按钮被点击了!")

app = wx.App(False)
frame = MyFrame(None, "wxPython Panel 示例")
frame.Show(True)
app.MainLoop()

3.menuExit=filemenu.Append(wx.ID_EXIT, "&Exit", "Terminate the program") menuExit = filemenu.Append(wx.ID_EXIT, "E&xit", " Terminate the program") 有什么区别,&的位置有什么影响

wxPython 中,当你调用 wx.Menu.Append() 方法来添加一个菜单项时,可以指定一些特殊的字符来影响菜单项的显示和行为:

  1. "&Exit":在这个字符串中,& 符号用于指定一个快捷键(也称为加速键或热键)。在这里,&E 表示 "E" 键是这个菜单项的快捷键。在大多数操作系统中,用户可以通过按下 Alt 键加上这个字符(在这个例子中是 "E")来快速选择这个菜单项。

  2. "E&xit":在这个字符串中,& 符号放在了 "Exit" 的第一个字母前面,这意味着 "X" 将成为快捷键。用户将使用 Alt+X 来激活这个菜单项。

  3. " Terminate the program":这是菜单项的描述,它是一个字符串,提供了关于菜单项功能的额外信息。在大多数菜单实现中,这个描述不会直接显示在菜单上,但可以在工具提示或菜单项的辅助访问信息中使用。

  4. 空格:在 "E&xit" 中,& 后面的空格是必需的,以确保菜单项在显示时 "X" 字母下面能够正确地出现一个下划线,这是图形用户界面中指示快捷键的标准方式。

  5. wx.ID_EXIT:这是一个预定义的标识符,通常用于表示退出程序的标准菜单项。使用预定义的ID可以让菜单项在不同的应用程序中保持一致的行为,并且可以利用操作系统的快捷键(如果存在)。

总结来说,& 的位置决定了哪个字母将成为菜单项的快捷键,这对于用户快速访问菜单功能非常重要。如果 & 后面紧跟的字符是空格或不在可见字符范围内,那么通常不会显示下划线,且不会有快捷键效果。

wxPython 的某些版本或配置中,如果 & 后面没有紧跟字母,或者紧跟的是特殊字符,可能不会显示下划线,但这个字符仍然可以作为快捷键使用。因此,正确的使用 & 可以提高菜单的可访问性和用户体验。

4.状态栏跟菜单栏在哪儿?

点击运行出来的窗口里的File,就会出现菜单栏,鼠标放在具体菜单项目的时候,相关的状态信息会在frame窗口的最下面显示。(我最开始也纳闷儿我菜单栏跟状态栏呢。。。)

5.验证器validation的示例

wx.ValidatorwxPython 中是用来提供对用户输入进行验证的机制。简单来说,它是一种确保用户在文本控件(如 wx.TextCtrl)中输入的数据符合特定要求的方法。以下是对 wx.Validator 的一些关键点的解释,以及如何使用它们:

  1. 目的wx.Validator 的主要目的是确保用户输入的数据是有效的,比如检查输入是否为数字、电子邮件地址、特定格式的字符串等。

  2. 使用场景:当你创建需要用户输入的对话框或输入控件时,可以使用 wx.Validator

  3. 自定义验证器:要使用 wx.Validator,通常需要定义一个 wx.Validator 的子类。这个子类可以是 wx.TextValidator(专门用于文本输入的验证器)或者其他自定义的验证器。

  4. 关联控件:创建了验证器对象后,你需要将它与特定的输入控件关联起来。这可以通过调用控件的 SetValidator() 方法来实现。

  5. 处理事件wx.Validator 还可以截取控件内发生的事件,如键盘敲击事件,并根据这些事件执行特定的逻辑。

  6. 数据转储wx.Validator 还可以用来从控件中提取数据,并将它们转换成适当的格式。

示例:这个示例展示了如何使用 wxPython 创建一个简单的应用程序,其中包含一个文本输入框,该输入框通过自定义验证器限制只能输入文字。

import wx

class NumericTextValidator(wx.Validator):
    def __init__(self):
        super(NumericTextValidator, self).__init__()
        self.Bind(wx.EVT_CHAR, self.OnChar)

    def Clone(self):
        # 返回当前验证器的一个副本
        return NumericTextValidator()

    def Validate(self, parent):
        # 验证控件内容
        return True

    def TransferToWindow(self):
        # 将验证器中的数据传输到控件
        return True

    def TransferFromWindow(self):
        # 从控件传输数据到验证器
        return True

    def OnChar(self, event):
        # 检查按键事件,只允许数字
        key = event.GetKeyCode()
        if key < wx.WXK_SPACE or key == wx.WXK_DELETE:
            event.Skip()  # 允许空格、删除等特殊键
        elif not wx.GetKeyState(wx.MOD_CONTROL) and chr(key).isdigit():
            event.Skip()  # 允许数字键
        else:
            event.Veto()  # 阻止其他字符

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        super(MyFrame, self).__init__(parent, title=title, size=(300, 200))
        panel = wx.Panel(self)

        text_ctrl = wx.TextCtrl(panel, pos=(20, 20), size=(150, -1))
        validator = NumericTextValidator()
        text_ctrl.SetValidator(validator)

        # 其他代码...

app = wx.App(False)
frame = MyFrame(None, "wxPython Validator Example")
frame.Show(True)
app.MainLoop()

自留能跑成功的示例代码:

这个布局死板些,但是好理解一点

import wx
class ExamplePanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.quote = wx.StaticText(self, label='Your quote:', pos=(20, 30))

        # 这个多行的文本框只是用来记录并显示events,不要纠结之
        self.logger = wx.TextCtrl(self, pos=(500,20), size=(200,150),
                                  style=wx.TE_MULTILINE | wx.TE_READONLY)

        # 一个按钮
        self.button = wx.Button(self, label='Save', pos=(300, 300))
        self.Bind(wx.EVT_BUTTON, self.OnClick, self.button)

        # 仅有1行的编辑控件
        self.lblname = wx.StaticText(self, label='Your name:', pos=(20, 60))
        self.editname = wx.TextCtrl(self, value='Enter here your name:',
                                    pos=(150, 60), size=(140, -1))
        self.Bind(wx.EVT_TEXT, self.EvtText, self.editname)
        self.Bind(wx.EVT_CHAR, self.EvtChar, self.editname)

        # 一个ComboBox控件(下拉菜单)
        self.sampleList = ['friends', 'advertising', 'web search',
                           'Yellow Pages']
        self.lblhear = wx.StaticText(self, label="How did you hear from us ?",
                                     pos=(20, 90))
        self.edithear = wx.ComboBox(self, pos=(190, 90), size=(95, -1),
                                    choices=self.sampleList,
                                    style=wx.CB_DROPDOWN)
        self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, self.edithear)
        # 注意ComboBox也绑定了EVT_TEXT事件
        self.Bind(wx.EVT_TEXT, self.EvtText, self.edithear)

        # 复选框
        self.insure = wx.CheckBox(self, label="Do you want Insured Shipment ?",
                                  pos=(20,180))
        self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, self.insure)

        # 单选框
        radioList = ['blue', 'red', 'yellow', 'orange', 'green', 'purple',
                     'navy blue', 'black', 'gray']
        self.rb = wx.RadioBox(self, label="What color would you like ?",
                              pos=(20, 210), choices=radioList,
                              style=wx.RA_SPECIFY_COLS)
        self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, self.rb)

    def OnClick(self, event):
        self.logger.AppendText('Button Clicked\n')
    def EvtText(self, event):
        self.logger.AppendText('Text Changed: %s\n' % event.GetString())

    def EvtChar(self, event):
        self.logger.AppendText('EvtChar: %d\n' % event.GetKeyCode())
        event.Skip()
    def EvtComboBox(self, event):
        self.logger.AppendText('EvtComboBox: %s\n' % event.GetString())
    def EvtCheckBox(self, event):
        self.logger.AppendText('EvtCheckBox: %d\n' % event.Checked())
    def EvtRadioBox(self, event):
        self.logger.AppendText('EvtRadioBox: %d\n' % event.GetInt())


app = wx.App(False)
frame = wx.Frame(None, title="Example", size=(750, 400))
panel = ExamplePanel(frame)
frame.Show()
app.MainLoop()

这个布局好像是要灵活一点,用了wxGridBagSizer,但是感觉没有上面那个示例好理解

# -*- coding: utf-8 -*-

import wx
class ExamplePanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        # 创建一些Sizer
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        grid = wx.GridBagSizer(hgap=5, vgap=5)    # 行和列的间距是5像素
        hSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.quote = wx.StaticText(self, label='Your quote:', pos=(20, 30))
        grid.Add(self.quote, pos=(0,0))    # 加入GridBagSizer

        self.logger = wx.TextCtrl(self, pos=(300,20), size=(200,300), style=wx.TE_MULTILINE | wx.TE_READONLY)

        self.button = wx.Button(self, label='Save', pos=(200, 325))
        self.Bind(wx.EVT_BUTTON, self.OnClick, self.button)

        self.lblname = wx.StaticText(self, label='Your name:', pos=(20, 60))
        grid.Add(self.lblname, pos=(1,0))
        self.editname = wx.TextCtrl(self, value='Enter here your name:', pos=(150, 60), size=(140, -1))
        grid.Add(self.editname, pos=(1,1))
        self.Bind(wx.EVT_TEXT, self.EvtText, self.editname)
        self.Bind(wx.EVT_CHAR, self.EvtChar, self.editname)

        # 向GridBagSizer中填充空白的空间
        grid.Add((10, 40), pos=(2,0))


        self.sampleList = ['friends', 'advertising', 'web search', 'Yellow Pages']
        self.lblhear = wx.StaticText(self, label="How did you hear from us ?", pos=(20, 90))
        grid.Add(self.lblhear, pos=(3,0))
        self.edithear = wx.ComboBox(self, pos=(150, 90), size=(95, -1), choices=self.sampleList, style=wx.CB_DROPDOWN)
        grid.Add(self.edithear, pos=(3,1))
        self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, self.edithear)
        self.Bind(wx.EVT_TEXT, self.EvtText, self.edithear)

        self.insure = wx.CheckBox(self, label="Do you want Insured Shipment ?", pos=(20,180))
        # 加入Sizer的同时,设置对齐方式和边距
        grid.Add(self.insure, pos=(4,0), span=(1,2), flag=wx.BOTTOM, border=5)
        self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, self.insure)

        radioList = ['blue', 'red', 'yellow', 'orange', 'green', 'purple', 'navy blue', 'black', 'gray']
        self.rb = wx.RadioBox(self, label="What color would you like ?", pos=(20, 210), choices=radioList, 
                              majorDimension=3, style=wx.RA_SPECIFY_COLS)
        grid.Add(self.rb, pos=(5,0), span=(1,2))    # 合并了1行2列的单元格
        self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, self.rb)

        hSizer.Add(grid, 0, wx.ALL, 5)
        hSizer.Add(self.logger)
        mainSizer.Add(hSizer, 0, wx.ALL, 5)
        mainSizer.Add(self.button, 0, wx.CENTER)
        # 可以把SetSizer()和sizer.Fit()合并成一条SetSizerAndFit()语句
        self.SetSizerAndFit(mainSizer)

    def OnClick(self, event):
        self.logger.AppendText('Click on object with Id %d\n' % event.GetId())
    def EvtText(self, event):
        self.logger.AppendText('EvtText: %s\n' % event.GetString())
    def EvtChar(self, event):
        self.logger.AppendText('EvtChar: %d\n' % event.GetKeyCode())
        event.Skip()
    def EvtComboBox(self, event):
        self.logger.AppendText('EvtComboBox: %s\n' % event.GetString())
    def EvtCheckBox(self, event):
        self.logger.AppendText('EvtCheckBox: %d\n' % event.Checked())
    def EvtRadioBox(self, event):
        self.logger.AppendText('EvtRadioBox: %d\n' % event.GetInt())


app = wx.App(False)
frame = wx.Frame(None, title="Demo with Notebook")
nb = wx.Notebook(frame)

nb.AddPage(ExamplePanel(nb), "Absolute Positioning")
nb.AddPage(ExamplePanel(nb), "Page Two")
nb.AddPage(ExamplePanel(nb), "Page Three")

frame.Show()
app.MainLoop()

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值