Scrolled Text in Tkinter (scrollbar issue) with .grid() - python

I'm having some issues with a ScrolledText widget in tkinter.
The Scrollbar is not showing up.
Here is my code:
from tkinter import *
import os
from tkinter.scrolledtext import ScrolledText
#window variables
win = Tk()
win.title('TextS')
win_width = 600
win_height = 400
win.geometry('{}x{}'.format(win_width,win_height))
#widgets
title = Label(win, text="TextS", font=("Helvetica", 36, "bold"), bg="lightgray")
title.grid(row=0, column=0)
st = ScrolledText(win, width=400, height=300)
st.grid(column=1, pady=10, padx=10)
#main loop
while True:
win.update()
Some Screen Shots:
With .grid() what I want to use:
screenshot
With .pack() which I do not want to use:
screenshot
(Has scroll bar)
Sorry if this is a noobie mistake,
Thank you!
Have a great day! :)

ScrolledText uses width and height in chars, not in pixels - so you create very big widget and scroller doesn't fit in window. You have to use smaller values.
grid doesn't use free space when you resize (all of them use value weight=0. You have to use bigger weight to inform which row and column has to use this free space when you resize.
win.grid_columnconfigure(1, weight=1) # column 1
win.grid_rowconfigure(1, weight=1) # row 1
Now it will resize cells in row 1 and column 1 but it doesn't resize widgets in cells. Widgets needs grid(..., sticky='nsew') to resize in all directions.
import tkinter as tk # PEP8: `import *` is NOT preferred
from tkinter.scrolledtext import ScrolledText
# window variables # PEP8: one space after `#`
win = tk.Tk()
win.grid_columnconfigure(1, weight=1)
win.grid_rowconfigure(1, weight=1)
title = tk.Label(win, text="TextS", font=("Helvetica", 36, "bold"), bg="lightgray")
title.grid(row=0, column=1)
st = ScrolledText(win, width=100, height=25)
st.grid(column=1, pady=10, padx=10, sticky='nsew')
# main loop
win.mainloop()
PEP 8 -- Style Guide for Python Code

Using same code.
set geometry to 350x300
In line 20 set ScrolledText to width=40, height=10
Set column to 0 not 1
You're set to go.
Code:
from tkinter import *
import os
from tkinter.scrolledtext import ScrolledText
#window variables
win = Tk()
win.title('TextS')
win_width = 600
win_height = 400
win.geometry('350x300')
#widgets
title = Label(win, text="TextS", font=("Helvetica", 36, "bold"), bg="lightgray")
title.grid(row=0, column=0)
st = ScrolledText(win, width=40, height=10)
st.grid(column=0, pady=10, padx=10)
#main loop
while True:
win.update()
win.mainloop()
Screenshot output:

Related

How should I change my tkinter code to rearrange the elements on my page?

I'm learning tkinter and getting stumped in one area. Here's the code:
from tkinter import *
from tkinter.messagebox import showinfo
def button_press():
showinfo('info','pressed button')
root = Tk()
root.geometry('800x500')
f = Frame(root)
f.pack()
Label(f, text="this is a line of text").pack(side=LEFT)
s = StringVar(value='enter here')
Entry(f, textvariable=s, width=100).pack(side=LEFT)
Button(f, text='Button', command=button_press).pack(side=RIGHT)
root.mainloop()
It produces:
But I want to align the text vertically with the entry field like this:
What do I need to change to make that happen?
Using .pack() is not advisable if you want to create more complex Frame structures.
Instead assign the items to variables and place those into a .grid().
.grid splits up your frame into different rows and columns or "sticks" them on a certain place.
below an example:
from tkinter import *
from tkinter.messagebox import showinfo
def button_press():
showinfo('info', 'pressed button')
root = Tk()
root.geometry('800x500')
f = Frame(root)
f.pack()
l1 = Label(f, text="this is a line of text")
l1.grid(row=1, column=1, sticky=W)
s = StringVar(value='enter here')
entry = Entry(f, textvariable=s, width=100)
entry.grid(row=2, column=1)
button = Button(f, text='Button', command=button_press)
button.grid(row=2, column=2)
root.mainloop()

