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日

相关文章

  • 常用正则表达式 整理篇

    常用正则表达式整理篇攻略 正则表达式是一种用于匹配文本的模式。在实际应用中,我们经常需要使用正表达式来解析HTML、XML等文本数据。本攻略将详细讲解常用正则表达式的整理,包括正则表达式的基本语法、常用的正则表达式模式、以及如何在Python中使用正则表达式。 正则表达式基本语法 正则表达式是一种用于匹配文本的模式。在Python中,我们可以使用re模块来使…

    python 2023年5月14日
    00
  • Python数据结构之树的全面解读

    Python数据结构之树的全面解读 什么是树? 树是一种重要的数据结构,它以分层的方式存储数据,根据结点之间的层次关系,被称作父结点、子结点以及兄弟结点。 树的组成部分 一棵树由一个根结点、若干个子树以及它们构成的森林组成。树具有以下属性:- 每个结点都有唯一的一个父结点(除了根结点)- 每个结点可以有多个子结点- 没有环路(即,一个结点不能成为它自己的祖先…

    python 2023年5月14日
    00
  • Django 实现前端图片压缩功能的方法

    一、前言 在现代 Web 应用程序中,经常需要上传、显示图片。但是,过多的图片会增加服务器的负担,也会占用用户的带宽。为了达到更好的用户体验,我们需要在上传图片的同时实现对图片的压缩。 本文将介绍 Django 框架如何实现前端图片压缩功能的方法。 二、前端图片压缩 前端图片压缩指的是在使用 JavaScript 等前端语言进行图片处理。前端图片压缩可大大减…

    python 2023年5月18日
    00
  • Python错误与异常处理

    Python 错误与异常处理 – 完整攻略 Python 是一门强大的编程语言,但是编写代码时难免会出现错误和异常。这篇文档将讲解 Python 中的错误和异常处理。 异常 Python 中的异常是指运行时出现的错误。当程序出现异常时,程序将停止运行并输出错误信息。Python 中有许多内置的异常类,例如 ZeroDivisionError、TypeErro…

    python 2023年5月13日
    00
  • Python 正则表达式基础知识点及实例

    Python正则表达式基础知识点及实例 正则表达式是一种用于描述字符串模式的语言,可以用于配、查找、替换和分割。在Python中,可以使用re模块使用正则表达式。本文将详细介绍中正则表达式的语法、字符集、转义字符以及常用函数,并提供两个示例说明。 正则表达式语法 正则表达式由普通字符和元字符组成,普通字符表示本身,而元字符有特殊的含。下面是一些用的元字符: …

    python 2023年5月14日
    00
  • python可变对象,不可变对象详解

    Python可变对象和不可变对象详解 在Python中,对象分为可变对象和不可变对象。对于可变对象,我们在操作它时可以改变它的值,而不可变对象在创建之后就无法改变。 Python的基本数据类型中有五种不可变对象:数字、字符串、元组、不可变集合和不可变字典。除此之外,其他类型都是可变对象,比如列表、字典、集合等。 不可变对象 数字 数字不可变是因为它们是按值传…

    python 2023年5月13日
    00
  • python实现在遍历列表时,直接对dict元素增加字段的方法

    要在Python中遍历字典列表,并为其元素添加新字段,通常有两种方法: 方法一:使用for循环遍历并修改元素 # 定义一个包含字典元素的列表 users = [ {‘name’: ‘John’, ‘age’: 25}, {‘name’: ‘Jane’, ‘age’: 20}, {‘name’: ‘Bob’, ‘age’: 30} ] # 遍历列表 for u…

    python 2023年5月13日
    00
  • 使用python+pygame开发消消乐游戏附完整源码

    下面为您详细讲解使用Python+Pygame开发消消乐游戏的完整攻略: 1. 安装Pygame Pygame是Python中常用的游戏开发库,如果没有安装,需要通过以下命令进行安装: pip install pygame 2. 游戏框架搭建 使用Pygame开发游戏需要先搭建游戏框架,具体流程如下: 2.1. 导入库 import pygame impor…

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