wxPython图形界面开发(更新 2023.11.26)

134 篇文章 14 订阅
53 篇文章 2 订阅

介绍 | 图像查看器 | 增强型图像查看器 | 数据库查看器 | 数据库编辑器 | 计算器 | 压缩包归档器 | MP3 标签编辑器 | PDF合并/拆分实用程序 | 文件搜索实用程序 | FTP应用程序 | XML 编辑器 | 分发应用程序 | wxPython 演示 | 小部件检查工具

GUI
在您深入研究 wxPython 之前,我认为最好先解释一下 GUI 是什么。 图形用户界面是在屏幕上绘制的界面,然后用户可以与之交互。 用户界面由几个常见组件组成,例如:

  • 主窗口
  • 菜单/工具栏
  • 按钮
  • 文本输入
  • 标签

这些统称为小部件。 wxPython 工具包提供了几十个小部件,包括许多用纯 Python 编写的复杂的自定义小部件。 作为开发人员,您将使用这些小部件并以令人愉悦的方式排列它们,以便用户与之交互。

示例-窗口
当您使用 wxPython 创建用户界面时,您几乎总是需要创建一个 wx.Frame 和一个 wx.Panel。 wx.Frame 是包含所有其他小部件的窗口对象。 它实际上是一个框架。 面板有点不同。 它也是一个容器,但它还支持在小部件之间切换的能力。 如果没有面板,选项卡将无法按您预期的方式工作。 您也可以使用面板对小部件进行分组。

让我们创建一个示例Frame来开始:



import wx

app = wx.App(False)

frame = wx.Frame(None, title='Hello World')

frame.Show()

app.MainLoop()

你会注意到的第一件事是你导入了 wx 模块。 这是一个关键的导入,因为您将需要它用于任何 wxPython 的核心小部件。 接下来实例化 Application 对象:wx.App。 你必须有一个 wx.App 实例才能在 wxPython 中运行任何东西。 但是,您一次可能只有其中之一。 你会注意到我已经传入了 False 作为它的第一个参数。 这样做是为了防止 wxPython 捕获 stdout 并将其重定向到由 wxPython 自动生成的新框架。 你可以试试这个,因为它对调试很有用,但不是你想在大多数时候在生产中启用的东西。

对于下一步,您将创建 wx.Frame 实例。 框架有一个必需的参数。

虽然看到上面的内容是非常标准的,但为了更明确,您可以将该行重写为以下内容:

frame = wx.Frame(parent=None, title=‘Hello World’)
如您所见,框架要求您传入父级。 在这种情况下,由于这是应用程序的主要入口点,因此将父项设置为无。 我们还将 title 参数设置为一个字符串,因为如果你没有,那么它默认为一个空字符串,这有点无聊。 接下来调用框架的 Show() 方法使其在屏幕上可见。

最后,要让应用程序本身运行,您必须调用应用程序对象的 MainLoop() 方法。 这将启动事件循环,以便您的 wxPython 应用程序可以响应键盘和小部件事件。 运行此代码时,您应该会看到一个如下所示的窗口:

尽管此代码有效,但您很少会编写与上述示例类似的代码。 相反,您将阅读和编写的大多数 wxPython 代码都放在类中。

示例-类
将 wxPython 中的大多数代码放入类的原因是因为您希望使您的代码更加模块化。 为此,您将与框架相关的小部件放在框架类中,并将分组到面板类中的小部件放入面板中。 你会发现在所有 Python 的 GUI 框架中都是如此,比如 Tkinter 或 PyQt。

让我们花点时间更新上面的示例,使其使用类:

import wx


class MyFrame(wx.Frame):

    def __init__(self):

        wx.Frame.__init__(self, None, title='Hello World')

        self.Show()

if __name__ == '__main__':

    app = wx.App(redirect=False)

    frame = MyFrame()

    app.MainLoop()

