Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3+ Tkinter Center Label Text

This is a tkinter question for Python 3+ on Windows OS. So I know how to center Label text (justify=CENTER) and I know from everything I've searched for the Label text by default is justified center.

Can someone look at my code below and please tell me what I'm doing wrong. I've searched online for hours about this and I just can't see what I'm incorrectly doing.

from tkinter import *
from tkinter.ttk import *


class MainApplication():

    def __init__(self, master):
        self.master = master
        self.master.title("OOP GUI Example")
        self.master.iconbitmap("Blank.ico")


        label = Label(self.master, text="Test Callback", )
        greet_button = Button(self.master, width=25, text="Greet", command=self.greet)
        close_button = Button(self.master, width=25, text="Close", command=self.close)

        Grid.columnconfigure(self.master, 0, weight=1)
        Grid.rowconfigure(self.master, (0,1,2), weight=1)

        label.grid(row=0, column=0, sticky="NSWE",padx=(10, 10), pady=(7.5, 0))
        greet_button.grid(row=1, column=0, sticky="NSWE", padx=(10, 10), pady=(10, 1.5))
        close_button.grid(row=2, column=0, sticky="NSWE", padx=(10, 10), pady=(1.5, 10))


    def greet(self):
        print("Greetings!")
        return


    def close(self):
        self.master.quit()
        return


root = Tk()
root.style = Style()
#  ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
root.style.theme_use("clam")
gui = MainApplication(root)
root.mainloop()

This line here label.grid(row=0, column=0, sticky="NSWE",padx=(10, 10), pady=(7.5, 0)) is making the text left justified. Particularly sticky="NSWE" but I want this here so the label widget resizes with the window, so I'm stuck.

like image 516
probat Avatar asked Jan 17 '18 17:01

probat


2 Answers

The problem is that you are reading the documentation for the tkinter label but you are using a ttk label. This is why you should not use wildcard imports -- when two modules export objects with the same name (eg: tkinter.Label and ttk.Label) it becomes difficult to know which one is being used in your code. The default for a ttk label is to be aligned left, but the tkinter label is aligned center, and the order of your imports means that you're using a ttk Label.

The quick fix for your example is to explicitly set the anchor option for the ttk label (eg: label.configure(anchor="center")).

You should also fix your imports so that this problem doesn't happen to you again. Instead of doing a wildcard import (eg: from tkinter import *) you should explicitly import the module as a unit, optionally with a shorter name. Once you do that, you need to prefix your widgets with the name of the module.

For example, given these import statements:

import tkinter as tk
from tkinter import ttk

... you would then create a ttk label with ttk.Label(...), and a tkinter label with tk.Label(...) which makes your code much easier to understand, and it removes all ambiguity.

like image 95
Bryan Oakley Avatar answered Oct 12 '22 23:10

Bryan Oakley


This is a textbook example of namespace clustering. You're clustering python's namespace, with the lines:

from tkinter import *
from tkinter.ttk import *

this means if there's a tkinter.ttk class that has the same name that of tkinter class, ttk one will be used, such as Button and Label. And apparently ttk not necessarily have the tkinter.Label's justify option. A simple position swap is sufficed to demonstrate the difference swap the imports to:

from tkinter.ttk import *
from tkinter import *

Instead and see what happens.


See below example with center justified text where no namespaces are clustered, using tkinter.Label as label:

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()

label = tk.Label(root, text="Test Callback")
btn = tk.Button(root, text="Text so long that root has to resize.")
btn.pack()
label.pack(fill='both', expand=True)

root.mainloop()

See below example center justified text where no namespaces are clustered, using tkinter.ttk.Label as label:

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()

label = ttk.Label(root, text="Test Callback")
btn = tk.Button(root, text="Text so long that root has to resize.")
btn.pack()
label.pack(expand=True)

root.mainloop()
like image 35
Nae Avatar answered Oct 13 '22 01:10

Nae