Tkinter 面向对象框架《一》

news2025/1/10 11:09:30

一、说明

        在本教程中,您将学习如何在 Tkinter 中应用面向对象编程以使代码更有条理。首先介绍Tk下小部件,然后介绍Ttk小部件,即如何从ttk.Frame类继承并在根窗口中使用它。

二、定义 Tkinter 面向对象的窗口

2.1 最基本的对象

        以下简单程序创建一个根窗口并将其显示在屏幕上:

import tkinter as tk
root = tk.Tk()
root.mainloop()

当程序变得越来越复杂时,可以使用面向对象的编程方法使代码更有条理。

下面的程序实现与上面的程序相同的结果,但使用 aclass代替:

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()


if __name__ == "__main__":
    app = App()
    app.mainloop()

怎么运行的。

  • 首先,定义一个App类,继承该类tk.Tk。在方法内部__init__(),调用类__init__()的方法tk.Tk
  • 其次,创建该类的新实例App并调用该mainloop()方法来显示根窗口。

2.2 Tkinter 中面向对象窗口的另一个示例

下面的类表示一个由标签和按钮组成的窗口。当您单击该按钮时,程序会显示一个消息框:

import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo


class App(tk.Tk):
  def __init__(self):
    super().__init__()

    # configure the root window
    self.title('My Awesome App')
    self.geometry('300x50')

    # label
    self.label = ttk.Label(self, text='Hello, Tkinter!')
    self.label.pack()

    # button
    self.button = ttk.Button(self, text='Click Me')
    self.button['command'] = self.button_clicked
    self.button.pack()

  def button_clicked(self):
    showinfo(title='Information', message='Hello, Tkinter!')

if __name__ == "__main__":
  app = App()
  app.mainloop()

它的工作原理。

  • 首先,在__init__()App类的方法中创建一个标签和按钮。
  • 其次,将button_clicked()方法分配给按钮的命令选项。在该button_clicked()方法内,显示一个消息框。
  • 第三,将应用程序引导移至该if __name__ = "main"块。

2.3 小结

  • 使用面向对象的编程方法使代码更有条理。
  • 定义一个类,继承该类tk.Tk。始终super().__init__()在子类中从父类调用 。

三、关于Ttk的原理

        上面您学习了如何对类进行子类化。但是,一个 Tkinter 应用程序应该只有一个实例。 因此,从 ttk 继承是很常见的。Frame 类并在根窗口中使用子类。

ttk介绍: 是增强版的tk,其中有17个图形类,包括tk中的11个类:
Button, Checkbutton, Entry, Frame, Label, LabelFrame, Menubutton, PanedWindow, Radiobutton, Scale, Scrollbar
ttk新增的6个: Combobox, Notebook, Progressbar, Separator, Sizegrip, Treeview
这17个类都继承自 Widget。

3.2 ttk,Frame继承和实例化

        若要继承该类,请使用以下语法:ttk.Frame

class MainFrame(ttk.Frame):
    pass

        由于 Frame 需要一个容器,因此您需要向其 __init__() 方法添加一个参数,并调用 ttk.Frame 类的 __init__() 方法,如下所示:

class MainFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)  

        下面显示了具有标签和按钮的完整类。单击该按钮时,它会显示一个消息框:MainFrame

class MainFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        options = {'padx': 5, 'pady': 5}

        # label
        self.label = ttk.Label(self, text='Hello, Tkinter!')
        self.label.pack(**options)

        # button
        self.button = ttk.Button(self, text='Click Me')
        self.button['command'] = self.button_clicked
        self.button.pack(**options)

        # show the frame on the container
        self.pack(**options)

    def button_clicked(self):
        showinfo(title='Information',
                 message='Hello, Tkinter!')

        下面定义了一个继承自Tk类的类:App

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        # configure the root window
        self.title('My Awesome App')
        self.geometry('300x100')

        您可以通过块引导应用程序。if __name__ == "__main__"

if __name__ == "__main__":
    app = App()
    frame = MainFrame(app)
    app.mainloop()

在此代码中:

  • 首先,创建该类的新实例。App
  • 其次,创建类的新实例,并将其容器设置为应用实例。MainFrame
  • 第三,通过调用 app() 启动应用程序。它将执行将调用根窗口的方法。__call__()mainloop()

把它们放在一起:

import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo


class MainFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)

        options = {'padx': 5, 'pady': 5}

        # label
        self.label = ttk.Label(self, text='Hello, Tkinter!')
        self.label.pack(**options)

        # button
        self.button = ttk.Button(self, text='Click Me')
        self.button['command'] = self.button_clicked
        self.button.pack(**options)

        # show the frame on the container
        self.pack(**options)

    def button_clicked(self):
        showinfo(title='Information',
                 message='Hello, Tkinter!')


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        # configure the root window
        self.title('My Awesome App')
        self.geometry('300x100')


if __name__ == "__main__":
    app = App()
    frame = MainFrame(app)
    app.mainloop()

