Python 图形界面框架TkInter之在源码中找pack方法

当我们在学习 Python 编程语言时,经常会用到 Python 的图形界面框架 Tkinter。而 Tkinter 的布局管理器 Layout Manager 有三种,分别是 pack、grid、place。

本篇攻略主要介绍如何在 Tkinter 源码中找到 pack 方法。在 Tkinter 的源码中,pack 方法主要由两个类完成,分别是:CorePackPack. 这两个类分别定义了 pack 的基础和具体实现。

首先,我们可以在 Python 安装目录下找到 Tkinter 源码的位置。我们以 Python 3.9.2 版本为例,可以在以下路径找到 tkinter 的源码:

C:\Users\UserName\AppData\Local\Programs\Python\Python399\Lib\tkinter

其中,appdatausername 可以根据你的电脑用户名和操作系统版本而变化。接着,我们打开 tkinter 目录下的 __init__.py 文件,可以看到以下代码:

from tkinter import *
import tkinter.ttk as ttk
import tkinter.font as font

# 模块注释...

__init__.py 中,我们已经直接导入了 tkinter 模块的全部内容。而 tkinter 模块中的 pack 布局管理器,就是通过 CorePackPack 两个类完成的。下面,我们详细介绍一下这两个类的作用:

CorePack

CorePack 类是 Pack 类的父类,它定义了 pack 的一些基本属性和方法。它的主要作用如下:

  1. 定义了一些默认的参数,例如:fill="none", expand="no"
  2. 声明一些实例变量,例如:self._args, self._options
  3. 定义了一些实例方法,例如:_setitem, _option_dict, _option_db, _options.

下面是 CorePack 类的完整代码示例:

class CorePack:
    # 默认参数
    _default = {
        "anchor": "center",
        "expand": "no",
        "fill": "none",
        "ipadx": 0,
        "ipady": 0,
        "padx": 0,
        "pady": 0,
        "side": "top"
    }

    def _setitem(self, args, kwargs):
        """处理参数"""
        if len(args) == 1:
            # 传递 option 字典
            options = args[0]
        else:
            # 将 args 转化为 list,方便后面操作
            options = list(args)

        # 合并 options 和 kwargs 中的参数
        for key, value in kwargs.items():
            options.append(f"-{key}")
            options.append(value)

        return options

    def _option_dict(self, kwargs):
        """将参数映射成字典"""
        options_dict = {}

        for key in kwargs:
            if key == "side" and kwargs[key]:
                options_dict[key] = kwargs[key][0]
            else:
                options_dict[key] = kwargs[key]

        return options_dict

    def _option_db(self, kwargs):
        """将参数映射成字典"""
        options_dict = {}

        for key in kwargs:
            if isinstance(kwargs[key], tuple):
                options_dict[key] = ",".join(map(str, kwargs[key]))
            else:
                options_dict[key] = kwargs[key]

        return options_dict

    def _options(self, args, kwargs):
        """获取选项参数"""
        if len(args) == 1 and isinstance(args[0], (int, float, str)):
            # 将 args 转化为 list,方便后面操作
            args = list(args)
            options = []

            # args 中的第一个参数为 side
            kwargs["side"] = args.pop(0)

            options += self._setitem(args, kwargs)
        else:
            options = self._setitem(args, kwargs)

            if "side" not in kwargs:
                options.insert(0, "-top")

            if not any(x for x in options if x.startswith("-side=")):
                options.insert(0, "-side=top")

        return self._option_dict(self._option_db(options))

Pack

Pack 类是 CorePack 类的子类,它是 pack 的具体实现。Pack 类的主要作用如下:

  1. 声明一些实例变量,例如:self.masterself.slaves
  2. 定义了一些实例方法,例如:forget, info, place, propagate, slaves, unpack

下面是 Pack 类的完整代码示例:

class Pack(CorePack):
    """pack 布局管理器"""

    def __init__(self, master=None, cnf={}, **kw):
        super().__init__()

        # 父容器
        self.master = master

        # 子容器
        self.slaves = []

        # 保存配置信息
        self._configure(cnf, kw)

    def pack_configure(self, cnf={}, **kw):
        """设置控件属性"""
        self._configure(cnf, kw)

    def pack_forget(self):
        """隐藏控件"""
        for slave in self.slaves:
            slave.pack_forget()

    def pack_info(self, name=None):
        """返回控件的属性"""
        if name:
            info_list = []

            for slave in self.slaves:
                info = slave.pack_info()

                if info["name"] == name:
                    return info

            raise TclError(f"no {name} packed in {self}")

        elif len(self.slaves) == 1:
            return self.slaves[0].pack_info()

        else:
            info_list = []

            for slave in self.slaves:
                name = slave.pack_info()["name"]

                if name:
                    info_list.append(name)

            return tuple(info_list)

    def pack_propagate(self, flag=None):
        """允许或禁止控件自动调整"""
        if flag is None:
            flag = 1

        elif isinstance(flag, str):
            flag = {"yes": 1, "no": 0, "1": 1, "0": 0}[flag]

        elif flag:
            flag = 1

        else:
            flag = 0

        self.master.pack_propagate(flag)

    def pack_slaves(self):
        """返回子控件"""
        return self.slaves

    def pack_unpack(self):
        """取消控件"""
        for slave in self.slaves:
            slave.pack_unpack()

    def pack_configure(self, cnf=None, **kw):
        """设置控件属性"""
        if cnf is None:
            cnf = {}

        self._configure(cnf, kw)

    def _configure(self, cnf={}, kw={}):
        """设置控件属性"""
        cnf = self._option_db(cnf)
        kw = self._option_db(kw)

        self.master.tk.call(
            ("pack", "configure", self._name) +
            self._options(self._args, cnf, kw))

    def _options(self, args, cnf, kw):
        """获取选项参数"""
        options = super()._options(args, kw)

        if cnf or args:
            options += ("-",)

        return options + super()._options(args, cnf)

