Tkinter Scroll through a canvas of frames - python

I'm trying to add a scroll bar to a canvas filled with multiple MsgFrame classes. MsgFrame inherits from the tk.Frame class. I've tried multiple youtube videos and articles but none have worked.
root = tk.Tk()
root.geometry('500x500')
scrollBar= Scrollbar(root)
scrollBar.pack(side=RIGHT, fill='y')
canvas = Canvas(root, yscrollcommand=scrollBar.set)
frames = []
for row, msg in enumerate(MESSAGES):
frame = MsgFrame(msg, canvas, row*3+1)
frames.append(frame)
for frame in frames:
frame.pack(side=TOP, anchor=NW, padx=5, pady=5)
canvas.pack(side=LEFT, fill=BOTH)
scrollBar.config(command=canvas.yview)
root.mainloop()

Related

Tkinter Scrollbar Does not work for objects inside canvas

I've made a canvas with two scrollbar and two buttons. But the scrollbar doesn't interact with the buttons inside the canvas.
What I want to make, is whenever I scrolls (for example, scroll down), all buttons in the canvas moves to the opposite direction (in this case, move up), but currently they won't move at all.
ws = Tk()
ws.title('PythonGuides')
frame = Frame(
ws,
width=500,
height=400
)
frame.pack(expand=True, fill=BOTH)
canvas = Canvas(
frame,
bg='#4A7A8C',
width=500,
height=400,
scrollregion=(0, 0, 700, 700)
)
vertibar = Scrollbar(
frame,
orient=VERTICAL
)
vertibar.pack(side=RIGHT, fill=Y)
vertibar.config(command=canvas.yview)
horibar = Scrollbar(
frame,
orient=HORIZONTAL
)
horibar.pack(side=BOTTOM, fill=X)
horibar.config(command=canvas.xview)
canvas.config(width=500, height=400)
canvas.config(
xscrollcommand=horibar.set,
yscrollcommand=vertibar.set
)
example=tkinter.Button(canvas, text="1")
example.grid(row=3, column=5)
example2 = tkinter.Button(canvas, text="2")
example2.grid(row=6, column=7)
canvas.pack(expand=True, side=LEFT, fill=BOTH)
ws.mainloop()
You cannot scroll items of canvas if they are put into the canvas using .grid()/.pack()/.place().
Use .create_window() instead:
...
example = tkinter.Button(canvas, text="1")
canvas.create_window(10, 10, window=example, anchor="nw")
example2 = tkinter.Button(canvas, text="2")
canvas.create_window(50, 50, window=example2, anchor="nw")
...

Python tkinker resitze Canvas

