本帖最后由 damiaa 于 2025-3-5 21:12 编辑
【 STM32MP135F-DK测评】+(5)为制作图形界面通读python-gtk-3手册 之一
一 概念和板子上python>k的情况。
Gtk,全称GIMP Toolkit,是一个免费且开源的图形用户界面(GUI)工具包,由GNOME和活跃的开发者社区维护。它提供了丰富的控件和布局管理器,使得开发者能够轻松地创建美观、实用的用户界面。Gtk不仅支持C语言,还提供了对Python、JavaScript、C++、Rust等多种语言的支持,因此它广泛应用于桌面应用程序的开发。
STM32MP135F-DK在安装了stm32mp1-openstlinux-6.6-yocto-scarthgap-mpu-v24.11.06后动安排了python3 和gtk3.0,上面有一些例子,面包上的Pyhton GTK launcher 就可以启动很多例子。
当然我们也可以直接编写例子,我这里准备在windows上的vscode上编写后用ssh传到板子上运行。
二、实践操作:通读前面5章节
1,最小例程:
Python 3,需要通过gi (GObject Introspection)模块使用Gtk+,以便能够访问 GTK+ 的类和函数。并且指向GTK+ 3库版本:gi.require_version('Gtk', '3.0') 的目的。
随后Gtk.Window()来创建一个空的窗体。
然后可以连接一些事件到窗体,比如win.connect("destroy", Gtk.main_quit)
连接quit事件
后面就可以用win窗体对象的showall()方法来显示。
最后,我们使用Gtk.main()启动 GTK+ 处理循环,当窗口关闭时退出。
运行就用:python xxx.py
2,扩展举例:
一个经典的有用的例子的PyGObject v版本如下:
具体是在按下button后会在命令行窗口输出Hello World
3 基础知识
本节将介绍 GTK+ 的一些最重要的方面。
3.1. 主循环和信号
像大多数 GUI 工具包一样,GTK+ 使用事件驱动的编程模型。当用户什么都不做时,GTK+ 位于主循环中并等待输入。如果用户执行了一些作 - 比如鼠标单击 - 那么主循环会 “唤醒” 并向 GTK+ 传递一个事件。
当 widget 收到事件时,它们会频繁地发出一个或多个信号。Signals 通过调用已连接到 Signal 的函数来通知程序“发生了一些有趣的事情”。此类函数通常称为回调。调用回调时,通常会执行一些作 - 例如,单击“打开”按钮时,可能会显示文件选择器对话框。回调完成后,GTK+ 将返回主循环并等待更多用户输入。
一个通用的函数示例是:
handler_id = widget.connect("event", callback, data)
首先,widget 是我们之前创建的 widget 的一个实例。接下来,我们感兴趣的事件。每个小组件都有其自己的特定事件,这些事件可能会发生。例如,如果您有一个按钮,您通常希望连接到 “clicked” 事件。这意味着当单击按钮时,会发出信号。第三,callback 参数是回调函数的名称。它包含在发出指定类型的信号时运行的代码。最后, data 参数包括在发出信号时应传递的任何数据。但是,此参数是完全可选的,如果不需要,可以省略。
该函数返回一个数字,用于标识此特定信号-回调对。
如果有需要断开与信号的连接,以便在它所连接的信号的任何未来或当前正在进行的发射期间不会调用回调函数,可以使用下面的函数
widget.disconnect(handler_id)
如果不知道什么原因失去了指针句柄,额可以如下操作:
widget.disconnect_by_func(callback)
应用程序应连接到顶级窗口的 “destroy” 信号。它在销毁对象时发出,因此当用户请求关闭顶级窗口时,此信号的默认处理程序会销毁窗口,但不会终止应用程序。将顶层窗口的 “destroy” 信号连接到函数 Gtk.main_quit() 将产生所需的行为。
window.connect("destroy", Gtk.main_quit)
3.2. 属性
Properties 描述 Widget 的配置和状态。至于信号,每个小部件都有自己特定的属性集。例如,按钮具有属性 “label”,其中包含按钮内标签 Widget 的文本。在创建 Widget 的实例时,您可以将任意数量的属性的名称和值指定为关键字参数。要创建向右对齐的标签,文本为 “Hello World” 并呈 25 度角,请使用:
label = Gtk.Label(label="Hello World", angle=25, halign=Gtk.Align.END)
相当于下面的句子:
label = Gtk.Label()
label.set_label("Hello World")
label.set_angle(25)
label.set_halign(Gtk.Align.END)
除了使用 getter 和 setter 之外,还可以通过 props 属性(如 widget.props.prop_name = value)来获取和设置 gObject 属性。这等效于更详细的 widget.get_property(“prop-name”) 和 widget.set_property(“prop-name”, value)。
要查看正在运行的 GTK 版本中的小部件有哪些属性可用,您可以 “dir” “props” 属性:
widget = Gtk.Box()
print(dir(widget.props))
这将在控制台中打印 Gtk.Box 的属性列表。
4. 如何处理字符串
本节解释了字符串在 Python 2.x、Python 3.x 和 GTK+ 中的表示方式,并讨论了使用字符串时出现的常见错误。
4.1. 定义
从概念上讲,字符串是字符列表,例如 'A'、'B'、'C' 或 'É'。字符是抽象表示,它们的含义取决于它们使用的语言和上下文。Unicode 标准描述了字符如何由码位表示。例如,上面的字符分别用码位 U+0041、U+0042、U+0043 和 U+00C9 表示。基本上,码位是 0 到 0x10FFFF 范围内的数字。
如前所述,将字符串表示为代码点列表是抽象的。为了将此抽象表示形式转换为字节序列,必须对 Unicode 字符串进行编码。最简单的编码形式是 ASCII,其执行方式如下:
如果码位< 128,则每个字节与代码的值相同。如果码位为 128 或更大,则此编码无法表示 Unicode 字符串。(在这种情况下,Python 会引发 UnicodeEncodeError 异常。)虽然 ASCII 编码应用简单,但它只能编码 128 个不同的字符,这几乎不够。解决此问题的最常用编码之一是 UTF-8(它可以处理任何 Unicode 码位)。UTF 代表“Unicode 转换格式”,而“8”表示编码中使用 8 位数字。
4.2. Python 2
4.2.1. Python 2.x 的 Unicode 支持
Python 2 带有两种不同类型的对象,可用于表示字符串,str 和 unicode。后者的实例用于表示 Unicode 字符串,而 str 类型的实例是字节表示形式(编码的字符串)。在后台,Python 将 Unicode 字符串表示为 16 位或 32 位整数,具体取决于 Python 解释器的编译方式。Unicode 字符串可以使用 unicode.encode() 转换为 8 位字符串:
Python 的 8 位字符串有一个 str.decode() 方法,它使用给定的编码来解释字符串:
不幸的是,如果 8 位字符串恰好只包含 7 位 (ASCII) 字节,Python 2.x 允许您混合 unicode 和 str,但如果它包含非 ASCII 值,则会得到 UnicodeDecodeError:
4.2.2. GTK+ 中的 Unicode
GTK+ 对所有文本使用 UTF-8 编码的字符串。这意味着,如果调用返回字符串的方法,则始终会获取 str 类型的实例。这同样适用于需要一个或多个字符串作为参数的方法,它们必须是 UTF-8 编码的。但是,为方便起见,如果作为参数提供,PyGObject 会自动将任何 unicode 实例转换为 str:
请注意末尾的警告。尽管我们以 unicode 实例作为参数调用 Gtk.Label.set_text(),但 Gtk.Label.get_text() 将始终返回一个 str 实例。因此,txt 和 unicode_string 并不相等。
如果您想使用 gettext 国际化您的程序,这一点尤其重要。您必须确保 gettext 将为所有语言返回 UTF-8 编码的 8 位字符串。一般来说,建议在 GTK+ 应用程序中根本不使用 unicode 对象,只使用 UTF-8 编码的 str 对象,因为 GTK+ 没有与 unicode 对象完全集成。否则,每次调用 GTK+ 方法时,您都必须将返回值解码为 Unicode 字符串:
4.3. Python 3
4.3.1. Python 3.x 的 Unicode 支持
从 Python 3.0 开始,所有字符串都作为 Unicode 存储在 str 类型的实例中。另一方面,编码的字符串以 bytes 类型的实例形式表示为二进制数据。从概念上讲, str 是指文本,而 bytes 是指数据。使用 str.encode() 从 str 转到 bytes,使用 bytes.decode() 从 bytes 到 str。
此外,不再可能将 Unicode 字符串与编码字符串混合使用,因为这会导致 TypeError:
4.3.2. GTK+ 中的 Unicode
因此,与 Python 3.x 相比,事情更加简洁和一致,因为如果你将字符串传递给方法或方法返回字符串,PyGObject 将自动编码/解码为 UTF-8 或从 UTF-8 解码。字符串或文本将始终仅表示为 str 的实例:
4.4. 参考资料
Python 3.0 中的新增功能描述了明确区分文本和数据的新概念。
Unicode HOWTO 讨论了 Python 2.x 对 Unicode 的支持,并解释了人们在尝试使用 Unicode 时经常遇到的各种问题。
Python 3.x 的 Unicode HOWTO 讨论了 Python 3.x 中的 Unicode 支持。
UTF-8 编码表和 Unicode 字符包含 Unicode 码位列表及其各自的 UTF-8 编码。
5. 小部件库 Widget Gallery
选择对话框
布局容器Assistant
Button
颜色选择对话框
文件选择对话框
流式布局box
字体选择按钮框
字体选择对话框
总之,从图就可以看出大概意思了。
先写到这里,谢谢