I have a tkinker
window with several buttons and layouts that use place. I tried to create a scrollbar to the entire window, but I can not place the button in the frame. Can someone help me, how can I add this button on the frame?
#btn1 = tk.Button(win,
text="Browse...",
compound="left",
fg="blue", width=22,
font=("bold", 10),
height=1,
)
#btn1.place(x=600, y=0)
import json
from tkinter import *
import tkinter as tk
from tkinter import filedialog as fd
win = Tk()
win.geometry("500x500")
# main
main_frame = Frame(win)
main_frame.pack(fill=BOTH, expand=1)
# canvas
my_canvas = Canvas(main_frame)
my_canvas.pack(side=LEFT, fill=BOTH, expand=1)
# scrollbar
my_scrollbar = tk.Scrollbar(main_frame, orient=VERTICAL, command=my_canvas.yview)
my_scrollbar.pack(side=RIGHT, fill=Y)
# configure the canvas
my_canvas.configure(yscrollcommand=my_scrollbar.set)
my_canvas.bind(
'<Configure>', lambda e: my_canvas.configure(scrollregion=my_canvas.bbox("all"))
)
second_frame = Frame(my_canvas)
my_canvas.create_window((0, 0), window=second_frame, anchor="nw")
CodePudding user response:
For starters I would recommend removing your redundant import statement. I would use import tkinter as tk for readability, it's always nice to know what module your code is calling functions & methods from. It look like you set your window size and place your button outside that. I adjusted your x and y position. The example below will put the button on your screen.
import json
import tkinter as tk
from tkinter import filedialog as fd
win = tk.Tk()
win.geometry("500x500")
# main
main_frame = tk.Frame(win)
main_frame.pack(fill=tk.BOTH, expand=1)
# canvas
my_canvas = tk.Canvas(main_frame)
my_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
# scrollbar
my_scrollbar = tk.Scrollbar(main_frame, orient=tk.VERTICAL, command=my_canvas.yview)
my_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
btn1 = tk.Button(main_frame,
text="Browse...",
compound="left",
fg="blue", width=22,
font=("bold", 10),
height=1,
)
btn1.place(x=300, y=300)
# configure the canvas
my_canvas.configure(yscrollcommand=my_scrollbar.set)
my_canvas.bind('<Configure>', lambda e: my_canvas.configure(scrollregion=my_canvas.bbox("all")))
second_frame = tk.Frame(my_canvas)
my_canvas.create_window((0, 0), window=second_frame, anchor="nw")
CodePudding user response:
Creating a Scrollable Frame:
If you want to make a frame (say target_frame
) scrollable, you must follow the below 5 steps:
- Create a frame (say
outer_frame
) to serve as a parent for a canvas and the scrollbar. - Add
target_frame
as an item to the canvas using the.create_window()
method. - Connect the canvas and scrollbar with each other using
command = canvas.yview
andyscrollcommand = scrollbar.set
in the appropriate places. - Specify which region of the canvas should be scrollable. If you want the entire canvas to be scrollable, use
canvas.configure(scrollregion = canvas.bbox("all")
- Add all the required widgets to
target_frame
, not to theouter_frame
or the canvas.
Solution:
Broadly, your code has the following 3 problems:
- You have not given
win.mainloop()
without which your tkinter application will not open. - The parent of
btn1
should besecond_frame
, notwin
. second_frame
has not been initialised with awidth
andheight
. Whenever a frame is added to a canvas using the.create_window()
method, it must have a predefined width and height. Otherwise, the frame will not be displayed.
In your code, target_frame
and outer_frame
correspond to second_frame
and main_frame
respectively. I made the above 3 changes to your code to get it working.
Working Code:
import json
from tkinter import *
import tkinter as tk
from tkinter import filedialog as fd
win = Tk()
win.geometry("500x500")
# main
main_frame = Frame(win)
main_frame.pack(fill=BOTH, expand=1)
# canvas
my_canvas = Canvas(main_frame)
my_canvas.pack(side=LEFT, fill=BOTH, expand=1)
# scrollbar
my_scrollbar = tk.Scrollbar(main_frame, orient=VERTICAL, command=my_canvas.yview)
my_scrollbar.pack(side=RIGHT, fill=Y)
# configure the canvas
my_canvas.configure(yscrollcommand=my_scrollbar.set)
my_canvas.bind(
'<Configure>', lambda e: my_canvas.configure(scrollregion=my_canvas.bbox("all"))
)
second_frame = Frame(my_canvas, width = 1000, height = 100)
btn1 = tk.Button(second_frame,
text="Browse...",
compound="left",
fg="blue", width=22,
font=("bold", 10),
height=1,
)
btn1.place(x=600, y=0)
my_canvas.create_window((0, 0), window=second_frame, anchor="nw")
win.mainloop()