Tkinter scrollbar is not scrolling - python

As part of a tkinter app I'm building using Python 3.8, I need a particular tab in a Notebook to be scrollable. The notebook needs to remain at a fixed size, but the problem is that there will be cases in which the contents of the tab will exceed the size of the notebook.
The scrollbar appears as it should, but scrolling appears to have no effect on the contents of the tab. It looks like it thinks it's scrolling something but I do not know what. Here's an isolated example of a tab with a scrollbar which has no effect:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
tabs = ttk.Notebook(root, width=200, height=650)
tab_options = tk.Frame(tabs)
tabs.add(tab_options, text="Options")
main_frame = tk.Frame(tab_options)
main_frame.pack()
canvas = tk.Canvas(main_frame)
canvas.pack(side="left",fill="both",expand=1)
scrollbar = ttk.Scrollbar(main_frame,orient="vertical",command=canvas.yview)
scrollbar.pack(side="right", fill="y",expand=1)
lf_options = tk.Frame(canvas)
lf_options.pack()
canvas.configure(yscrollcommand=scrollbar.set)
canvas.configure(scrollregion=(0,0,200,1000))
for i in range(50):
ttk.Label(lf_options, text=str(i)).pack()
tabs.pack()
root.mainloop()
I imagine it's something to do with how I'm hooking up the frames to the canvas but I cannot for the life of me get it to work. I've seen suggestions about setting scrollregion to
canvas.bbox("all")
but I don't understand how to associate that with the maximum height that can be displayed, i.e. the height of the notebook itself. Using that as the scrollregion also just makes the scrollbar unscrollable.
I know there are many similar questions on here, but I have not found any of those examples to work in this case.
Any advice would be greatly appreciated. Thanks!

It seems more logical to use a tk.Listbox for this purpose, see below for example an edited version of your code. Here the scrollbar works just as expected!
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
tabs = ttk.Notebook(root, width=200, height=650)
tab_options = tk.Frame(tabs)
tabs.add(tab_options, text="Options")
listbox = tk.Listbox(tab_options)
for i in range(50):
listbox.insert(tk.END, f"Number {i}")
listbox.pack(side="left", fill="both", expand=1)
scrollbar = ttk.Scrollbar(tab_options, orient="vertical", command=listbox.yview)
scrollbar.pack(side="right", fill="y", expand=1)
listbox.configure(yscrollcommand=scrollbar.set)
tabs.pack()
root.mainloop()

Related

Python Tkinter with Turtle and Scrollbars

I have been having some problems implementing scrollbars into my Tkinter program which uses turtle. I am able to create and add the turtle canvas to my Tkinter program just fine, however, the scrollbars don't seem to fit visually even though they can be dragged. The canvas also starts offset meaning you have to scroll it to the centre every time. Below is an example of this issue.
I know that I could use turtles built-in "Scrolledcanvas" however this would mean I am unable to style the scrollbars using ttk. If possible I would remove the scrollbars entirely, and just simply centre the graphics and make them fit the canvas at all times, however, this seemed too complex for me.
I have provided a working example below for anyone to take a look at.
import tkinter as tk
from tkinter import ttk
import turtle
root = tk.Tk()
aFrame = tk.Canvas(root)
aFrame.pack()
aCanvas = tk.Canvas(aFrame)
aCanvas.grid(row=0, column=0, sticky="")
aScreen = turtle.TurtleScreen(aCanvas)
aXScrollbar = ttk.Scrollbar(aFrame, orient="horizontal", command=aCanvas.xview)
aXScrollbar.bind("<Configure>",
lambda e: aCanvas.configure(
scrollregion=aCanvas.bbox("all")
))
aXScrollbar.grid(row=1, column=0, sticky="ew")
aYScrollbar = ttk.Scrollbar(aFrame, orient="vertical", command=aCanvas.yview)
aYScrollbar.bind("<Configure>",
lambda e: aCanvas.configure(
scrollregion=aCanvas.bbox("all")
))
aYScrollbar.grid(row=0, column=1, sticky="ns")
aTurtle = turtle.RawTurtle(aScreen)
aTurtle.goto(0, 0)
aTurtle.fillcolor('blue')
aTurtle.begin_fill()
for i in range(4):
aTurtle.forward(150)
aTurtle.right(90)
aTurtle.end_fill()
root.mainloop()
Thanks for any help!

Python's Tkinter Entry not appearing on window

