get rid of blank space around widgets in tkinter - python

I put widgets on a window with .grid and noticed that the widgets have space around them. I fixed that on canvas widget with highlightthickness but this doesn't work with button widgets. It doesn't look cool when you have grey window background and there's white space around buttons.
P.S. I use python3 on macos Sierra
root = Tk()
root.configure(bg='grey')
w = Canvas(root, width=150, height=150, highlightthickness=0)
w.grid(row=1, column=1, sticky="nsew")
clear_btn = Button(text="Clear", width=15, command=lambda: w.delete("all"))
clear_btn.grid(row=2, column=1)
root.mainloop()
P.S. TKinter leaving borders around widgets that's what it looks like. The guy was advised to use highlightbackground, but when I screenshot widgets, I still have that blank space around the widget.

To get the button to fill the entire space of the grid box it occupies, try setting the sticky argument of the grid() function to "NSEW":
from tkinter import *
root = Tk()
root.configure(bg = "grey")
w = Canvas(root, width = 150, height = 150, highlightthickness = 0)
w.grid(row = 1, column = 1, sticky = "NSEW")
clear_btn = Button(text = "Clear", width = 15, command = lambda: w.delete("all"))
clear_btn.grid(row = 2, column = 1, sticky = "NSEW")
root.mainloop()
Before:
After:
Note: The appearance of these windows may vary slightly between operating systems and even between different visual themes on the same operating system.

I don't have OSX, so I cannot check, but I think that if you use ttk and a style different from the default one (like 'clam'), you might be able to configure things like you want.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.configure(bg='grey')
style = ttk.Style(root)
style.theme_use('clam')
w = tk.Canvas(root, width=150, height=150, highlightthickness=0)
w.grid(row=1, column=1, sticky="nsew")
clear_btn = ttk.Button(text="Clear", width=15, command=lambda: w.delete("all"))
clear_btn.grid(row=2, column=1)
root.mainloop()

Related

Tkinter Python - How to delete blank in label

I have an issue with a label on tkinter. I would like to know if it's possible to "occupy space", when I insert long text my label become huge and I have a lot of blank around my text. Is it possible to delete this blank ?
action=customtkinter.CTkLabel(master=frame_right, width=400, height=150, text="", justify=tkinter.LEFT, text_font=("Roboto Medium", -10), fg_color="white")
action.grid(row=4, column=2, padx=15, pady=15, sticky='')
Label from custom tkinter
Here the code to reproduct what happen :
import customtkinter
from tkinter import *
class App(customtkinter.CTk):
WIDTH = 850
HEIGHT = 620
app = customtkinter.CTk() # create CTk window like you do with the Tk window (you can also use normal tkinter.Tk window)
app.geometry(f"{App.WIDTH}x{App.HEIGHT}")#taille de la fenetre graphique
app.grid_rowconfigure(0, weight=1)
app.grid_columnconfigure(1, weight=1)
frame_right = customtkinter.CTkFrame(master=app)
frame_right.grid(row=0, column=1, sticky="nswe", padx=20, pady=20)
# configure grid layout (3x7)
frame_right.rowconfigure((0, 1, 2, 3), weight=1)
frame_right.rowconfigure(7, weight=10)
frame_right.columnconfigure((0, 1), weight=1)
frame_right.columnconfigure(2, weight=0)
action=customtkinter.CTkLabel(master=frame_right, width=400, height=150, text="", justify="center", text_font=("Roboto Medium", -10), fg_color="white")
action.grid(row=4, column=2, padx=15, pady=15, sticky="n")
action.configure(text="CustomTkinter is a python UI-library based on Tkinter, which provides new, modern and fully customizable widgets.\nThey are created and used like normal Tkinter widgets and can also be used in combination with normal Tkinter")
app.mainloop()
You've given an explicit width and height to the label, so tkinter is trying to honor that size. Since your text doesn't fill the space, the extra space is going to appear blank.
If you remove width=400, height=150, from where you create the label, the label will be just big enough to fit the text.
The following screenshot shows what I get when I remove the explicit width and height:
I finally resolved my problem, I replaced this
frame_right.columnconfigure((0, 1), weight=1)
frame_right.columnconfigure(2, weight=0)
by this :
frame_right.grid_columnconfigure(0, weight=1)
frame_right.grid_columnconfigure(1, weight=10)