上述代码中,我们可以看到 Pack 类中的 pack_configurepack_forgetpack_infopack_propagatepack_slavespack_unpack 这几个方法,这些方法就是 pack 的具体实现。

同时,Pack 类中还包含 _configure_options 这两个私有方法,它们分别用于配置控件的属性和获取选项参数。需要注意的是,_configure_options 方法定义在 CorePack 类中,因此 Pack 类中只需要继承即可。

通过上述代码和解释,我们已经知道如何在 Tkinter 源码中找到 pack 方法,并且了解了 CorePackPack 两个类的作用。接下来,我们举两个例子,更具体地说明如何使用 pack 的方法。

例子 1:使用 pack 布局管理器进行水平排列

import tkinter as tk

root = tk.Tk()

for i in range(3):
    tk.Button(root, text=f"Button {i}").pack(side="left")

root.mainloop()

这个例子中,我们使用了 packside 参数实现水平排列。在 for 循环中创建三个按钮,并将它们都设置为 side="left",即使它们水平排列。

例子 2:使用 pack 布局管理器进行竖直排列

import tkinter as tk

root = tk.Tk()

for i in range(3):
    tk.Button(root, text=f"Button {i}").pack(side="top")

root.mainloop()

这个例子中,我们同样使用了 packside 参数实现竖直排列。在 for 循环中创建三个按钮,并将它们都设置为 side="top",即使它们竖直排列。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 图形界面框架TkInter之在源码中找pack方法 - Python技术站

(0)
上一篇 2023年6月13日
下一篇 2023年6月13日

相关文章

  • python中itertools模块使用小结

    Python中itertools模块使用小结 Python中itertools是一个标准库,用于生成迭代器的函数和无限迭代器。它提供了各种有用的迭代器用于有效地对迭代器工作。下面是一些最常用的itertools函数: itertools.count(start=0, step=1) 生成从start开始的连续整数,步骤为step。 import iterto…

    python 2023年6月3日
    00
  • Python 音视频剪辑快速入门教程

    Python 音视频剪辑快速入门教程 简介 Python 是一种跨平台的编程语言,拥有丰富的模块和库,可以用于开发各种类型的应用,包括音视频剪辑。 本文将介绍使用 Python 进行音视频剪辑的基本流程和常用库,包括 FFmpeg、MoviePy 和 PyDub。同时,也会结合示例,讲解其具体用法和实现。 安装 在使用 Python 进行音视频剪辑前,需要先…

    python 2023年5月19日
    00
  • 如何在启动时在 Python IDLE 中预加载 Python 模块?

    【问题标题】:How to Pre-load Python Modules in Python IDLE on Startup?如何在启动时在 Python IDLE 中预加载 Python 模块? 【发布时间】:2023-04-01 03:58:01 【问题描述】: 我在 Windows 7 上。当我启动 Python IDLE 时,我希望它预加载:pan…

    Python开发 2023年4月8日
    00
  • Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)

    Python SQLAlchemy基本操作和常用技巧 什么是SQLAlchemy SQLAlchemy是Python中最流行的ORM框架之一。ORM即“对象关系映射”,它提供了一种将数据库和Python对象联系起来的方式,这种方式使得在Python中操作数据库变得更加容易,同时也能够提供更好的抽象化和安全性。 安装SQLAlchemy 要使用SQLAlche…

    python 2023年5月13日
    00
  • Python操作配置文件ini的三种方法讲解

    Python操作配置文件ini的三种方法讲解 配置文件ini格式是将配置信息存储在文件中的一种方式,它通常被用来存储应用程序的一些设置、选项和配置信息。Python提供了多种方法来操作ini格式的配置文件,本文介绍其中的三种方法。 1. 使用configparser模块 configparser模块是Python内置的操作ini格式配置文件的模块。它提供了C…

    python 2023年6月3日
    00
  • Elasticsearch py客户端库安装及使用方法解析

    好的。下面我将详细讲解“Elasticsearch py客户端库安装及使用方法解析”的完整攻略,具体内容包括: 安装Elasticsearch py客户端库 连接到Elasticsearch集群 创建Elasticsearch索引 写入数据 查询数据 示例说明 1. 安装Elasticsearch py客户端库 Elasticsearch py客户端库可以通…

    python 2023年6月3日
    00
  • 深入理解Python变量的数据类型和存储

    深入理解 Python 变量的数据类型和存储 Python 是一门动态类型语言,即变量的类型是在运行时确定的。因此,深入理解 Python 变量的数据类型和存储及其在计算机底层的表示方式,有助于我们更好地使用 Python 进行编程。 Python 变量的数据类型 Python 内置了五种标准的数据类型,分别是: Numbers(数字):整数、浮点数、复数等…

    python 2023年5月14日
    00
  • vs code 配置python虚拟环境的方法

    下面是详细讲解“vs code 配置python虚拟环境的方法”的完整攻略。 什么是Python虚拟环境 Python虚拟环境是指在一个系统中运行的独立Python环境,其各自的环境变量、依赖包、Python解释器、工具等都是独立的。为什么要使用Python虚拟环境?我们知道在Python应用程序开发中,开发环境与生产环境的配置可能会不同,部署环境与测试环境…

    python 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部