Tkinter - uneven frames overlapping - python

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

Related

What is the proper way to set the size of a canvas in Tkinter?

I'm trying to build a simple GUI in Tkinter and I'm having trouble with placing a frame and a canvas beside each other. The canvas seems to take up more space than the width and height that have been specified.
Example code:
root = tk.Tk()
parent = tk.Frame(root)
parent.grid()
parent.master.geometry('400x400')
canvas = tk.Canvas(parent, width=200, height=400, relief='raised', borderwidth=5)
canvas.grid(row=0, column=0, sticky='nsew')
frame = tk.Frame(parent, width=200, height=400, relief='raised', borderwidth=5)
frame.grid(row=0, column=1, sticky='nsew')
parent.mainloop()
This gives this result:
You can see that the canvas has pushed the frame outside the window
However, when its just the frame, the frame fits nicely within the window:
When it's just the canvas the canvas pushes outside the window:
What is causing this difference in sizing and how do I handle it? Is there a proper way to set the size of a canvas?
In addition to the width parameter, there are two other parameters that control the width of a canvas: borderwidth and highlightthickness. Both of those may have non-zero default values, depending on your platform.
In addition, the geometry manager may also contribute to the width and height depending on options and other factors.
To get a canvas that is precisely 200 pixels wide and 400 pixels tall, set the other values to zero, and don't use geometry manager options that may restrict or expand the size of the widget.
canvas = tk.Canvas(root, width=200, height=400, borderwidth=0, highlilghtthickness=0)

One of my canvases doesn't show in the Tkinter window (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()

Scrollbar in Tkinter

I tried many things to do 2 things :
center my content (horizontal)
have a scrollbar right and bottom
Here my code :
# encoding: utf8
from tkinter import *
from tkinter import ttk
class Program:
def __init__(self):
# Tk.__init__(self)
# Fill the content of the window
self.window = Tk()
self.window.geometry("1080x720")
self.createFrameWithScrollbar()
self.content()
def createFrameWithScrollbar(self):
# Create a Main Frame
self.mainFrame = Frame(self.window)
self.mainFrame.pack(fill=BOTH, expand=True)
# Create a canvas
self.canvas = Canvas(self.mainFrame)
self.canvas.pack(side=LEFT, fill=BOTH, expand=True)
# Add a scrobar
yScrollbar = ttk.Scrollbar(self.mainFrame, orient=VERTICAL, command=self.canvas.yview)
yScrollbar.pack(side=RIGHT, fill=Y)
xScrollbar = ttk.Scrollbar(self.mainFrame, orient=HORIZONTAL, command=self.canvas.xview)
xScrollbar.pack(side=BOTTOM, fill=X)
# Configure the canvas
self.canvas.configure(yscrollcommand=yScrollbar.set)
self.canvas.configure(xscrollcommand=xScrollbar.set)
self.canvas.bind('<Configure>', lambda e: self.canvas.configure(scrollregion = self.canvas.bbox("all")))
self.frame = Frame(self.canvas)
self.canvas.create_window((0,0), window=self.frame, anchor="nw")
self.currentFrame = Frame(self.frame)
self.currentFrame.configure(bg="red")
self.currentFrame.pack(fill=BOTH, expand=1)
def content(self):
label_title = Label(self.currentFrame, text="Title")
label_title.grid(column=0, row=0, sticky=NSEW)
label_description = Label(self.currentFrame, text="Title")
label_description.grid(column=0, row=1, sticky=NSEW)
label_version = Label(self.currentFrame, text="0.2 beta [Novembre 2020]")
label_version.grid(column=0, row=2, sticky=NSEW)
# Lauch the program
app = Program()
app.window.mainloop()
So the result is the following :
So any suggestion ?
The bottom sidebar is so small ! I don't know why.
Are regarding the text, it's not center at all ;(
I want to have it center and changing position if I rezize the window
Thanks a lot
pack works by allocating space along an entire empty side of the master, so the order of when you call pack matters. When you pack the canvas before packing the scrollbar, the canvas takes up the entire left side from top to bottom.
The simple solution is to pack the scrollbars before you pack the canvas.
yScrollbar.pack(side=RIGHT, fill=Y)
xScrollbar.pack(side=BOTTOM, fill=X)
self.canvas.pack(side=LEFT, fill=BOTH, expand=True)
To make the UI look a bit more professional, grid is usually a better choice when laying out scrollbars. With pack, either one edge of the horizontal scrollbar will be below the vertical scrollbar, or the edge of the vertical scrollbar will be directly beside the horizontal one. That, or you have to add a little bit of padding so the scrollbars don't seem to overlap.
When I have a scrollable widget, I almost always put it and the one or two scrollbars together in a frame using grid. Then, I can treat them all as if they were a single widget when adding them to the rest of the UI.
In a comment you ask about how to do it in a grid. You simply need to place the widgets in the appropriate rows and columns, and make sure that the row and column with the scrollable widget has a non-zero weight so any extra space is allocated to it.
self.mainFrame.grid_rowconfigure(0, weight=1)
self.mainFrame.grid_columnconfigure(0, weight=1)
yScrollbar.grid(row=0, column=1, sticky="ns")
xScrollbar.grid(row=1, column=0, sticky="ew")
self.canvas.grid(row=0, column=0, sticky="nsew")

python tkinter canvas size using scrollbar

Edited: I want the size of canvas1 to be adjusted using scrollbar. When I run this, only canvas1 is visible no place left on frame for canvas2. I want canvas1's size on the frame to be somewhere near 300*400 and when I scroll it to visualize the whole frame (1000*800)
I want to construct a frame with two canvas. but the problem is that i dont know how to fit first canvas within the scrollbar. In the following code the size of canvas is huge because of that the second canvas is not displayed in the frame. What i want is to fix the size of first canvas within the scrollbar. Am new to tkinter so have no idea how to do that
i will really appreciate your help
root=Tk()
master=Frame(root,width=300,height=300)
master.grid(row=0,column=0)
xscrollbar = Scrollbar(master, orient=HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=E+W)
yscrollbar = Scrollbar(master)
yscrollbar.grid(row=0, column=1, sticky=N+S)
canvas1=Canvas(master, width=1000, height=800, background='white',xscrollcommand=xscrollbar.set,yscrollcommand=yscrollbar.set)
canvas1.grid(row=0,column=0, sticky=N+S+E+W)
xscrollbar.config(command=canvas1.xview)
yscrollbar.config(command=canvas1.yview)
canvas2=Canvas(master, width=100, height=200, background='pink',xscrollcommand=xscrollbar.set,yscrollcommand=yscrollbar.set)
canvas2.grid(row=2,column=0)
mainloop()
What you want to do is set the canvas size to be 300x400, and then set the scrollregion attribute of the canvas to be 1000*800.
canvas1 = Canvas(..., width=300, height=400, scrollregion=(0,0,1000,800))

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