输出:

3.3 更多面向对象框架示例

        下面的示例使用这些类从“框架”教程转换“替换”窗口:

import tkinter as tk
from tkinter import ttk


class InputFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)
        # setup the grid layout manager
        self.columnconfigure(0, weight=1)
        self.columnconfigure(0, weight=3)

        self.__create_widgets()

    def __create_widgets(self):
        # Find what
        ttk.Label(self, text='Find what:').grid(column=0, row=0, sticky=tk.W)
        keyword = ttk.Entry(self, width=30)
        keyword.focus()
        keyword.grid(column=1, row=0, sticky=tk.W)

        # Replace with:
        ttk.Label(self, text='Replace with:').grid(
            column=0, row=1, sticky=tk.W)
        replacement = ttk.Entry(self, width=30)
        replacement.grid(column=1, row=1, sticky=tk.W)

        # Match Case checkbox
        match_case = tk.StringVar()
        match_case_check = ttk.Checkbutton(
            self,
            text='Match case',
            variable=match_case,
            command=lambda: print(match_case.get()))
        match_case_check.grid(column=0, row=2, sticky=tk.W)

        # Wrap Around checkbox
        wrap_around = tk.StringVar()
        wrap_around_check = ttk.Checkbutton(
            self,
            variable=wrap_around,
            text='Wrap around',
            command=lambda: print(wrap_around.get()))
        wrap_around_check.grid(column=0, row=3, sticky=tk.W)

        for widget in self.winfo_children():
            widget.grid(padx=0, pady=5)


class ButtonFrame(ttk.Frame):
    def __init__(self, container):
        super().__init__(container)
        # setup the grid layout manager
        self.columnconfigure(0, weight=1)

        self.__create_widgets()

    def __create_widgets(self):
        ttk.Button(self, text='Find Next').grid(column=0, row=0)
        ttk.Button(self, text='Replace').grid(column=0, row=1)
        ttk.Button(self, text='Replace All').grid(column=0, row=2)
        ttk.Button(self, text='Cancel').grid(column=0, row=3)

        for widget in self.winfo_children():
            widget.grid(padx=0, pady=3)


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Replace')
        self.geometry('400x150')
        self.resizable(0, 0)
        # windows only (remove the minimize/maximize button)
        self.attributes('-toolwindow', True)

        # layout on the root window
        self.columnconfigure(0, weight=4)
        self.columnconfigure(1, weight=1)

        self.__create_widgets()

    def __create_widgets(self):
        # create the input frame
        input_frame = InputFrame(self)
        input_frame.grid(column=0, row=0)

        # create the button frame
        button_frame = ButtonFrame(self)
        button_frame.grid(column=1, row=0)


if __name__ == "__main__":
    app = App()
    app.mainloop()

3.4 小结

  • 子类化并初始化框架上的小部件。ttk.Frame
  • 在根窗口中使用 的子类。ttk.Frame

四、总结

        本文阐述了如何在Tkinter上使用面向对象的编程方法,更多的和更需要掌握的是消息原理。在系列文章的下篇我们将集中阐述事件和绑定问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1275142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode-206-反转链表(C语言实现)

题目: 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例 3&…

TA-Lib学习研究笔记(八)——Momentum Indicators 上

TA-Lib学习研究笔记(八)——Momentum Indicators 上 Momentum Indicators 动量指标,是最重要的股票分析指标,能够通过数据量化分析价格、成交量,预测股票走势和强度,大部分指标都在股票软件中提供。 1. A…

Python函数专题(下)侯小啾python领航班系列(十三)】

Python函数专题(下)侯小啾python领航班系列(十三)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹…

不会代码(零基础)学语音开发(语音开发板)

语音开发板板载资源介绍 通过上图可以看到VDB-150S语音开发板应该是集目前上市的所有语音开发板中板载资源最为丰富的一款开发板。板载的主要资源有: 双色LED状态指示灯;两个测试时使用的按键开关;红外寻迹/接近传感器;固件烧录器…

初识Linux:权限

目录 提示:以下指令均在Xshell 7 中进行 Linux 的权限 内核: 查看操作系统版本 查看cpu信息 查看内存信息 外部程序: 用户: 普通用户变为超级用户: su 和 su-的区别: root用户变成普通用户&#…

管理员配置Jupterhub

在Ubuntu上演示如何部署R语言环境,包括 posit的已经编译了一些R的安装 系统已经装了R,我额外编译的R如何让大家都能用到 如何配置RStudio jupyterhub的配置和使用 管理员如何配置jupyterhub 用户如何配置自己的jupyter环境 Ubuntu上的R部署 这一次…

OSI七层模型与TCP/IP四层模型

一、OSI七层模型简述 OSI 模型的七层是什么?在 OSI 模型中如何进行通信?OSI 模型有哪些替代方案? TCP/IP 模型关于专有协议和模型的说明 二、七层模型详解(DNS、CDN、OSI) 状态码DNS nslookup命令 CDN whois命令 …

