One of my canvases doesn't show in the Tkinter window (Python) - python

I'm trying to make a Tkinter window with two canvases: one for inputs, one for results.
The reason for that is that I couldn't find a way to clear just the results when the next input comes in so if there's a way to do that, that would also solve my problem, but I didn't find a way to solve that.
The issue is that the second canvas won't show up on the window. I've tried putting something on it right away, but it still didn't work. Also when searching for a solution, I found a code that I tried for myself and then it worked.
Here's the code:
root = tk.Tk() #I used import tkinter as tk
canvas = tk.Canvas(root, width = 400, height = 200)
canvas.pack(side='top', anchor='nw', fill='x')
canvas2 = tk.Canvas(root, width = 400, height = 600)
canvas.pack(side='top', anchor='nw', fill='both')

You typed canvas.pack(side='top', anchor='nw', fill='both') instead of canvas2.pack(side='top', anchor='nw', fill='both'). Here is the corrected code:
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=200, bg="red")
canvas.pack(side='top', anchor='nw', fill='x')
canvas2 = tk.Canvas(root, width=400, height=600, bg="blue")
canvas2.pack(side='top', anchor='nw', fill='both')
root.mainloop()

Related

How can I hide the image in Tkinter Python

I want to hide the image in Tkinter Python module. How can I do it?
For example:
from tkinter import *
root = Tk()
root.title("Example")
root.geometry("500x500")
root.resizable(0, 0)
def hide():
# How can I hide the image?
canvas = Canvas(root, width=500, height=500)
canvas.pack()
image = PhotoImage(file='example.png')
img = canvas.create_image(0, 0, anchor=NW, image=image)
hide = Button(root, text="Hide", command=hide)
hide = canvas.create_window(0, 30, anchor=NW, window=hide)
root.mainloop()
I try the [image].destory(), but it's not working.
If you want to remove a canvas object from a canvas, you can use the delete method of the canvas. It takes as a parameter the id of the object to be deleted:
canvas.delete(img)

Tkinter - uneven frames overlapping

Could someone please confirm if there is any possibility to create Tkinter frames with uneven dimensions overlapping, and then by using Tkinter raise function, I would like to display whichever frames is required to me, but for some reason, I couldn't find an option to do this, any suggestions/advises are much appreciated.
Something like the below in the image, yellow, green & red like to be 3 different frames
Thank you in advance..!!
Yes, this is possible, though not with transparency in the frames. If you don't really need frames and just need rectangles, this answer shows how to get transparency with images on a canvas.
Your post is unclear as to exactly what you expect, but here's an example that uses place to arrange the frames like in your picture. If you run the code, you can click on a frame to raise it to the top.
import tkinter as tk
root = tk.Tk()
root.geometry("800x800")
yellow_frame = tk.Frame(root, width=800, height=300, background="yellow", bd=8, relief="solid")
green_frame = tk.Frame(root, width=800, height=300, background="green", bd=8, relief="solid")
red_frame = tk.Frame(root, width=200, height=800, background="red", bd=8, relief="solid")
yellow_frame.place(x=0, y=0, anchor="nw")
green_frame.place(x=0, y=300, anchor="nw")
red_frame.place(x=500, y=0, anchor="nw")
for frame in (yellow_frame, green_frame, red_frame):
frame.bind("<1>", lambda event: event.widget.lift())
root.mainloop()

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()

get rid of blank space around widgets in tkinter

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()

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