在本例中,您将继承 wx.Frame 并将您的子类命名为 MyFrame。 然后,您以与以前相同的方式设置框架,只是框架的代码进入了您的 init() 方法。 您还需要调用 self.Show() 使框架可见。 应用程序的创建仍然像以前一样在代码的末尾。 您还可以在此处实例化您的新框架类。

您还没有完成修改。 Python 3 建议在处理类时使用 super()。 wxPython 中内置 super() 函数的主要用途是用于引用父类,而无需对其进行实际命名。 如果你有空闲时间,我强烈推荐你参考Raymond Hettinger 关于 super() 的文章,因为它非常有助于理解为什么它如此有用。

不管怎样,让我们更新你的代码,让它也使用 super():


import wx

class MyFrame(wx.Frame):

    def __init__(self):

        super().__init__(None, title='Hello World')

        self.Show()

if __name__ == '__main__':

    app = wx.App(redirect=False)

    frame = MyFrame()

    app.MainLoop()

你会看到很多没有使用 super() 的遗留代码。 但是,由于本文使用Python 3,因此您将使用良好的实践并在示例中使用 super()。

请注意,在 Python 2 中,您需要像这样调用 super:

super(MyFrame, self).init(None, title=‘Hello World’)

让我们继续并在您的示例中添加一个带有按钮的 Panel 类:

import wx

class MyPanel(wx.Panel):

    def __init__(self, parent):

        super().__init__(parent)
        button = wx.Button(self, label='Press Me')

class MyFrame(wx.Frame):

    def __init__(self):

        super().__init__(None, title='Hello World')

        panel = MyPanel(self)

        self.Show()

if __name__ == '__main__':

    app = wx.App(redirect=False)

    frame = MyFrame()

    app.MainLoop()

在此添加一个包含一个小部件的面板:一个按钮。 您会注意到面板应该有一个父级,在本例中是一个 Frame。 不过,您可以让其他小部件成为面板的父级。 例如,您可以将面板相互嵌套,或者将 wx.Notebook 制作到它们的父面板中。 无论如何,您只需要一个面板作为框架的唯一小部件。 如果面板是框架的唯一子小部件,面板也会自动扩展以填充框架。 如果您在框架中添加一个面板和一个按钮而不给它们一个位置或将它们放入 sizer,那么它们最终会堆叠在彼此的顶部。

注意:wx.Panel 小部件在 Windows 上启用小部件之间的选项卡。 因此,如果您希望能够在您创建的表单中浏览小部件,您需要有一个面板作为它们的父级。

无论如何,当我运行这段代码时,它最终看起来像这样:

事件
事件是用户使用您的应用程序时发生的事情。 例如,当用户在您的应用程序处于焦点时按下键盘上的按钮时,这将触发 KeyEvent。 如果用户单击您应用程序上的小部件,它将触发某种小部件事件。 您可以通过创建事件绑定来捕获这些事件。 这意味着您正在为您希望应用程序做出反应的特定事件创建一个侦听器。 例如,如果您的应用程序中有一个按钮,您可能希望该按钮在用户按下时执行某些操作。 要真正让按钮做某事,您需要将按钮绑定到按钮按下事件。

让我们更新前面的例子,让按钮真正做一些事情:

import wx

class MyPanel(wx.Panel):

    def __init__(self, parent):

        super().__init__(parent)
        button = wx.Button(self, label='Press Me')

        button.Bind(wx.EVT_BUTTON, self.on_button_press)



    def on_button_press(self, event):

        print('You pressed the button')

class MyFrame(wx.Frame):

    def __init__(self):

        super().__init__(None, title='Hello World')

        panel = MyPanel(self)

        self.Show()

if __name__ == '__main__':

    app = wx.App(redirect=False)

    frame = MyFrame()

    app.MainLoop()

这里调用按钮的 Bind() 方法并告诉它绑定到一个事件:wx.EVT_BUTTON。 这是按钮按下事件。 第二个参数是按下按钮时要调用的函数。 最后创建事件处理函数 on_button_press()。 您会注意到它需要一个事件参数。 当您在 wxPython 中捕获一个事件时,它会将一个事件对象传递给您绑定到该事件的函数。 这个事件对象通常包含识别调用该函数的小部件的信息以及一堆其他信息。