How to make text show up in a specific location on a Tkinter window

please see the code below. Working on a 100 days of code project. How to I make text appear in a specific position (x=400, y=150) for example on a window.
Please see my code below.
from tkinter import *
from tkinter import messagebox
BACKGROUND_COLOR = "#B1DDC6"
window = Tk()
window.title('Flashy')
window.config(padx=50, pady=50, bg=BACKGROUND_COLOR)
# Todo. Center the front of the card.
canvas = Canvas(width=800, height=526, bg=BACKGROUND_COLOR, highlightthickness=0)
card_front = PhotoImage(file='images/card_front.png')
canvas.create_image(400, 263, image=card_front)
canvas.grid(row=0, column=1, columnspan=2)
# Placing text on the card.
text_1 = Label(text="French", bg='white', font=("Ariel", 40, "italic"), fg='black')
text_1.goto(x=400, y=150)
text_1.grid(row=0, column=0, columnspan=2)
# Buttons
check_mark = PhotoImage(file='images/right.png')
check_mark_button = Button(image=check_mark, highlightthickness=0)
check_mark_button.grid(row=1, column=2)
wrong_mark = PhotoImage(file='images/wrong.png')
wrong_mark_button = Button(image=wrong_mark, highlightthickness=0)
wrong_mark_button.grid(row=1, column=1)
window.mainloop()
I tried using .config to specify the location for the text but that doesn't work.
Use the place() geometry manager to place widgets at specific coordinates.
Instead of:
text_1.goto(x=400, y=150)
Try...
text_1.place(x=400, y=150)
And remove:
text_1.grid(row=0, column=0, columnspan=2)
since you should only use one geometry manager method (pack, grid, or place) on a given widget.

Tkinter center Label in the GUI

import tkinter as tk
from tkinter import *
HEIGHT = 600
WIDTH = 600
root = tk.Tk()
def button_event1():
import ThreePlayers
print(ThreePlayers)
def button_event2():
import TwoPlayersGame
print(TwoPlayersGame)
def button_event3():
print("")
def button_event4():
print("")
def button_event5():
quit()
root = Tk()
root.title('Connect 4 Game')
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
L.config(anchor=CENTER)
L.pack()
button = tk.Button(root, text="3 Player Game", command=button_event1)
button.pack()
button = tk.Button(root, text="2 Player Game", command=button_event2)
button.pack()
button = tk.Button(root, text="1 Player Game", command=button_event3)
button.pack()
button = tk.Button(root, text="Options", command=button_event4)
button.pack()
button = tk.Button(root, text="QUIT", command=button_event5)
button.pack()
root.mainloop()
Above is my Code for a Tkinter GUI but I want the have the label at the center of the root/window how do I do that? Currently its sitting on top of the buttons everything else is fine the button events and such works
In my opinion, you should have used place or grid instead of pack. Because pack only gives few alignment options.
otherwise, maybe divide the main window into two frames then pack the label at the top of the lower frame
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
L.pack(side = TOP)
I wish this helps. but you should use grid for better alignment or place.
You can use the following commands to place the label in the center
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
# L.config(anchor=CENTER)
# L.pack()
L.place(x=HEIGHT/2, y=WIDTH/2, anchor="center")
Similarly, you can also use button.place(x=100, y=25) for buttons
REF: Tkinter: Center label in frame of fixed size?

Tkinter how to size fonts and keep alignment