Python - Tkinter button size changes when chaging the size of its font

I want to change the fontsize in a Tkinter button. But the button size changes along with it.
I even tried to limit the height and width of the button but nothing seems to work,
This is the code:
from tkinter import *
root = Tk()
root.geometry("500x300")
root.resizable(False, False)
button = Button(root, text="Ihsan", bg="Black", fg="white",
activeforeground="white", activebackground="grey", width=15, height=3,
font=("ariel", "43"))
button.place(x=350, y=20)
root.mainloop()
I get a window with a huge button. Please help
Width and height of the button in letters (if displaying text) or pixels (if displaying an image).
Here's one way to go, by using size of image to limit size of button when font size changed. Not sure if it is best one.
import tkinter as tk
from PIL import Image, ImageTk
def new_font():
global setting
setting = 1 - setting
font = f"ariel {32 if setting else 16}"
button.configure(font=font)
setting = 0
root = tk.Tk()
im = Image.new("RGB", (200, 200))
photo = ImageTk.PhotoImage(im)
root.geometry("300x300")
root.resizable(False, False)
button = tk.Button(
root,
text="Ihsan",
bg="Black",
fg="white",
activeforeground="white",
activebackground="grey",
width=200,
height=200,
font=("ariel", "16"),
image=photo,
compound='center')
button.place(x=30, y=20)
size = tk.Button(root, text="Size", command=new_font)
size.place(x=30, y=250)
root.mainloop()
The width and height is what is giving you the large button. Height in this case means 3 fontsize high.
Default is that it only enclose the text.
Margins you provide with pad, either in the widget itself, or when you pack it.
Using place is a bit uncommon and has its specific usecases, it does not look like you need it. The pack geometry manager can be used instead.
from tkinter import *
root = Tk()
root.geometry("500x300")
root.resizable(False, False)
button = Button(root, text="Ihsan", bg="Black", fg="white",
activeforeground="white", activebackground="grey",# width=15, height=3,
font=("ariel", "43"))
#button.place(x=350, y=20)
button.pack(side=RIGHT)
root.mainloop()

Why is a Tkinter frame not showing all three buttons unless gui is dragged into wider/bigger size

I have a gui which is not showing the buttons the way I would like. The frame is being cropped unless the gui is stretched.
Like this, where finally I see the three buttons desired:
I want to have the frame with the buttons (frame2) always show the three buttons and maintain the same size irregardless of the size the gui is enlarged to. Any idea of where I am going wrong?
Code
import tkinter as tk
import tkinter
from tkinter import ttk
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
#=====================================================================
# ROOT FIGURE FOR GUI
#=====================================================================
root = tk.Tk()
root.title("Tab Widget")
root.geometry("600x450")
tabControl = ttk.Notebook(root)
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tabControl.add(tab1, text ='Circle Cal')
tabControl.add(tab2, text ='OPW')
tk.Grid.rowconfigure(root, 0, weight=1)
tk.Grid.columnconfigure(root, 0, weight=1)
tabControl.grid(column=0, row=0, sticky=tk.E+tk.W+tk.N+tk.S)
#MAKE A FIGURE OBJECT
my_figure1 = Figure(figsize = (4, 4), dpi = 100)
#MAKE A FRAME WIDGET
frame1 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
frame1.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
#create another frame(frame2)
frame2 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
frame2.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.BOTH)
#MAKE A CANVAS OBJECT
my_canvas1 = FigureCanvasTkAgg(my_figure1, master = frame1) # creating the Tkinter canvas containing the Matplotlib figure
# TURN THE CANVAS OBJECT INTO A CANVAS WIDGET
my_canvas1.get_tk_widget().pack(side = tkinter.TOP, fill = tkinter.BOTH, expand = 1) # placing the canvas on the Tkinter window
my_canvas1.draw()
def plotData():
pass
def clearPlot():
pass
# MAKE BUTTON TO PLOT GRAPH
button1 = tk.Button(frame2, text = "Plot", command = plotData, relief = tk.GROOVE, padx =20, pady =20 )
button1.grid(row = 0, column = 0)
# MAKE BUTTON TO CLEAR PLOT
button2 = tk.Button(frame2, text = "Clear", command = clearPlot, relief = tk.GROOVE, padx =20, pady =20 )
button2.grid(row = 0, column = 1)
# MAKE BUTTON TO close
button2 = tk.Button(frame2, text = "Close", command = clearPlot, relief = tk.GROOVE, padx =20, pady =20 )
button2.grid(row = 0, column = 2)
root.mainloop()
The answer is simply that there isn't enough room for the buttons. You're forcing the size of the window to be a specific width and the width is just too small.
When you force a window to be a specific size, pack will need to shrink one or more widgets to make all of the widgets fit. It does this in the reverse order that the widgets were added with pack.
Since you want the canvas to be the widget that grows and shrinks, you need to pack the frame that contains it last. So, call pack on frame2 before calling pack on frame1.
This is easiest if you group your calls to pack together rather than interlacing them with widget creation.
frame2.pack(side=tk.RIGHT, anchor=tk.E, fill=tk.BOTH)
frame1.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
Have you tried removing
root = tk.Tk()
root.title("Tab Widget")
#root.geometry("600x450")
the geometry manager