如果您运行此代码,您应该会看到每次按下按钮时都会将“您按下按钮”打印到标准输出。 试一试!

在继续之前,我想提一下,您还可以像这样绑定事件:

self.Bind(wx.EVT_BUTTON, self.on_button_press, button)

如果你以这种方式进行绑定,你是在告诉 wxPython 你正在将函数绑定到 wx.Panel 而不是 wx.Button。 这允许我们将多个小部件绑定到同一个事件但不同的事件处理程序,然后使用 event.Skip() 来控制哪些事件在图层上冒泡。 在这个例子中,按钮在底层,面板在下一层,框架在顶层。

让我们再更新一次代码:

import wx

class MyPanel(wx.Panel):

    def __init__(self, parent):

        super().__init__(parent)
        button = wx.Button(self, label='Press Me')

        self.Bind(wx.EVT_BUTTON, self.panel_button_handler, button)

        button.Bind(wx.EVT_BUTTON, self.on_button_press)

    def panel_button_handler(self, event):

        print('panel_button_handler called')

    def on_button_press(self, event):

        print('on_button_press called')

        event.Skip()

class MyFrame(wx.Frame):

    def __init__(self):

        super().__init__(None, title='Hello World')

        panel = MyPanel(self)

        self.Show()

if __name__ == '__main__':

    app = wx.App(redirect=False)

    frame = MyFrame()

    app.MainLoop()

在这里,您将 EVT_BUTTON 绑定到面板和按钮对象,但您让它们调用不同的事件处理程序。 当您按下按钮时,它的事件处理程序会立即被调用并打印出适当的字符串。 然后调用 event.Skip() 以便 EVT_BUTTON 事件上升到下一个事件处理程序(如果存在)。 在这种情况下,您有一个用于面板并且它也会触发。 如果您愿意,也可以将框架绑定到 EVT_BUTTON 并在那里捕获它。 在任何这些点上,您都可以删除对 event.Skip() 的调用,并且该事件将停止在该事件处理程序处传播。

绝对定位 vs 尺码器
wxPython 支持小部件的绝对定位和小部件的相对定位。 小部件的相对定位需要使用称为 Sizer 或 Layouts 的特殊容器对象。 sizer 允许您调整应用程序的大小并让小部件随之调整大小。 如果您使用绝对定位,则小部件根本无法扩展或更改位置,因此当您调整应用程序大小时,您会发现某些小部件可能会被切断。 如果您在使用低分辨率显示器的计算机上加载应用程序,也会发生这种情况。 始终建议您使用 sizer,因为它们将使您的应用程序更适合在多个显示器和屏幕尺寸上使用。

如果您想尝试使用绝对定位,您需要做的就是更新对您之前创建的 wx.Button 实例化的调用。

这是示例,

button = wx.Button(self, label=‘Press Me’, pos=(100, 10))

这里的新参数称为位置的 pos。 它需要一个以像素为单位的 x 和 y 坐标元组。 起始位置或原点是左上角或 (0, 0)。 在上面的示例中,您告诉 wxPython 将按钮放置在距面板左侧 100 像素和顶部 10 像素的位置。

当你这样做时,它是这样的:

现在让我们尝试使用 sizer。

wxPython 工具包有几个可以使用的 sizer:

wx.BoxSizer

wx.StaticBoxSizer

wx.GridSizer

wx.FlexGridSizer

wx.WrapSizer

您还可以将 sizer 相互嵌套。 出于演示目的,您将重点关注 wx.BoxSizer。 让我们尝试将应用程序中的按钮水平和垂直居中。

示例1:wxPython中面板切换
示例2:Raspberry Pi控制wxPython仪表盘
示例3:wxPython异步等待示例