java商城系统选型技巧

近期有很多网友在知乎、百度上咨询如何选择java商城系统,本文我们介绍目前有哪些java商城系统,如何选择商城系统,希望有所帮助。 我们之前做过调研,目前java语言开发的商城系统主要有shop、javashop、ejavashop、远丰、mall4j、li…

【【FPGA 之 MicroBlaze定时器中断实验】】

FPGA 之 MicroBlaze定时器中断实验 AXI Timer 具有 AXI 总线接口,能够产生不同时间周期和占空比的时钟、脉冲产生电路、产生与时间有关的中断和用于电机控制的脉宽调制信号。 AXI Timer IP 核提供了一个 AXI4 Lite 接口用于与处理器通信;它内部有两个可…

美国站卖家请在今年12/28前更新W-8税务信息

美国税务信息采集指南 根据美国国家税务局的规定,非美国纳税人需要向亚马逊提供W-8BEN表格,以豁免美国报税要求。美国国家税务局W-8BEN表格将在卖家向亚马逊提供此表格三年后过期。收到提示时,海外卖家需要重新接受税务信息采集以提交新表格。…

探索APP自动化测试工具的重要作用是什么?

随着移动应用市场的蓬勃发展,保障应用程序的质量和性能成为开发团队至关重要的任务。在这个背景下,APP自动化测试工具崭露头角,成为提高开发效率、减少错误率的关键工具。本文将探讨APP自动化测试工具的用途,以及它们在移动应用开…

Qt开发 之 安装程序错误--安装进程(qt.tool.perl)的解决办法

文章目录 1、问题描述2、问题原因3、解决方案3.1、不关闭错误弹出窗口3.2、手动安装Perl3.3、安装Perl完成后,点击“ignore”继续安装 1、问题描述 Win11下,安装qt5.12.12时遇到“安装进程(qt.tools.perl)运行期间出现错误” 问题描述: Err…

C++-详解智能指针

目录 ​编辑 一.什么是智能指针 1.RAII 2.智能智能指针 二.为什么需要智能指针 1.内存泄漏 a. 什么是内存泄漏,内存泄漏的危害 b.内存泄漏分类 c.如何检测内存泄漏 d.如何避免内存泄漏 总结一下: 2.为什么需要智能指针以及智能指针的原理 三.智能指针的使用 1.C…

程序员养生之道:延寿不忘初心——延寿必备

文章目录 每日一句正能量前言如何养生饮食篇运动篇休息篇后记 每日一句正能量 现代社会已不是大鱼吃小鱼的年代,而是快鱼吃慢鱼的年代。 前言 在IT行业中,程序员是一个重要的职业群体。由于长时间的繁重编程工作,程序员们常常忽略了身体健康…

(Python) 字典dict的使用

a dict(namekl_pen, kl_target0.01, lam0.5) print(类型:, type(a)) print(数值:, a) print(name键的值:, a[name]) print(键:, a.keys()) print(值:, a.values())

知虾平台丨优化Shopee店铺运营,提升销售利润——了解知虾平台

在如今竞争激烈的电商市场中,Shopee作为一家快速发展的平台,吸引了众多卖家加入。然而,要在Shopee上取得成功并实现可观的销售利润,并不是一件容易的事情。为了帮助卖家更好地了解市场趋势、优化商品关键词、监控竞争对手等&#…

Java中的异常你了解多少?

目录 一.认识异常二.异常分类三.异常的分类1.编译时异常2.运行时异常 四.异常的处理1.LYBL:事前防御型2.EAFP:事后认错型 五.异常的抛出Throw注意事项 六.异常的捕获1.异常的捕获2.异常声明throws3.try-catch捕获并处理 七.自定义异常 一.认识异常 在Jav…

MySQL实现(免密登录)

简介: MySQL免密登录是一种允许用户在没有输入密码的情况下直接登录到MySQL服务器的配置。这通常是通过在登录时跳过密码验证来实现的。 1、修改MySQL的配置文件 使用vi /etc/my.cnf,添加到【mysqld】后面 skip-grant-tables #配置项告诉mysql跳过权限验证&#…

避免客户开发信被限制的方法与策略

开发信是外贸或者出海企业常用的一种开发客户的方式。相较于其他的获客方式,开发信能够更加精准地投放到客户中,并且只需承担较低的成本。但是,由于一些限制管制要求,外贸人员可能会遇到开发新被限制的情况。今天,小编…

元宇宙时代CSGO游戏装备市场如何迎合年轻人的需求?

元宇宙时代游戏装备市场如何迎合年轻人的需求?游戏装备市场的主要消费者是年轻人,他们对于游戏装备有着自己的需求和偏好。 为了迎合年轻人的需求,游戏装备需要具备以下几个特点: 1、个性化。年轻人喜欢表达自己的个性和风格&am…