0
点赞
收藏
分享

微信扫一扫

算法通关村——用4kb寻找重复元素

大明宫 2023-12-05 阅读 31

一、说明

        在本教程中,您将学习如何在 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 类并在根窗口中使用子类。

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上使用面向对象的编程方法,更多的和更需要掌握的是消息原理。在系列文章的下篇我们将集中阐述事件和绑定问题。

举报

相关推荐

0 条评论