详情参阅 - 亚图跨际

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: wxPython是Python语言中的一个图形化界面设计库,它基于wxWidgets开发而来。下面是五个wxWidgets类列表: 1. wx.Frame类:这是wxPython中最基本的窗口类之一。它代表着一个顶级窗口,可以包含其他控件或窗口,例如按钮、文本框等。通过继承该类,可以创建自定义的窗口。 2. wx.Panel类:这是一个用于容纳其他控件的容器类。使用该类可以将多个控件组合在一起,并在窗口中作为一个整体进行管理。 3. wx.Button类:这是一个用于创建按钮控件的类。通过该类可以创建各种类型的按钮,并为其添加事件处理函数,实现按钮被点击时的相应功能。 4. wx.TextCtrl类:这是一个用于输入和显示文本的控件类。它可以用于接收从用户输入的文本,也可以用于显示程序输出的信息。 5. wx.BoxSizer类:这是一个用于控制控件布局的类。通过该类可以将多个控件按照水平或垂直顺序排列,并设置它们的位置和大小。 以上是五个常用的wxWidgets类列表,使用这些类,我们可以轻松地创建具有丰富功能的图形化界面,实现各种交互操作。 ### 回答2: 在Python图形化界面设计(wxPython)中,有五个常用的wxWidgets类。下面我将逐一介绍它们。 1. wx.Frame类:这是wxWidgets中最基本的类之一。它表示一个包含标题栏、菜单栏、工具栏和其他控件的窗口框架。我们可以使用这个类来创建应用程序的主窗口。 2. wx.Panel类:这个类是一个面板,用于承载其他控件。它可以嵌入到wx.Frame类中,作为主窗口的子窗口。我们可以在这个面板上添加其他控件,如按钮、文本框等。 3. wx.Sizer类:这个类用于调整面板中控件的布局。它可以帮助我们确定控件在面板上的位置和大小。常见的布局管理器有wx.BoxSizer和wx.GridSizer,它们可以分别用于水平和垂直布局或者网格布局。 4. wx.Button类:这个类表示一个按钮控件。我们可以在界面上添加按钮,并为按钮绑定相应的事件处理函数,以响应用户的点击操作。例如,我们可以为按钮添加一个点击事件,在事件处理函数中实现按钮的功能。 5. wx.TextCtrl类:这个类表示一个文本框控件,用于用户输入和显示文本。我们可以将其用于输入框、输出框等场景。例如,我们可以创建一个用于用户输入的文本框,并在某个按钮被点击时获取用户输入的值。 这些是wxPython中常用的五个wxWidgets类。通过使用这些类,我们可以创建出美观、交互性强的图形化界面,并实现相应的功能。 ### 回答3: 在Python中使用wxPython进行图形化界面设计,可以方便地利用wxWidgets类来创建各种控件和窗口。以下是五个常用的wxWidgets类: 1. wx.Frame类:这是创建顶级窗口的基类,它提供了一个有标题栏、菜单栏和工具栏的窗口。可以通过继承wx.Frame类来创建自定义的窗口,并在窗口中添加其他控件。 2. wx.Panel类:这是一个容器类,可以用来放置其他控件。通过在wx.Frame类中添加wx.Panel对象,可以将多个控件组合在一个面板中,从而实现更复杂的界面设计。 3. wx.Button类:这是一个按钮控件类,用于创建各种类型的按钮,比如普通按钮、复选框、单选框等。可以为按钮添加事件处理函数,使其响应用户的点击操作。 4. wx.TextCtrl类:这是一个文本输入控件类,用于接收用户的文本输入。可以设置文本控件的大小、样式和限制输入的格式,还可以获取用户输入的文本内容。 5. wx.StaticText类:这是一个静态文本控件类,用于在界面上显示文字内容。与wx.TextCtrl类不同,静态文本控件一般不允许用户输入,只用于展示信息。 以上是wxPython中常用的五个wxWidgets类,通过这些类的组合和使用,可以实现简单到复杂的图形化界面设计

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值