I'm writing an app that needs to be zoomable. Using the default system fonts, "TkDefaultFont and TkTextFont" I increase their sizes and I get the results I want sort of. The problem is after sizing the alignment is thrown off between the field label and field widget. I have tried applying update_idletasks() but it does nothing. Moving the mouse over the widget fixes the problem as see in the video. If you run the example below go the the size spinbox and change the size to view the issue.
My dev system is Linux, Desktop KDE, I don't know if this is a OS issue.
A link to a short video of the issue.
Video of Alignment Issue.
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
root = tk.Tk()
root.rowconfigure(0, weight=1)
root.columnconfigure(99, weight=1)
frame = ttk.Frame(root)
frame.rowconfigure(0, weight=1)
frame.columnconfigure(0, weight=1)
cbo = ttk.Combobox(frame)
cbo.config(
values=('Test 1', 'Test 2', 'Test 3')
)
cbo.set(value='Test 1')
ent_var = tk.StringVar()
ent = ttk.Entry(frame, textvariable=ent_var)
ent_var.set('Test')
lb_size = ttk.Label(frame, text='size')
spn = ttk.Spinbox(frame, values=tuple(range(1, 101)))
font1 = tkfont.nametofont('TkDefaultFont')
font2 = tkfont.nametofont('TkTextFont')
lbl_field_name = tk.Label(frame, text='Field Name')
lbl_field_name.grid()
def size(e):
cfg = font1.actual()
cfg['size'] = e.widget.get()
font1.configure(**cfg)
font2.configure(**cfg)
spn.bind('<<Increment>>', size)
spn.bind('<<Decrement>>', size)
cbo.grid(row=0, column=1, sticky=tk.NSEW)
ent.grid(row=0, column=2, sticky=tk.NSEW)
lb_size.grid(row=0, column=3, sticky=tk.NSEW)
spn.grid(row=0, column=4, sticky=tk.NSEW)
frame.grid(sticky=tk.NSEW)
root.mainloop()
The only way I have found to avoid this issue is to change the font from each entry's configure() method. I guess the easier way will be to put all the entries in a list, see code below.
I have also noticed that size() uses the previous value of the spinbox not the one after the increment/decrement. To avoid that, I suggest you to use the command option of the spinbox instead of the bindings to <<Increment>> and <<Decrement>> (see code below).
Finally, you do not need to retrieve the whole font settings to update the size, you can simply do font1.configure(size=<newsize>).
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
root = tk.Tk()
root.rowconfigure(0, weight=1)
root.columnconfigure(99, weight=1)
frame = ttk.Frame(root)
frame.rowconfigure(0, weight=1)
frame.columnconfigure(0, weight=1)
entries = [] # list of all entries
cbo = ttk.Combobox(frame)
cbo.config(
values=('Test 1', 'Test 2', 'Test 3')
)
cbo.set(value='Test 1')
entries.append(cbo)
ent_var = tk.StringVar()
ent = ttk.Entry(frame, textvariable=ent_var)
ent_var.set('Test')
entries.append(ent)
def size():
size = spn.get() # get current spinbox's value
font1.configure(size=size)
font2.configure(size=size)
for e in entries: # update font in all entries
e.configure(font=font2)
lb_size = ttk.Label(frame, text='size')
# use the command option to update the font size
spn = ttk.Spinbox(frame, command=size, values=tuple(range(1, 101)))
font1 = tkfont.nametofont('TkDefaultFont')
font2 = tkfont.nametofont('TkTextFont')
lbl_field_name = ttk.Label(frame, text='Field Name')
lbl_field_name.grid()
cbo.grid(row=0, column=1, sticky=tk.NSEW)
ent.grid(row=0, column=2, sticky=tk.NSEW)
lb_size.grid(row=0, column=3, sticky=tk.NSEW)
spn.grid(row=0, column=4, sticky=tk.NSEW)
frame.grid(sticky=tk.NSEW)
root.mainloop()

Using tkinter grid

