Reputation: 2757
I have been coding an application which is pretty much a fancy text editor, and I have been getting problems with resizing the widgets inside it. My goal is for it to look a bit like IDLE with a horizontal scrollbar as well.
from tkinter import *
from tkinter import ttk
root = Tk()
width = preset frame width in relation to root
hieght = preset frame height in relation to root
frame = ttk.Frame(master=root, width=width, height=height)
frame.grid()
frame.grid_propagate(False)
vbar = ttk.Scrollbar(root, orient=VERTICAL)
hbar = ttk.Scrollbar(root, orient=HORIZONTAL)
vbar.grid(row=0, column=1, sticky=N S)
hbar.grid(row=1, column=0, sticky=E W)
text_widget = Text(frame, width=189, height=47, wrap=NONE, undo=True, yscrollcommand=vbar.set, xscrollcommand=hbar.set)
text_widget.grid()
vbar.config(command=text_widget.yview)
hbar.config(command=text_widget.xview)
I am using python 3.7, windows 10 and PyCharm. If you find a duplicate of this question, please comment and let me check it out before marking as a duplicate and or closing, for i have yet to find an answer. it works, just resizing is the issue. it should behave a bit like windows notepad with word wrap off.
Upvotes: 0
Views: 1900
Reputation: 4730
This is a relatively simple problem to solve.
If you wished to continue creating the program using the Grid
geometry manager, you will need to familiarise yourself with the Grid.rowconfigure()
and Grid.columnconfigure()
functions.
These allow you to set the configuration options for the Grid
geometry manager within the confines of a container widget. Specifically, the attribute we care about is weight
. As explained here:
Every column and row has a "weight" grid option associated with it, which tells it how much it should grow if there is extra room in the master to fill. By default, the weight of each column or row is 0, meaning don't expand to fill space.
For the user interface to resize then, we'll need to give a positive weight to the columns we'd like to expand. This is done using the "columnconfigure" and "rowconfigure" methods of grid. If two columns have the same weight, they'll expand at the same rate; if one has a weight of 1, another of 3, the latter one will expand three pixels for every one pixel added to the first.
(emphasis mine)
So, in this case we need to make a few changes. Firstly, we need to add sticky = "NESW"
to both the frame.grid()
and text_widget.grid()
calls, otherwise the Text
widget won't expand with the scrollbars. Secondly, we need to add the below snippet to the program:
Grid.columnconfigure(root, 0, weight=1)
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(frame, 0, weight=1)
Grid.rowconfigure(frame, 0, weight=1)
This ends up with the below program (after making some changes so I can actually run the provided example):
from tkinter import *
from tkinter import ttk
root = Tk()
frame = ttk.Frame(master=root)
frame.grid(sticky="NSEW")
vbar = ttk.Scrollbar(root, orient=VERTICAL)
hbar = ttk.Scrollbar(root, orient=HORIZONTAL)
vbar.grid(row=0, column=1, sticky="NS")
hbar.grid(row=1, column=0, sticky="EW")
text_widget = Text(frame, wrap=NONE, undo=True, yscrollcommand=vbar.set, xscrollcommand=hbar.set)
text_widget.grid(sticky="NSEW")
vbar.config(command=text_widget.yview)
hbar.config(command=text_widget.xview)
Grid.columnconfigure(root, 0, weight=1)
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(frame, 0, weight=1)
Grid.rowconfigure(frame, 0, weight=1)
As a side note, it would be very simple to rebuild this program using the Pack
geometry manager which is (subjectively) more intelligent when it comes to resizing widgets:
from tkinter import *
from tkinter import ttk
root = Tk()
frame = ttk.Frame(master=root)
frame.pack(expand=True, fill="both")
vbar = ttk.Scrollbar(frame, orient=VERTICAL)
hbar = ttk.Scrollbar(root, orient=HORIZONTAL)
vbar.pack(side="right", fill="y")
root.update()
hbar.pack(side="bottom", fill="x", padx=vbar.winfo_width())
text_widget = Text(frame, wrap=NONE, undo=True, yscrollcommand=vbar.set, xscrollcommand=hbar.set)
text_widget.pack(expand=True, fill="both")
vbar.config(command=text_widget.yview)
hbar.config(command=text_widget.xview)
Upvotes: 1