I am trying to make a window that would take an input through an entry and that would be either a web address or ip address and i would use a loop to update the text of a label to show the current ping every second. But I'm stuck at the very beginning because my entry would not appear on my window. Here is my code:
import tkinter as tk
from tkinter import *
window = tk.Tk()
window.title("Server Status")
window.geometry('400x600')
window.resizable(0,0)
canvas = tk.Canvas(window,height=600,width=1000,bg='#263D42')
canvas.pack()
txtf=tk.Entry(window, width=10)
txtf.pack()
window.mainloop()
Where am I going wrong? I have tried it with several changes but still cant get it to appear there. Any help would be appreciated.
Thanks.
Your entry is below the canvas, but because (1) your window geometry specifies a smaller size than that requested for the canvas, and (2) you set it to be non resizable, you can never access it.
Choose how to resolve this conflict; the example below sets the size of the canvas, and lets the window resize to enclose all its widgets.
import tkinter as tk
window = tk.Tk()
window.title("Server Status")
canvas = tk.Canvas(window, height=600, width=1000, bg='#263D42')
canvas.pack()
txtf = tk.Entry(window, width=10)
txtf.pack()
window.mainloop()

How to access entries beyond the window size in Tkinter

I am creating a form with 40 labels and entries. The problem is that I can enter till 20 after that the window size reaches the maximum and I cannot see entries below it. How do I integrate a scrolling option in Tkinter main window? I know that scrollbar cannot be integrated into main window and only to widgets. I want something so that I can either scroll using mouse or arrow keys or anything to see below content. Below is my code:
from Tkinter import *
root = Tk()
root.title('test')
root.geometry("400x400")
for i in range(40):
Label(root, text="Field {} ".format(i)).grid(row=i,column=0)
value=Entry(root).grid(row=i,column=1)
root.mainloop()
Output image
ListBox
Scrollbars are almost always used in conjunction with Listbox, Canvas or Text widget. To connect a vertical scrollbar to one of these widgets you have to do two things:
Set the widget’s yscrollcommand callbacks to the set method of the scrollbar.
Set the scrollbar’s command to the yview method of the widget.
Example
from tkinter import *
master = Tk()
scrollbar = Scrollbar(master)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = Listbox(master, yscrollcommand=scrollbar.set)
for i in range(40):
listbox.insert(END, Label(master, text=f"Field {i} "))
listbox.insert(END, Entry(master))
listbox.pack(side=LEFT, fill=BOTH)
scrollbar.config(command=listbox.yview)
mainloop()

Tkinter : How to center the window title

I am creating a project using tkinter and when I create a window, I couldn't seem to get the window title to center itself (Like most programs nowadays). Here's the example code:
from tkinter import *
root = Tk()
root.title("Window Title".center(110))# Doesn't seem to work
root.mainloop()
Is there a way to center the window title up ? Thanks in advance
There is nothing you can do. Tkinter has no control over how the window manager or OS displays the titles of windows other than to specify the text.
I came up with a trick that does the job and it consists in simply adding as much blank space before the title:
import tkinter as tk
root = tk.Tk()
root.title(" Window Title")# Add the blank space
frame = tk.Frame(root, width=800, height=200, bg='yellow')
frame.grid(row=0,column=0)
root.mainloop()
Output:
Alternatively, you can use a string consisting of an empty space and concatenate it to the title after multiplication. I mean:
import tkinter as tk
root = tk.Tk()
blank_space =" " # One empty space
root.title(80*blank_space+"Window Title")# Easier to add the blank space
frame = tk.Frame(root, width=800, height=200, bg='yellow')
frame.grid(row=0,column=0)
root.mainloop()
More adding onto what Billal suggested is this example that adjust depending on the window size. I still wouldn't recommend it since it's just a hack for visual aesthetics but if you really want to have it.
import tkinter as tk
def center(e):
w = int(root.winfo_width() / 3.5) # get root width and scale it ( in pixels )
s = 'Hello Word'.rjust(w//2)
root.title(s)
root = tk.Tk()
root.bind("<Configure>", center) # called when window resized
root.mainloop()
width=root.winfo_screenwidth()
spacer=(" "*(int(width)//6))
root.title(spacer+"Your title")
This is not that much perfect but this will work.

Is there a tkinter equivalent for Perl/Tk's Scrolled pseudo-widget?

Perl/Tk has a pseudo-widget Tk::Scrolled that takes as its argument another widget and adds a corresponding scrollbar according to options (where to put it in relation to the widget and if to show at all if there is nothing to scroll). For example, to have a listbox with a scrollbar to the right that disappears if the listbox can display all entries you just have to say:
my $Listbox = $MW->Scrolled ('Listbox', -scrollbars => 'oe');
Has tkinter (3.3.2) some equivalent functionality?
Tkinter has a Scrollbar class that can be used to wrap widgets in a scrollbar. It may not be as concise to configure as perl, but you can set it up to do what you are asking for without too much hassle.
Here are some examples of the scrollbar in use:
from Tkinter import *
root = Tk()
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = Listbox(root)
listbox.pack()
for i in range(100):
listbox.insert(END, i)
# attach listbox to scrollbar
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)
mainloop()

Categories