ZenLinux
ZenLinux

Reputation: 23

Tkinter class method and accessing class members

In the attempt to make an editor with composite tkinter widgets I have stumbled upon an error or a bug? The methods defined in the MyTextWidget class : fl() and fh() are to set the font size of the text widget belonging to the same class.

My understanding is that this should work, but when I have three instances of the same MyTextWidget class on a canvas using create_window() method, upon pressing the fl button and fh button, the text size in all three textwidgets changes simulataneously. I first tested it with one widget, when everything was working to my satisfaction, I added two more instances of the same class, but now it is not working as I expected it.

If this helps, the version is Python 2.7 and Tkinter version is Revision: 81008, debian linux.

Your help is appreciated, especially if you can guide me to a book or document that helps with the relevant information. Kindly enlighten.

import Tkinter as tk
import tkFont

class MyTextWidget(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent)


        self.text = tk.Text(self, *args, **kwargs)
        self.tbar = tk.Frame(self, *args, **kwargs)
        self.tbar.pack(side=tk.TOP, padx=2, pady=2, fill="x", expand=True)
        self.fl = tk.Button(self.tbar)
        self.fl.pack(side=tk.LEFT, padx=2, pady=2)
        self.fh = tk.Button(self.tbar, *args, **kwargs)
        self.fh.pack(side=tk.LEFT, padx=2, pady=2)
        def fl():
            print "fl called"
            self.text.configure(font=tkFont.Font(family="mytsmc", size=7), spacing1=2,spacing2=22,spacing3=2)
        def fh():
            print "fh called"
            self.text.configure(font=tkFont.Font(family="mytsmc", size=9), spacing1=2,spacing2=22,spacing3=2)

        self.fl.config(text="fl", width=1, command=fl)
        self.fh.config(text="fh", width=1, command=fh)

        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)
        self.text.configure(yscrollcommand=self.vsb.set,
                            font=tkFont.Font(family="mytsmc", size=8),
                            spacing1=2,spacing2=32,spacing3=2)
        self.vsb.pack(side="right", fill="y")
        # self.text.pack(side="left", fill="both", expand=True)
        self.text.pack(side="left", fill="both", expand=False)

        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 myEditor(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.w = tk.Canvas(self, width=1320,
                 height=740,
                 borderwidth=1,
                 background='white',
                 relief='raised')
        self.w.pack(anchor='center')
        #One
        self.scrolled_text1 = MyTextWidget(self)
        self.firstwidget = self.w.create_window(10, 10,
                                                anchor=tk.NW,
                                                width=400,
                                                height=400,
                                                window=self.scrolled_text1)
        with open("/home/username/datafiles/1.txt", "r") as f:
            self.scrolled_text1.insert("1.0", f.read())
        #Two
        self.scrolled_text2 = MyTextWidget(self)
        self.firstwidget = self.w.create_window(420, 10,
                                                anchor=tk.NW,
                                                width=400,
                                                height=400,
                                                window=self.scrolled_text2)
        with open("/home/username/datafiles/2.txt", "r") as f:
            self.scrolled_text2.insert("1.0", f.read())
        #Three
        self.scrolled_text3 = MyTextWidget(self)
        self.firstwidget = self.w.create_window(830, 10,
                                                anchor=tk.NW,
                                                width=400,
                                                height=400,
                                                window=self.scrolled_text3)
        with open("/home/username/datafiles/3.txt", "r") as f:
            self.scrolled_text3.insert("1.0", f.read())

        def switchtob(event=None):
            self.scrolled_text1.text.focus()
            print "switched to b"
        def switchton(event=None):
            self.scrolled_text2.text.focus()
            print "switched to n"
        def switchtom(event=None):
            self.scrolled_text3.text.focus()
            print "switched to m"
        root.bind('<Control-b>',switchtob)
        root.bind('<Control-n>',switchton)
        root.bind('<Control-m>',switchtom)

root = tk.Tk()
myEditor(root).pack(side="top", fill="both", expand=True)
def exit(event=None):
    quit()
root.bind('<Control-q>',exit)

root.mainloop()

Upvotes: 2

Views: 293

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386362

The simple fix is to create the fonts once, save a reference to them, and then use them instead of instantiating new fonts every time you click the button.

class MyTextWidget(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        ...
        self.font1 = tkFont.Font(family="mytsmc", size=7)
        self.font2 = tkFont.Font(family="mytsmc", size=9)
        ...
        def fl():
            self.text.configure(font=self.font1, spacing1=2,spacing2=22,spacing3=2)
        def fh():
            self.text.configure(font=self.font2, spacing1=2,spacing2=22,spacing3=2)

Upvotes: 1

Related Questions