So yeah, I just want a scrollbars cause I have a lot of frames, but I just don't get how to use it.
I tried a couple of things with a little variation each time but even though I think I'm getting close it's still not there.
In my code I have a canvas that fills the main Tk window and inside that canvas I have a lot of frames in a grid generated with a for loop.
Code:
import tkinter as to
import tkinter.ttk
def generateFrames(root, o):
pieFrame = Frame(root)
pieFrame.grid(row=int(o/4), column=o%4, padx=25)
mainWindow = tk.Tk()
scrollbar = Scrollbar(mainWindow, orient='vertical')
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
canvas = Canvas(mainWindow, yscrollcommand=scrollbar.set)
scrollbar.config(command=canvas.yview)
canvas.pack(expand=tk.YES, fill=tk.BOTH)
for I in range(16):
generateFrames(canvas, i)
mainWindow.mainloop()
working code is:
import tkinter as tk
import tkinter.ttk
def generateFrames(root, o):
pieFrame = Frame(root)
pieFrame.grid(row=int(o/4), column=o%4, padx=25)
mainWindow = tk.Tk()
scrollbar = Scrollbar(mainWindow, orient='vertical')
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
canvas = Canvas(mainWindow, yscrollcommand=scrollbar.set)
scrollbar.config(command=canvas.yview)
canvas.pack(expand=tk.YES, fill=tk.BOTH)
canvas.configure(scrollregion=(0,0,0,2000))
mainFrame = Frame(mainWindow)
mainFrame.pack(fill=tk.BOTH)
for I in range(16):
generateFrames(mainFrame, i)
canvas.create_window(950, 750, window=mainFrame)
mainWindow.mainloop()
Related
I am trying to display a bunch of OptionMenu in tkinter. The problem is that once there are too many OptionMenu they go out of screen and they cannot be accessed anymore.
So I thought of implementing a full-screen scrollbar to solve this.
I followed this tutorial - link, in this, the full-screen scrollbar is implemented by putting buttons inside a frame
The code from the tutorial - Working code with buttons
So I tried to use this code but instead of buttons, use OptionMenu.
This is my code
from tkinter import *
import tkinter as tk
from tkinter import ttk
class App(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
master.title('ATOM')
master.geometry('650x650')
main_frame = Frame(root)
main_frame.pack(fill=BOTH, expand=1)
# Create A Canvas
my_canvas = Canvas(main_frame)
my_canvas.pack(side=LEFT, fill=BOTH, expand=1)
# Add A Scrollbar To The Canvas
my_scrollbar = ttk.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")))
# Create ANOTHER Frame INSIDE the Canvas
second_frame = Frame(my_canvas)
# Add that New frame To a Window In The Canvas
my_canvas.create_window((0,0), window=second_frame, anchor="nw")
length=[1,2,3,4,5,6,7,8,9,10]
variable_rsi_length = tk.StringVar(second_frame)
rsi_len = ttk.OptionMenu(second_frame, variable_rsi_length,*length )
variable_rsi_length.set('14')
for thing in range(100):
ttk.Button(second_frame, text=f'Button {thing} Yo!').grid(row=thing, column=0, pady=10, padx=10)
my_label = Label(second_frame, text="It's Friday Yo!").grid(row=3, column=2)
rsi_len.pack()
self.pack()
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
app.mainloop()
But this doesn't give any error on running in fact it does not even show the new window.
How can I implement this?
What's wrong is that you cannot use pack when its children are being managed by grid.
To be more specific, the error is: _tkinter.TclError: cannot use geometry manager pack inside .!frame.!canvas.!frame which already has slaves managed by grid
So, what you can easily do is just use one type of geometry manager.
Either use only "pack", or only "grid".
Here's a quick solution:
.
.
.
for thing in range(100):
ttk.Button(second_frame, text=f'Button {thing} Yo!').pack()
my_label = Label(second_frame, text="It's Friday Yo!").pack()
rsi_len.pack()
self.pack()
.
.
.
My code:
import tkinter as tk
root = tk.Tk()
for i in range(50):
for j in range(50):
tk.Button(height=1, width=2, bg='Blue').grid(row=j, column=i)
root.mainloop()
I can not see all of the buttons in the screen even when I maxmize the window. so I want to add an option to zoom out (all of the widgets will be smaller) so I can see all of them. How do I do that?
Example code:
import tkinter as tk
root = tk.Tk()
root.state('zoomed')
widgets_to_zoom_list = []
DEFAULT_SIZE = 50
def zoom(widget):
for every_widget in widgets_to_zoom_list:
every_widget.config(width=widget.get(), height=widget.get())
def main():
canvas = tk.Canvas(root)
frame = tk.Frame(canvas)
zoom_scale = tk.Scale(root, orient='vertical', from_=1, to=100)
zoom_scale.config(command=lambda args: zoom(zoom_scale))
zoom_scale.set(DEFAULT_SIZE)
pixel = tk.PhotoImage(width=1, height=1)
for i in range(50):
btn = tk.Button(frame, text=str(i + 1), bg='Blue', image=pixel, width=DEFAULT_SIZE, height=DEFAULT_SIZE, compound="c")
btn.grid(row=0, column=i)
widgets_to_zoom_list.append(btn)
canvas.create_window(0, 0, anchor='nw', window=frame)
# make sure everything is displayed before configuring the scroll region
canvas.update_idletasks()
canvas.configure(scrollregion=canvas.bbox('all'))
canvas.pack(fill='both', side='left', expand=True)
zoom_scale.pack(fill='y', side='right')
root.mainloop()
if __name__ == '__main__':
main()
From what i have been able to understand from your question, i think you want the window to be resizable in tkinter.
To allow a window to be resized by the user, we use the resizable function -:
root.resizable(height = True, width = True)
In this case the two args are height and width which help you customize if you only want the widget to be vertically resizable or only want it to be horizontally resizable.
Your code with this function added should look like this -:
import tkinter as tk
root = tk.Tk()
root.resizable(True, True) #Assuming you want both vertically and horizontally resizable window.
for i in range(50):
for j in range(50):
tk.Button(height=1, width=2, bg='Blue').grid(row=j, column=i)
root.mainloop()
I hope this will solve your problem.
And I also hope you are safe in this time of an ongoing pandemic.
I am having this issue where the scroll bar is not displaying on the listbox. I do not know what the issue is as.
I believe the issue is originating from the Scrollbar variables as the Listbox appears to be displaying and functioning properly.
The output is displaying the listbox with no scrollbar on the right (as set)
Here is the Listbox with the for loop however, it is displaying the wrong dimensions
Here is the code:
#imports
from tkinter import *
from tkinter import messagebox as ms
from tkinter import ttk
import sqlite3
from PIL import Image,ImageTk
import datetime
global time
time = datetime.datetime.now()
class main:
def __init__(self,master):
self.master = master
def search_user_sql(self):
self.search_user_sqlf = Frame(self.master, height=300, width =200)
scrollbar = Scrollbar(self.search_user_sqlf)
scrollbar.pack(side = RIGHT,fill = BOTH)
myList = Listbox(self.search_user_sqlf, yscrollcommand= scrollbar.set)
myList.pack( side = LEFT, fill = BOTH, expand = 2)
scrollbar.config( command = myList.yview )
self.search_user_sql()
root = Tk()
root.title("Gym Membership System")
main(root)
root.mainloop()
You need to pack the frame to display it. To pack() the frame with the correct size settings, try:
search_user_sqlf = Frame(master, height=300, width=200)
search_user_sqlf.pack(expand=True, fill='both')
search_user_sqlf.pack_propagate(0)
Here is how to attach a scrollbar to list set in a frame in Tkinter:
from tkinter import *
master = Tk()
search_user_sqlf = Frame( master, width=400, height=400)
search_user_sqlf.pack(expand=True, fill='both')
search_user_sqlf.pack_propagate(0)
scrollbar = Scrollbar(search_user_sqlf)
scrollbar.pack(side=RIGHT, fill=Y)
myList = Listbox(search_user_sqlf, yscrollcommand=scrollbar.set)
for line in range(100):
myList.insert(END, "This is line number " + str(line))
myList.pack( side = LEFT, fill = BOTH , expand = 2)
scrollbar.config( command = myList.yview )
mainloop()
This question concerns Python's Tkinter.
I first produced this GUI, a simple two-column set of rows in a Labelframe, with an icon on the right:
The above behaviour was correct and expected, based on this following code:
import tkinter as tk
import tkinter.ttk as ttk
from PIL import Image, ImageTk
root = tk.Tk()
icon_colours_fp = r"D:\Dropbox\coding\python\experiments\icon_component.gif"
icon_col = tk.PhotoImage(file=icon_colours_fp)
# icon_col = ImageTk.PhotoImage(Image.open(icon_colours_fp))
tk.Label(root, text="Past").grid(row=0, column=0)
tk.Label(root, text="Today").grid(row=1, column=0)
tk.Label(root, text="Future").grid(row=2, column=0)
_b = ttk.Button(root, image=icon_col)
_b['image'] =icon_col
_b.grid(row=0, column=1)
root.mainloop()
I then re-wrote the code as a class, hoping to produce something similar within a Labelframe:
import tkinter as tk
import tkinter.ttk as ttk
from PIL import Image, ImageTk
class Options(tk.Frame):
def __init__(self, parent):
super().__init__()
main_labelframe = ttk.LabelFrame(parent, text="Test Labelframe")
main_labelframe.pack(fill=tk.BOTH, expand=1)
frame_1 = tk.Frame(main_labelframe)
frame_1_sep = ttk.Separator(main_labelframe, orient=tk.VERTICAL)
frame_2 = tk.Frame(main_labelframe)
frame_1.pack(side=tk.LEFT)
frame_1_sep.pack(side=tk.LEFT, fill=tk.BOTH)
frame_2.pack(side=tk.LEFT)
tk.Label(frame_1, text="Past").grid(row=0, column=0)
tk.Label(frame_1, text="Today").grid(row=1)
tk.Label(frame_1, text="Future").grid(row=2)
icon_colours_fp = r"D:\Dropbox\coding\python\experiments\icon_component.gif"
icon_col = tk.PhotoImage(file=icon_colours_fp)
_b = ttk.Button(frame_2, image=icon_col)
_b['image'] = icon_col
_b.grid(row=0, column=0)
class Gui(tk.Tk):
def __init__(self):
super().__init__()
options = Options(self)
options.pack()
gui = Gui()
gui.mainloop()
The code then failed, in two respects:
The icon fails to appear.
The ttk Button becomes misaligned. (It appears in the centre, whereas by the grid, it should appear at the top.)
The failed code appears as follows:
I have experimented: among others, I changed the geometry manager to .pack(), and changed the parent of ttk.Button, but without success. Would appreciate some pointers as to where I've gone wrong, especially as to the disappearing icon.
You didn't keep a reference to the image. Easiest way here is to change:
icon_col = tk.PhotoImage(file=icon_colours_fp)
b = ttk.Button(frame_2, image=icon_col)
_b['image'] = icon_col
To:
self.icon_col = tk.PhotoImage(file=icon_colours_fp)
b = ttk.Button(frame_2, image=self.icon_col)
I'm trying to pack the button below the Text and Scrollbar widget.
#!/usr/bin/python
try:
from Tkinter import *
except ImportError:
from tkinter import *
class Chat(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.pack(anchor=N, fill=BOTH)
self.create_widgets()
self.count = 0
def create_widgets(self):
self.scrolly = Scrollbar(self)
self.scrolly.pack(side=RIGHT, fill=Y)
self.chattext = Text(self, borderwidth=5, yscrollcommand=self.scrolly.set)
self.chattext.pack(side=LEFT)
self.scrolly.config(command=Text.yview(self.chattext))
self.button1 = Button(self, text="Add text", command=self.add_text)
self.button1.pack()
def add_text(self):
self.count += 1
self.chattext.insert("end", "%i\n" % self.count)
self.chattext.update_idletasks()
def main():
root = Tk()
root.title("Test Chat Client")
root.geometry("600x500")
#root.resizable(0,0)
app = Chat(root)
root.mainloop()
if __name__ == "__main__":
main()
This is what it looks like
I want the button to be below and not in between the other widgets.
I have tried the following:
self.button1.pack(after=self.scrolly)
self.button1.pack(after=self.chattext)
How may i pack the button at the bottom?
Another issue is that the scrollbar does not work, when i try to scroll nothing happens.
(Yes, i have tried to fill the Text widget with alot of lines, more than it can view.)
Also, why is the scrollbar viewed/packed outside/"far" away from the Text widget?
Try using the grid geometry manager instead.
http://www.tkdocs.com/tutorial/grid.html
I think you should consider replacing the text field with a ScrolledText field.
It's a lot easier to use and doesn't require manual scrollbar placement.
(Don't use pack to place it though. Use grid)
import tkinter as tk
import tkinter.scrolledtext as tkst
self.chattext = tkst.ScrolledText(
master = self,
wrap = tk.WORD,
width = 20,
height = 10
)