Tkinter button distance from window edges

Is there a way using Tkinter to have buttons so that they are always placed a certain number of pixels from the edge of the window, even when the window is resized? I've tried using anchors but that didn't seem to move the placement in the window that much.
You can anchor buttons or any other widget to the sides of a window by starting with a Frame, and configuring its rows and columns to have a weight of 1 in order for it to fill the parent window.
import Tkinter as tk
import ttk
root = tk.Tk()
frame = ttk.Frame(root)
frame.pack(fill=tk.BOTH, expand=True)
frame.columnconfigure(index=0, weight=1)
frame.columnconfigure(index=2, weight=1)
frame.rowconfigure(index=0, weight=1)
frame.rowconfigure(index=2, weight=1)
Then, for each button you want to use sticky to anchor it to the respective side, and use padx or pady to add some padding (in pixels) between the button and the window.
top_padding = 5
top = ttk.Button(frame, text="Top")
top.grid(row=0, column=1, sticky=tk.N, pady=(top_padding, 0))
left_padding = 5
left = ttk.Button(frame, text="Left")
left.grid(row=1, column=0, sticky=tk.W, padx=(left_padding, 0))
right_padding = 5
right = ttk.Button(frame, text="Right")
right.grid(row=1, column=2, sticky=tk.E, padx=(0, right_padding))
bottom_padding = 5
bottom = ttk.Button(frame, text="Bottom")
bottom.grid(row=2, column=1, sticky=tk.S, pady=(0, bottom_padding))
root.mainloop()
have you tried using the padx function?
it works like this:
button=Button(place,text="something something", padx=10)
it provides with extra horizontal padding between widgets, aditionally, you could use frames with padx and an anchor so the text is fixated to a position

Placing tkinter widgets in foreground

I cannot achieve to create a Textbox (using tkinter's Text widget) which is in the background and having a Canvas item (e.g. an oval) over it (foregroud) :
import Tkinter as Tk
root = Tk.Tk()
c = Tk.Canvas(root, width=400, height=400, bg='white')
o = c.create_oval(10, 10, 390, 390, fill='red')
c.grid(row=0, column=0, columnspan=2, padx=5, pady=5)
t = Tk.Text(c)
t.place(x=10,y=10)
c.tag_lower(t)
c.tag_raise(o)
root.mainloop()
Even if I use c.tag_lower(t), c.tag_raise(o), it doesn't work. Do you know how to solve this problem ?
This is documented behavior. You cannot draw over other widgets that are embedded in a canvas. There is no workaround. To be able to draw on top of text, your only option is to draw the text using create_text.

Categories