子类化Tkinter以创建自定义Widget [英] Subclassing Tkinter to create a custom Widget

查看:431
本文介绍了子类化Tkinter以创建自定义Widget的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅以下代码:(我基本上尝试使用垂直滚动条创建一个文本小部件,同时保留我班级中Tkinter.Text的所有方法/函数)

please see the following code: (I am basically trying to create a text widget with a vertical scrollbar while retaining all the methods / functions from Tkinter.Text in my class)

class ScrollableTextWidget(Tkinter.Text):
    def __init__(self, parent):
        self.parent = parent
        self.Frame = ttk.Frame(self.parent)
        Tkinter.Text.__init__(self, self.Frame, width=1, height=1)
        self.__initWidget()

    def __initWidget(self):
        self.Frame.grid(sticky="NSEW")
        self.ScrollbarY = ttk.Scrollbar(self.Frame, orient="vertical", command=self.yview)
        self.configure(yscrollcommand=self.ScrollbarY.set)
        self.grid(column=0, row=0, sticky="NSEW")
        self.ScrollbarY.grid(column=1, row=0, sticky="NS")
        self.Frame.columnconfigure(0, weight=1)
        self.Frame.rowconfigure(0, weight=1)

创建我的cus是否可以这样的tom小部件还是我应该把它放在一个框架中并编写我自己的方法?

Is it ok to create my custom widget like this or should I rather put it in a frame and write my own methods?

推荐答案

子类化是非常正常的用于创建自定义窗口小部件但是,如果此自定义窗口小部件由多个窗口小部件组成,则通常会将 Frame 子类化。例如,要创建一个带有滚动条的文本小部件的小部件,我会这样做:

It's very normal to subclass a widget to create a custom one. However, if this custom widget is made up of more than one widget, you would normally subclass Frame. For example, to create a widget that is a text widget with a scrollbar I would do something like this:

import Tkinter as tk

class ScrolledText(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent)
        self.text = tk.Text(self, *args, **kwargs)
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)
        self.text.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")
        self.text.pack(side="left", fill="both", expand=True)

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.scrolled_text = ScrolledText(self)
        self.scrolled_text.pack(side="top", fill="both", expand=True)
        with open(__file__, "r") as f:
            self.scrolled_text.text.insert("1.0", f.read())

root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()

使用这种方法,请注意在插入文本时如何引用内部文本小部件。如果您希望此窗口小部件看起来更像真实文本窗口小部件,则可以创建到部分或全部文本窗口小部件功能的映射。例如:

With this approach, notice how you need to reference the inner text widget when inserting text. If you want this widget to look more like a real text widget, you can create a mapping to some or all of the text widget functions. For example:

import Tkinter as tk

class ScrolledText(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent)
        self.text = tk.Text(self, *args, **kwargs)
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)
        self.text.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")
        self.text.pack(side="left", fill="both", expand=True)

        # expose some text methods as methods on this object
        self.insert = self.text.insert
        self.delete = self.text.delete
        self.mark_set = self.text.mark_set
        self.get = self.text.get
        self.index = self.text.index
        self.search = self.text.search

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.scrolled_text = ScrolledText(self)
        self.scrolled_text.pack(side="top", fill="both", expand=True)
        with open(__file__, "r") as f:
            self.scrolled_text.insert("1.0", f.read())

root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()

这篇关于子类化Tkinter以创建自定义Widget的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