Search code examples
python-2.7user-interfacetkinterttk

Backporting Python 3 tkinter & ttk code to Python 2.7


I'm following a Sentdex tutorial, found here, specifically this part about creating a GUI in Python. However the tutorial is in python 3 and I'm using 2.7.

Importing Tkinter is fine, however when I come to importing ttk and then inheriting it into the class, a problem arises. In python 2.7 ttk is a separate module, which means is not in the Tkinter module.

import Tkinter as tk
import ttk

LARGE_FONT= ("Verdana", 12)


class SeaOfBTCApp(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "Seal of BTC")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (StartPage, PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

The problem appears to be when the classes inherit Tk, when I do:

button = ttk.Button(self, text="Visit Page 1",
                    command=lambda: controller.show_frame(PageOne))

It doesn't use ttk, the buttons still look the same (like when it was tk.Button). How can I make the buttons look like the ttk buttons.

Full code:

import Tkinter as tk
from ttk import *


LARGE_FONT= ("Verdana", 12)


class SeaOfBTC(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "Sea of BTC")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (StartPage, PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()


 class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        label = tk.Label(self, text="Start Page", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        button = ttk.Button(self, text="Visit Page 1",
                        command=lambda: controller.show_frame(PageOne))
        button.pack()

        button2 = ttk.Button(self, text="Visit Page 2",
                        command=lambda: controller.show_frame(PageTwo))
        button2.pack()


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Page One!!!", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        button1 = ttk.Button(self, text="Back to Home",
                        command=lambda: controller.show_frame(StartPage))
        button1.pack()

        button2 = ttk.Button(self, text="Page Two",
                        command=lambda: controller.show_frame(PageTwo))
        button2.pack()


class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Page Two!!!", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        button1 = ttk.Button(self, text="Back to Home",
                        command=lambda: controller.show_frame(StartPage))
        button1.pack()

        button2 = ttk.Button(self, text="Page One",
                        command=lambda: controller.show_frame(PageOne))
        button2.pack()


app = SeaOfBTC()
app.mainloop()

Solution

  • If you use ttk.Button, it absolutely will use the ttk button. It can't possibly do anything else because you're explicitly saying to use the Button class from the ttk module.

    Note: Depending on what platform you're on, the tk and ttk buttons may look identical.

    Other than the way you do the imports, there's virtually no difference between tkinter in python 2.x and 3.x.