I am fairly new to using .grid in tkinter and was wondering how I could get the l2 variable to be right under the l1 variable. When the code is run the 2nd label is too far down (even have to resize window). I would like to be able to place it in a specific place (below l1) but I'm not sure how to.
Thank you.
Example:
Welcome
Please log-in to continue
Gap's a little big there as well.
Current code:
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.geometry("1300x720")
myImage = PhotoImage(file='ssf.png')
label = Label(image=myImage)
label.grid(row=0)
label.image = myImage
l1 = Label(root, text="Welcome", font="Arial 100 bold", anchor="e").grid(row=0, column=1)
l2 = Label(root, text="Please log-in to continue.", font="Arial 30 bold", anchor="e").grid(row=10, column=1)
Preview of how it looks
Well, you can use the Frame widget to put the text in it like this:
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.geometry("1300x720")
myImage = PhotoImage(file='ssf.png')
label = Label(image=myImage)
label.grid(row=0)
label.image = myImage
labelFrame = Frame(root)
labelFrame.grid(row=0,column=1)
l1 = Label(labelFrame, text="Welcome", font="Arial 100 bold", anchor="e")
l1.grid(row=0, column=0)
l2 = Label(labelFrame, text="Please log-in to continue.", font="Arial 30 bold", anchor="e")
l2.grid(row=1, column=0)
The Frame widget is in row 0, column 1 and contains 'l1' and 'l2'.
Pls see my comments in the revised code below.
I would recommend drawing out the grid system on paper to visualise
your layout and compare it with what is created by your program.
Activating the background color of the widgets such as frame and
label will help you visualize your creation.
Recommend reading these references.
http://www.tkdocs.com/tutorial/grid.html
http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/layout-mgt.html
Happy coding. :)
#from tkinter import *
#from tkinter.ttk import *
## I suggest you abbreviate the imported modules to help you keep track of which
## module methods/functions you are using. See below. To be consistent, we will
## use ttk widgets where possible.
# Load tkinter for python 3
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
root.geometry("1300x720")
# Customise style of ttk widgets
# I have added this to help you visualise the grid system.
s=ttk.Style()
s.configure('frame1.TFrame', background='pink')
s.configure('l0.TLabel', background='blue')
s.configure('l1.TLabel', background='green')
s.configure('l2.TLabel', background='brown')
# Create a frame inside root to contain all the widgets.
# The frame contains a 2x2 grid.
frame1 = ttk.Frame(root, style='frame1.TFrame', borderwidth=20, relief=tk.SUNKEN )
frame1.grid(row=0, column=0, rowspan=2, columnspan=2, sticky='nsew')
# Load Image
# Added tk in fromt of PhotoImage.
myImage = tk.PhotoImage(file='ssf.png')
# Create a ttk.label to contain image
## I added ttk in front of Label. If not, it will mean you will use tk.Label instead of ttk.Label.
## Also I added frame1 as the 1st option to the ttk.Label to mean the ttk.Label
## is inside frame1.
## The "in_=frame1" option is added to grid to mean l0 is grid inside frame1 grid system.
l0 = ttk.Label(frame1, image=myImage, width=500)
l0.grid(in_=frame1, row=0, column=0, sticky='nsew')
#label.image = myImage
# Create a ttk.Label to contain l1
l1 = ttk.Label(frame1, text="Welcome", style='l1.TLabel', font="Arial 100 bold", anchor=tk.E)
l1.grid(in_=frame1, row=0, column=1)
#l1 = Label(root, text="Welcome", font="Arial 100 bold", anchor="e").grid(row=0, column=1)
# Create a ttk.Label to contain l2
l2 = ttk.Label(frame1, text="Please log-in to continue.", style='l2.TLabel', font="Arial 30 bold")
l2.grid(in_=frame1, row=1, column=1)
#l2 = Label(root, text="Please log-in to continue.", font="Arial 30 bold", anchor="e").grid(row=10, column=1)
# These configuration settings will let the grid columns and rows scale according
# to the changing size of the Window i.e. root.
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame1.rowconfigure(0, weight=1)
frame1.columnconfigure(1, weight=1)

Categories

Resources