I have a problem that I could not solve, thanks to many of you I was able to order the tree with the scrollbar, the problem now is that the scrollbar is always maximized, it does not calculate the amount of data that is inside.
frame = customtkinter.CTkFrame(self.wind, corner_radius=5)
frame.pack(expand="true")
button_llegue = customtkinter.CTkButton(master=frame, corner_radius=8,fg_color="IndianRed3",hover_color="IndianRed4", text='Llegue',command=self.add_fecha)
button_llegue.grid(row = 0, column = 0,pady=(20,10),padx=(15,15))
button_sali = customtkinter.CTkButton(master=frame, corner_radius=8,fg_color="PaleGreen3",hover_color="PaleGreen4", text='Me Voy',command=self.add_fecha)
button_sali.grid(row = 0, column = 1,pady=(20,10),padx=(15,15))
self.tree = ttk.Treeview(master=frame,height = 10, selectmode="browse")
self.tree.grid(row = 1,column=0,pady=(10,20),columnspan=2,sticky="NWSE",padx=(15,15))
self.tree.heading('#0', text = 'Ultimos registros', anchor = CENTER)
scrollbar = ttk.Scrollbar(frame,orient='vertical',command=self.tree.yview)
scrollbar.grid(row = 1, column=0, sticky="NSE",pady=(10,20),columnspan=2,padx=(0,15))
self.get_fechas()
Using command=self.tree.yview you send information from scrollbar to treeview - and it will scroll treeview when you will move scrollbar.
But you need also
self.tree.config(yscrollcommand=scrollbar.set)
to send information from treeview to scrollbar - and it will change size and position of scrollbar when you will add elements to treeview or when you will scroll treeview directly (using mouse wheel).
Minimal working code
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
tree = ttk.Treeview(root, selectmode="browse")
tree.pack(side='left', fill='both', expand=True)
scrollbar = tk.Scrollbar(root, orient='vertical', command=tree.yview)
scrollbar.pack(side='right', fill='y')
tree.config(yscrollcommand=scrollbar.set)
for x in range(1, 21):
print(tree.insert('', 'end', text=str(x)))
root.mainloop()
Related
how can i move the scrollbar inside a listbox? See the photo attached i used a red arrow for explain, here is my code:
from tkinter import *
window = Tk()
window.geometry('500x500')
window.config(bg='#3c3f41')
window.state('zoomed')
frame_listbox = Frame(window,bg='#3c3f41')
frame_listbox.pack(side=LEFT)
listbox = Listbox(frame_listbox,font=('Helvetica',30))
listbox.pack(padx=400)
scrollbar = Scrollbar(window)
scrollbar.pack(side=RIGHT,fill=Y)
scrollbar.config(command=listbox.yview)
listbox.config(yscrollcommand=scrollbar.set)
window.mainloop()
I tried to put a scrollbar inside a Listbox, i expect to understand if it's possible or not
It is recommended to put the scrollbar just to the right of the listbox instead of inside it. To achieve it:
make the scrollbar child of frame_listbox instead of window
move option padx=400 from scrollbar.pack(...) to frame_listbox.pack(...)
pack listbox to the LEFT side
from tkinter import *
window = Tk()
window.geometry('500x500')
window.config(bg='#3c3f41')
window.state('zoomed')
frame_listbox = Frame(window,bg='#3c3f41')
frame_listbox.pack(side=LEFT,padx=400) # added padx=400
listbox = Listbox(frame_listbox,font=('Helvetica',30))
listbox.pack(side=LEFT) # removed padx=400 and added side=LEFT
scrollbar = Scrollbar(frame_listbox) # changed parent to frame_listbox
scrollbar.pack(side=RIGHT,fill=Y)
scrollbar.config(command=listbox.yview)
listbox.config(yscrollcommand=scrollbar.set)
window.mainloop()
Does this will Help? By using grid instead place.
import tkinter as tk
root = tk.Tk()
root.title("Listbox Operations")
# create the listbox (note that size is in characters)
listbox1 = tk.Listbox(root, width=50, height=6)
listbox1.grid(row=0, column=0)
# create a vertical scrollbar to the right of the listbox
yscroll = tk.Scrollbar(command=listbox1.yview, orient=tk.VERTICAL)
yscroll.grid(row=0, column=1, sticky=tk.N+tk.S)
listbox1.configure(yscrollcommand=yscroll.set)
for i in range(1, 50):
listbox1.insert(tk.END, i)
root.mainloop()
Result:
I have issue dealing with scrollbar in tkinter.
I enclosed Treeview and Scrollbar widgets inside a frame for easier grouping. The problem is that when I update the Treeview to display a table with many columns, the scroll bar suddenly disappears (scroll bar retains only when at most 3 columns are displayed).
window = tk.Tk()
window.minsize(800, 700)
window.geometry("800x700")
...
middle = tk.Frame(window)
middle.pack(fill='x', side='top')
#red background for visualizing only
middle.configure(background='red')
displayTable = ttk.Treeview(middle, show='headings', selectmode="browse")
displayTable.pack(side=tk.LEFT)
#style for the table
style = ttk.Style()
style.theme_use("clam")
style.map("Treeview")
style.configure("Treeview.Heading", font=("Consolas", 12))
style.configure("Treeview", rowheight=30)
tabScroll = ttk.Scrollbar(middle, orient=tk.VERTICAL, command=displayTable.yview)
displayTable.configure(yscrollcommand=tabScroll.set)
tabScroll.pack(side=tk.RIGHT, fill='y')
I want that the scroll bar widget will not disappear whenever I display tables with cols > 3. Any idea where is the issue? I dont want to use grid() since the main window is resizable.
Table with 2 columns:
Table with 6 columns:
Note: data in table are fictitious
EDIT: as requested, below are the two variants for the working example:
Table with 2 rows:
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.minsize(800, 700)
window.geometry("800x700")
middle = tk.Frame(window)
middle.pack(fill='x', side='top')
#red background for visualizing only
middle.configure(background='red')
displayTable = ttk.Treeview(middle, show='headings', selectmode="browse")
displayTable.pack(side=tk.LEFT)
#headings
columns = ("id", "name")
displayTable['column'] = columns
displayTable.heading("# 1",text="id")
displayTable.heading("# 2",text="name")
#rows
for n in range(1, 100):
displayTable.insert('', tk.END, values=(n, f"Row entry{n}"))
#style for the table
style = ttk.Style()
style.theme_use("clam")
style.map("Treeview")
style.configure("Treeview.Heading", font=("Consolas", 12))
style.configure("Treeview", rowheight=30)
tabScroll = ttk.Scrollbar(middle, orient=tk.VERTICAL, command=displayTable.yview)
displayTable.configure(yscrollcommand=tabScroll.set)
tabScroll.pack(side=tk.RIGHT, fill='y')
window.mainloop()
Table with 4 rows:
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.minsize(800, 700)
window.geometry("800x700")
middle = tk.Frame(window)
middle.pack(fill='x', side='top')
#red background for visualizing only
middle.configure(background='red')
displayTable = ttk.Treeview(middle, show='headings', selectmode="browse")
displayTable.pack(side=tk.LEFT)
#headings
columns = ("id", "name", "job", "number")
displayTable['column'] = columns
displayTable.heading("# 1",text="id")
displayTable.heading("# 2",text="name")
displayTable.heading("# 3",text="job")
displayTable.heading("# 4",text="number")
#rows
for n in range(1, 100):
displayTable.insert('', tk.END, values=(n, f"Row entry{n}", f"Job{n}", f"09-{n}"))
#style for the table
style = ttk.Style()
style.theme_use("clam")
style.map("Treeview")
style.configure("Treeview.Heading", font=("Consolas", 12))
style.configure("Treeview", rowheight=30)
tabScroll = ttk.Scrollbar(middle, orient=tk.VERTICAL, command=displayTable.yview)
displayTable.configure(yscrollcommand=tabScroll.set)
tabScroll.pack(side=tk.RIGHT, fill='y')
window.mainloop()
My goal is that to not suppress the scrollbar when the table displays more than 3 columns (in that specific window dimensions). Hope this helps.
I followed some tutorial on attaching a scrollbar to a textbox. However, in the tutorial, the scrollbar is really a "bar". When I tried myself, I can only press the arrows to move up or down, the middle part is not movable. May I know what I did wrong?
import tkinter as tk
root = tk.Tk()
scroll = tk.Scrollbar(root)
scroll.grid(row = 0, column = 1)
message = tk.Text(root, yscrollcommand = scroll.set, height = 25, width = 60)
message.grid(row = 0, column = 0)
for i in range(50):
message.insert(tk.END, f'This is line {i}\n')
scroll.config(command = message.yview)
root.mainloop()
You just have to add sticky='nsew' to Scrollbar widget.
sticky='nsew' will make the Scrollbar widget to expand to fill up the entire cell (at grid position row=0 & column=1) at every side (n-north, s-south, e-east, w-west)
Here is the code:
import tkinter as tk
root = tk.Tk()
scroll = tk.Scrollbar(root)
# add sticky option to the Scrollbar widget
scroll.grid(row = 0, column = 1, sticky='nsew')
message = tk.Text(root, yscrollcommand = scroll.set, height = 25, width = 60)
message.grid(row = 0, column = 0)
for i in range(50):
message.insert(tk.END, f'This is line {i}\n')
scroll.config(command = message.yview)
root.mainloop()
I want to put the horizontal and vertical scrollbars at the edge of the yellow canvas using Python tkinter, but whatever I do, it does not move and just stay inside the perimeter of the canvas. Why? Below is the image:
Below is the code:
def render_gui(self):
self.main_window = tk.Tk()
self.main_window.geometry("1000x600")
self.main_window.title("Damaged Text Document Virtual Restoration")
self.main_window.resizable(True, True)
self.main_window.configure(background="#d9d9d9")
self.main_window.configure(highlightbackground="#d9d9d9")
self.main_window.configure(highlightcolor="black")
self.main_canvas = tk.Canvas(self.main_window, bg = "yellow")
self.main_canvas.pack(expand = True, fill = "both")
vsb = tk.Scrollbar(self.main_canvas, orient="vertical", command=self.main_canvas.yview)
hsb = tk.Scrollbar(self.main_canvas, orient="horizontal", command=self.main_canvas.xview)
vsb.grid(row=1, column=50,columnspan = 20, sticky='ns')
hsb.grid(row=20, column=1,rowspan = 20,sticky = 'wes')
self.main_canvas.configure(yscrollcommand=vsb.set,xscrollcommand=hsb.set)
self.main_window.mainloop()
Please help.
The problem is that you are putting the scrollbars inside the canvas, and you've put nothing else in the canvas.
When you use grid to put something inside another widget, rows and columns that are empty have a size of zero. Thus, even though you put the vertical scrollbar in column 50, columns 0 and 2-49 have a width of zero so column 50 appears on the left. (Column 1 is the width of the horizontal scrollbar.)
The same is true for the horizontal scrollbar - you're putting it in row 20, but rows 0 and 2-19 have a height of zero, so row 20 appears near the top.
Normally it's not a good idea to put scrollbars inside the canvas, since anything you draw on the canvas might be hidden or partially hidden by the scrollbars. If you want them to appear to be in the canvas, the simplest solution is to put both the canvas and the scrollbars inside a frame. You can then turn the border off on the canvas and turn the border on for the frame.
Example:
import tkinter as tk
class Example():
def render_gui(self):
self.main_window = tk.Tk()
self.main_window.geometry("1000x600")
self.main_window.title("Damaged Text Document Virtual Restoration")
self.main_window.resizable(True, True)
self.main_window.configure(background="#d9d9d9")
self.main_window.configure(highlightbackground="#d9d9d9")
self.main_window.configure(highlightcolor="black")
canvas_container = tk.Frame(self.main_window, bd=1, relief='sunken')
canvas_container.pack(expand = True, fill = "both")
self.main_canvas = tk.Canvas(canvas_container, bg = "yellow")
vsb = tk.Scrollbar(canvas_container, orient="vertical", command=self.main_canvas.yview)
hsb = tk.Scrollbar(canvas_container, orient="horizontal", command=self.main_canvas.xview)
self.main_canvas.configure(yscrollcommand=vsb.set,xscrollcommand=hsb.set)
vsb.grid(row=0, column=1, sticky="ns")
hsb.grid(row=1, column=0, sticky="ew")
self.main_canvas.grid(row=0, column=0, sticky="nsew")
canvas_container.grid_rowconfigure(0, weight=1)
canvas_container.grid_columnconfigure(0, weight=1)
self.main_window.mainloop()
e = Example()
e.render_gui()
The code has the canvas as the parent to the scrollbars.
Setting the scrollbars to have the same parent as the canvas, and changing a few placement things around, renders something workable:
import tkinter as tk
class test:
def __init__(self):
self.render_gui()
def render_gui(self):
self.main_window = tk.Tk()
self.main_window.geometry("1000x600")
self.main_window.title("Damaged Text Document Virtual Restoration")
self.main_window.resizable(True, True)
self.main_window.configure(background="#d9d9d9")
self.main_window.configure(highlightbackground="#d9d9d9")
self.main_window.configure(highlightcolor="black")
self.main_canvas = tk.Canvas(self.main_window, bg = "yellow")
vsb = tk.Scrollbar(self.main_window, orient="vertical", command=self.main_canvas.yview)
hsb = tk.Scrollbar(self.main_window, orient="horizontal", command=self.main_canvas.xview)
hsb.pack(side = "bottom", fill = "x")
vsb.pack(side = "right", fill = "y")
self.main_canvas.pack(expand = True, fill = "both")
self.main_canvas.configure(yscrollcommand=vsb.set,xscrollcommand=hsb.set)
self.main_window.mainloop()
t = test()
from tkinter import *
from tkinter import scrolledtext
janela = Tk()
scroll_x = Scrollbar(janela, orient="horizontal")
text = scrolledtext.ScrolledText(janela, wrap=NONE)
text.config(xscrollcommand=scroll_x.set)
scroll_x.configure(command=text.xview)
text.pack(fill=X)
scroll_x.pack(fill=X)
janela.mainloop()
I am working on this table in tkinter made from a bunch of treeveiw widgets. The idea is to get a table where I can add lines, select lines and edit them. In the code below you can add lines to the table by pushing the button. I now want to control the height of each row by configuring the style. However, when I use style the alignment of the treeview widgets is messed up, see attached picture. Any suggestions how to fix this?
EDIT: The problem is the added space between the widgets.
The code for the table is:
from tkinter import *
from tkinter import ttk
class MyApp(Tk):
def __init__(self):
super(MyApp, self).__init__()
self.geometry('950x500+100+100')
self.NewTree = []
label = Label(self,text='Table with some data', font=("Arial Bold", 25))
label.pack()
self.addLine()
master_frame = Frame(self, bd=3, relief=RIDGE)
master_frame.pack(side=BOTTOM)
# Create a frame for the canvas and scrollbar(s).
frame2 = Frame(master_frame)
frame2.pack(side = BOTTOM)
# Add a canvas in that frame.
self.canvas = Canvas(frame2)
self.canvas.grid(row=0, column=0)
# Create a vertical scrollbar linked to the canvas.
vsbar = Scrollbar(frame2, orient=VERTICAL, command=self.canvas.yview)
vsbar.grid(row=0, column=1, sticky=NS)
self.canvas.configure(yscrollcommand=vsbar.set)
# Create a frame on the canvas to contain the buttons.
self.table_frame = Frame(self.canvas)
# Create canvas window to hold the buttons_frame.
self.canvas.create_window((0,0), window=self.table_frame, anchor=NW)
def addLine(self):
#Make button for adding step
bt = Button(self,text='Add Line',command=lambda: self.addLineMethod())
bt.config(width=9, height=1)
bt.pack()
def addLineMethod(self):
lineNumber = int(len(self.NewTree)/5)
for index in range(5):
s = ttk.Style()
s.configure('MyStyle.Treeview', rowheight=25)
self.NewTree.append(ttk.Treeview(self.table_frame, height=1,show="tree",columns=("0"),style='MyStyle.Treeview'))
#Works fine when using this line instead of those above
#self.NewTree.append(ttk.Treeview(self.table_frame, height=1,show="tree",columns=("0")))
self.NewTree[index+5*lineNumber].grid(row=lineNumber, column=index+1)
self.NewTree[index+5*lineNumber]['show'] = ''
item = str(index+5*lineNumber)
self.NewTree[index+5*lineNumber].column("0", width=180, anchor="w")
self.NewTree[index+5*lineNumber].insert("", "end",item,text=item,values=('"Text text text"'))
self.table_frame.update_idletasks() # Needed to make bbox info available.
bbox = self.canvas.bbox(ALL) # Get bounding box of canvas with Buttons.
# Define the scrollable region as entire canvas with only the desired
# number of rows and columns displayed.
self.canvas.configure(scrollregion=bbox, width=925, height=200)
app = MyApp()
app.mainloop()
Her is a picture of the table with some lines.
Put the style configuration in the __init__() function and the effect will go away. I'm not clear as to why this works.
def __init__(self):
...
s = ttk.Style()
s.configure('MyStyle.Treeview', rowheight=20)