I have an Python3 Tkinter Programm. I have 3 Frames in the Main Window and in one Frame an canvas with scroll Option - now i want resitze the Canvas Area .
Now if i resize it moves the Scroll Bar for Y out the Window and the scrollbar for x works also not as expected (get bigger but slide area don't change)
How i Mange it to resize an Canvas in an grid Layout - The Window must be the same size , the Scrollbas must be updatet and the Canvas Plane must be bigger.
an excerpt from my code:
import tkinter as tk
def menu_build():
caninfo[0] += 10
cangui.configure(width = caninfo[0])
#cangui.configure(scrollregion=cangui.bbox("all"))
def gui():
master = tk.Tk()
master.title( "Easy Switch" )
master.geometry("480x320")
frametop = tk.Frame(master, bg="blue", bd=2)
frametop.grid(column=0,row=0)
frameex = tk.Frame(master, bg="yellow", bd=2)
frameex.grid(column=1,row=1)
framegui = tk.Frame(master, bg="red", bd=2)
framegui.grid(column=0, columnspan=2, row=1)
menu = tk.Menu(master)
master.config(menu=menu)
filemenu = tk.Menu(menu)
menu.add_cascade(label="Config", menu=filemenu)
filemenu.add_command(label="Resize",command=menu_build)
global cangui
cangui = tk.Canvas(framegui, width=385, height=250)
#caninfo = [385,250]
cangui.grid(row=1, column=2)
scroll_x = tk.Scrollbar(framegui, orient="horizontal", command=cangui.xview)
scroll_x.grid(row=2, column=2, sticky="ew")
scroll_y = tk.Scrollbar(framegui, orient="vertical", command=cangui.yview)
scroll_y.grid(row=1, column=3, sticky="ns")
cangui.configure(yscrollcommand=scroll_y.set,xscrollcommand=scroll_x.set)
cangui.configure(scrollregion=cangui.bbox("all"))
cwcb = tk.Checkbutton(framegui, text="ccw").grid(row=2,column=0)
cangui.create_arc(90,90,110,110,style=tk.PIESLICE,width=4,start=0,extent=300)
master.mainloop()
global caninfo
caninfo = [385,250]
if __name__ == "__main__":
gui()
no need to resize the canvas Area
wrote an extra funktion
win = [int(cangui.cget("width")),int(cangui.cget("height"))]
draw_xy = cangui.bbox("all")
swin = (min(0,draw_xy[0]),min(0,draw_xy[1]),max(draw_xy[2],win[0]),max(draw_xy[3],win[1]))
cangui.configure(scrollregion=swin)
reason: canvas.bbox("all") gives only the positon from most upper/left grafic and i want 0/0

scrollbar in Top level canvas

scrollbar in Top level window created for a canvas is not working and how do I get region of canvas. where canvas size varies with number of buttons in it
I have created frame in tk(root) and one widget in a frame creates Top level window , which has multiple Buttons in a Frame.Number of Button varies with list. That Frame(which has buttons in it) exists in a canvas. My problem is that after putting scroll widget canvas do not moves
from tkinter import *
root = Tk()
root.geometry("500x200")
my_app= Frame(root)
my_app.pack()
my_window = Toplevel(my_app, bg='brown')
my_window.geometry("500x200+300+500")
top_window = Frame(my_window, bd=2, relief=SUNKEN)
top_window.grid_columnconfigure(0, weight=1)
yscrollbar = Scrollbar(top_window)
yscrollbar.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(top_window, bd=0, yscrollcommand=yscrollbar.set)
canvas.config(scrollregion=(0, 0, 500, 1000))
canvas.grid(row=0, column=0, sticky=N+S+E+W)
yscrollbar.config( command = canvas.yview)
top_window.pack()
my_f = Frame(canvas)
def ins_ind(m):
print(m)
results =
["one","two","three","four","five","six","seven","eight","nine","ten"]
ins_list=[]
for ind, result in enumerate(results):
ins=str(result)
ins_list.append(ind)
ins_list[ind] = Button(my_f, text = ins, font='Times 12 bold',
bg='sandy brown',anchor=E, fg="black", command = lambda m=ins:
ins_ind(m) )
ins_list[ind].pack()
my_f.pack()
root.mainloop()
Scroll bar do no moves
For the buttons to move when you scroll the canvas you must put the buttons on the canvas.
Your code puts the buttons on the frame my_f. To put the buttons on the canvas you should use: canvas.create_window(x, y, window=button).

How to add two widgets in a tk.Frame located inside a tk.Canvas?

I'm trying to do a scrollable application with two buttons. Pressing one of those buttons should be put a new button in the Frame, and scroll the widgets inside the frame.
My question is how to put the two buttons in the frame?
when I try to put in the same Frame only I can see one button and only a small part of the other.
How to solve this?
from tkinter import * # from x import * is bad practice
global y
y=0
def _configure_interior(event):
print("hola")
size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
canvas.config(scrollregion="0 0 %s %s" % size)
def newbutton():
buttons=Button(interior, text="Button ")
buttons.pack()
#b2.place(y=50)
root =Tk()
#configuring the Scrollbars
vscrollbar = Scrollbar(root, orient=VERTICAL)
vscrollbar.pack(fill=Y, side=RIGHT)
hscrollbar = Scrollbar(root, orient=HORIZONTAL)
hscrollbar.pack(fill=X, side=BOTTOM)
#setting canvas with scrollbar
canvas = Canvas(root,height=500, width=500, bg="blue",
yscrollcommand=vscrollbar.set,xscrollcommand=hscrollbar.set)
canvas.propagate(0)
vscrollbar.config(command=canvas.yview)
hscrollbar.config(command=canvas.xview)
canvas.pack()
#making a interior scrolleable frame
interior = Frame(canvas,bg='black',height=600,width=600)
interior.pack(side="top", fill="both", expand=True)
#adding some widgets to the Frame
b=Button(interior, text="Button 2",command=newbutton)
b.pack()
b2=Button(interior, text="Button 2",command=newbutton)
b2.pack()
b2.place(x=50,y=50)
interior_id = canvas.create_window(30,30, window=interior,
anchor=NW)
interior.bind('<Configure>', _configure_interior)
root.mainloop()
You have also used pack() to place the interior frame on the canvas, which does not work. I've commentet that line out in the code below. Also I've commented out the b2.place() as you should not use more tham one geometry manager in a frame.
#making a interior scrolleable frame
interior = Frame(canvas,bg='black',height=600,width=600)
#interior.pack(side="top", fill="both", expand=True)
interior_id = canvas.create_window(30,30, window=interior,
anchor=NW)
#adding some widgets to the Frame
b=Button(interior, text="Button 2",command=newbutton)
b.pack()
b2=Button(interior, text="Button 2",command=newbutton)
b2.pack()
#b2.place(x=50,y=50)
The new buttons are now packed into interior.

Frame swapping is not working

I want to switch the frame, but not able to do it
1st Page(frame) should have red background color and "Hello" button and Frame size should have 900x650 as window size. When press "Hello" button it should swap to 2nd frame
2nd page (frame) should have green background color and "Hello" button and Frame size should have 900x650 as window size. When press "Hello" button it should swap to 1st frame
import Tkinter as tk
def raise_frame(frame):
print "Inside raise frame"
frame.tkraise()
root = tk.Tk()
root.geometry("900x650+220+20")
root.title("Testing")
frame1 = tk.Frame(root, width=900, height=650, background="red")
frame2 = tk.Frame(root, width=900, height=650, background="green")
B1= tk.Button(frame1, text="Hello", width =10, height=2, command = lambda:raise_frame(frame2)).place (x=200, y=200)
B2= tk.Button(frame2, text="Hello", width =10, height=2, command = lambda:raise_frame(frame1)).place (x=400, y=400)
frame1.pack( )
frame2.pack( )
root.mainloop()
Since you are using pack(), the second frame is placed below the first frame. You can check that by dragging the bottom part of the window. You'll see that there are 2 frames created with the red on the top, and the green on the bottom.
You can use grid() to place the frames on top of each other.
So, replace the lines
frame1.pack()
frame2.pack()
with
frame1.grid(row=0, column=0)
frame2.grid(row=0, column=0)

Categories