Tkinter Label: Retain Height when I change font to smaller size - python-3.x

I have an Label for a quite advanced calculator app.
I'd like to be able to change the font size when the text entered gets too long, to be able to enter more, but retain the height of the widget just for good looks.
Here's piece of code I tried:
self.biglabelfont = font.Font(family = "Arial", size = 24, weight = "bold")
self.entrylabel = Label(... font = self.biglabelfont ....)
self.entrylabel.pack(side = LEFT, fill = "x", expand = True)
self.entrylabel.propagate(0)
self.biglabelfont = font.Font(family = "Arial", size = 11, weight = "bold")
self.entrylabel.config(font = self.biglabelfont)
But it keeps shrinking the height.

Your choice to use pack_propagate is good, but you're doing it wrong. You must call it on the parent of the label widget, not on the label widget.
Here's a working example. Notice that the height of the sunken area doesn't change as the font grows and shrinks.
import Tkinter as tk
import tkFont
BG = "white"
HEIGHT = 75
def main():
global the_font, root
root = tk.Tk()
the_font = tkFont.Font(family="helvetica", size=18)
toolbar = make_toolbar(root)
subframe = make_subframe(root)
toolbar.pack(side="top", fill="x")
subframe.pack(side="top", fill="x")
root.geometry("400x400")
root.mainloop()
def make_subframe(parent):
frame = tk.Frame(parent, height=HEIGHT, borderwidth=1, relief="sunken", background=BG)
frame.pack_propagate(False)
label = tk.Label(frame, font=the_font, text="0123455.67890", background=BG)
label.pack(side="top", fill="both", expand=True)
return frame
def font_plus():
size = the_font.cget("size")
size += 2
the_font.configure(size=size)
def font_minus():
size = the_font.cget("size")
size -= 2
the_font.configure(size=size)
def make_toolbar(parent):
toolbar = tk.Frame(root)
grow = tk.Button(toolbar, text="Bigger", command=font_plus)
shrink = tk.Button(toolbar, text="Smaller", command=font_minus)
grow.pack(side="left")
shrink.pack(side="left")
return toolbar
main()

Related

Im having troubles with python(tkinter) gui with the layout

# Import module
from tkinter import *
import pyautogui, time
# Create object
root = Tk()
# Adjust size
root.geometry("350x350")
root.title("SycoBak's SpamBot")
# Add image file
bg = PhotoImage(file = "Slogo.png")
# Create Canvas
canvas1 = Canvas( root, width = 350,
height = 350)
canvas1.pack(fill = "both", expand = True)
# Display image
canvas1.create_image( 0, 0, image = bg,
anchor = "nw")
canvas1.create_text(250,250, text="SycoSpamBot")
L1 = Label(canvas1, text="Word")
L1.pack( side = LEFT)
E1 = Entry(canvas1)
E1.pack(side = RIGHT)
canvas1.create_window(100, 100, window=L1)
L2 = Label(canvas1, text="Amount")
L2.pack( side = LEFT)
E2 = Entry(canvas1)
E2.pack(side = RIGHT)
canvas1.create_window(100, 150, window=L2)
def Spammer ():
time.sleep(5)
x = 0
amount = int(E2.get())
word = E1.get()
while (amount > x):
pyautogui.typewrite(word)
pyautogui.press("enter")
x=x+1
button1 = Button(root, text = "Start", command=Spammer, bg="green")
button1_canvas = canvas1.create_window( 100, 10,
anchor = "nw",
window = button1)
root.mainloop()
Im wondering if I could make it so that the start button is at the bottom, and the word and amount labels are on the left side of a text input box.
This is how my GUI layout currently looks like. (Very Messy)
[1]: https://i.stack.imgur.com/UYvtU.png

Tkinter: How to make a rounded corner text widget?

Question
How to create a rounded corner text widget? I think I have an idea of creating a rounded canvas and fill the entire canvas with the text box with no border.
Problem
The code to create a rounded border canvas is not working when I try to extend the height and width of the canvas. The line breaks and becomes discontinuous.
The code to create rounded corner canvas is taken from How to make a tkinter canvas rectangle with rounded corners?
My code with custom width and height
def rounded_rect(canvas, x, y, w, h, c):
canvas.create_arc(x, y, x+2*c, y+2*c, start= 90, extent=90, style="arc")
canvas.create_arc(x+w-2*c, y+h-2*c, x+w, y+h, start=270, extent=90, style="arc")
canvas.create_arc(x+w-2*c, y, x+w, y+2*c, start= 0, extent=90, style="arc")
canvas.create_arc(x, y+h-2*c, x+2*c, y+h, start=180, extent=90, style="arc")
canvas.create_line(x+c, y, x+w-c, y )
canvas.create_line(x+c, y+h, x+w-c, y+h )
canvas.create_line(x, y+c, x, y+h-c)
canvas.create_line(x+w, y+c, x+w, y+h-c)
import tkinter
root = tkinter.Tk()
canvas = tkinter.Canvas(root)
canvas.grid(row=0,column=0)
# The width and height has been changed from the original solution
rounded_rect(canvas, 10, 10, 330, 290, 10)
root.mainloop()
Output
One solution is to use a ttk frame with a custom style that uses an image for the corners.
The following example is adapted from a tcl/tk solution I wrote back in 2007. It uses an odd color for the focus, and requires a white background, but you could create your own image to replace the one used in this solution (or edit the image in this example1)
# adapted from http://wiki.tcl.tk/%0920152
import tkinter as tk
from tkinter import ttk
focusBorderImageData = '''
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
Ry/99NIz//oGrZpUUEAAOw==
'''
borderImageData = '''
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
'''
root = tk.Tk()
style = ttk.Style()
borderImage = tk.PhotoImage("borderImage", data=borderImageData)
focusBorderImage = tk.PhotoImage("focusBorderImage", data=focusBorderImageData)
style.element_create("RoundedFrame",
"image", borderImage,
("focus", focusBorderImage),
border=16, sticky="nsew")
style.layout("RoundedFrame",
[("RoundedFrame", {"sticky": "nsew"})])
frame1 = ttk.Frame(style="RoundedFrame", padding=10)
text1 = tk.Text(frame1, borderwidth=0, highlightthickness=0, wrap="word",
width=40, height=4)
text1.pack(fill="both", expand=True)
text1.bind("<FocusIn>", lambda event: frame1.state(["focus"]))
text1.bind("<FocusOut>", lambda event: frame1.state(["!focus"]))
text1.insert("end", "This widget has the focus")
frame2 = ttk.Frame(style="RoundedFrame", padding=10)
text2 = tk.Text(frame2, borderwidth=0, highlightthickness=0, wrap="word",
width=40, height=4)
text2.pack(fill="both", expand=True)
text2.bind("<FocusIn>", lambda event: frame2.state(["focus"]))
text2.bind("<FocusOut>", lambda event: frame2.state(["!focus"]))
text2.insert("end", "This widget does not have the focus")
root.configure(background="white")
frame1.pack(side="top", fill="both", expand=True, padx=20, pady=20)
frame2.pack(side="top", fill="both", expand=True, padx=20, pady=20)
frame1.focus_set()
root.mainloop()
1The image data is a base64-encoded gif. If you decode the data and save it to a .gif file, you can edit it to use any colors you want.
Your canvas simply isn't large enough. Make it larger using
canvas = tkinter.Canvas(root, width=500, height=500)
Or make it resize with the root window using
canvas = tkinter.Canvas(root)
canvas.grid(row=0,column=0, sticky='NSEW')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
I ran into this issue as well except for the main window. I was making a sticky notes app for someone and they wanted the window's corners to be rounded.
I had 4 canvases in the 4 corners with the image of an arc based on the corners. Then I made the color of those images transparent and it worked surprisingly well so I wanted to share it.
Here is the code:
from tkinter import *
from PIL import Image,ImageTk
def drag(event,win):
x = win.winfo_pointerx() - win.offsetx
y = win.winfo_pointery() - win.offsety
win.geometry('+{x}+{y}'.format(x=x,y=y))
def click(event,win):
win.offsetx = event.x
win.offsety = event.y
root = Tk()
root.resizable(False,False)
root.geometry("610x260")
img = ImageTk.PhotoImage( Image.open("src/ARC.png").resize((150,150)), Image.ANTIALIAS )
img2 = ImageTk.PhotoImage( Image.open("src/ARC 2.png").resize((150,150)), Image.ANTIALIAS )
img3 = ImageTk.PhotoImage( Image.open("src/ARC 3.png").resize((150,150)), Image.ANTIALIAS )
img4 = ImageTk.PhotoImage( Image.open("src/ARC 4.png").resize((150,150)), Image.ANTIALIAS )
fr = Frame(root, bg = "yellow", bd = 0)
fr.pack( expand = True, fill = 'both')
canvas = Canvas(fr, bg = "yellow", width = 60, height = 60, bd=0, highlightthickness=0, relief='ridge')
canvas.create_image(-2,-2, image = img, anchor = "nw")
canvas2 = Canvas(fr, bg = "yellow", width = 60, height = 60, bd=0, highlightthickness=0, relief='ridge')
canvas2.create_image(62,-2, image = img2, anchor = "ne")
canvas3 = Canvas(fr, bg = "yellow", width = 60, height = 60, bd=0, highlightthickness=0, relief='ridge')
canvas3.create_image(-2,62, image = img3, anchor = "sw")
canvas4 = Canvas(fr, bg = "yellow", width = 60, height = 60, bd=0, highlightthickness=0, relief='ridge')
canvas4.create_image(62,62, image = img4, anchor = "se")
Grid.columnconfigure(fr, 0, weight = 1)
Grid.columnconfigure(fr, 1, weight = 1)
Grid.rowconfigure(fr, 1, weight = 1)
canvas.grid( row = 0, column = 0, sticky = 'NW' )
canvas2.grid( row = 0, column = 1, sticky = 'NE' )
canvas3.grid(row = 1, column = 0, sticky = 'SW' )
canvas4.grid(row = 1, column = 1, sticky = 'SE' )
root.overrideredirect(True)
root.wm_attributes('-transparentcolor', "#222222")
root.bind('<Button-1>', lambda e, root = root: click(e,root))
root.bind('<B1-Motion>', lambda e, root = root: drag(e,root))
root.mainloop()
Now you'd probably change the rows and columns of the canvases based on what you want inside the window but this is a good start.

How do I change font size for Tkinter Scrolling Text

I am using this code to make a scrolling text window using Tkinter with python 3.5, and I was curious what I could do to change the font size and color of the scrolling text.
import tkinter as tk
root = tk.Tk()
deli = 100 # milliseconds of delay per character
svar = tk.StringVar()
labl = tk.Label(root, textvariable=svar, height=5)
def shif():
shif.msg = shif.msg[1:] + shif.msg[0]
svar.set(shif.msg)
root.after(deli, shif)
shif.msg = 'Text example: Blah, Blah Blah'
shif()
labl.pack()
root.mainloop()
You just can't change the font-size of Scrollbar, because it doesn't have font-size.
You can change the font-size of Text. It has a font module.
textarea = Text(root, font=("Arial 45"))
def create_scrolltext(self):
F_font = ('bold', 30)
scroll_w = 30
scroll_h = 10
scrollText = scrolledtext.ScrolledText(self, width=scroll_w, height=scroll_h, wrap = tk.WORD, font=F_font)
scrollText.grid(column=0, columnspan=3)
def create_scrolltext(self):
F_font = ('bold', 30)
scroll_w = 30
scroll_h = 10
scrollText = scrolledtext.ScrolledText(self, width=scroll_w, height=scroll_h, wrap = tk.WORD, font=F_font)
scrollText.config(bg='white', fg='blue')
scrollText.grid(column=0, columnspan=3)

How can I add text and image inside a frame in Python using tkinter

I am writing my first programming codes. I want to know if I can add text and image label inside a frame. I created a canvas and added two frames to it and then tried to add image and text file (to be displayed at the top of the canvas) but the text and picture do not show. When I run the program without the frames, it does show. Here is the code:
#
from tkinter import *
from tkinter import ttk
root = Tk()
root.title ('iMedic')
canvas = Canvas(root, width = 1600, height = 800)
panewindow = ttk.Panedwindow(canvas, orient = VERTICAL)
panewindow.pack(fill = BOTH, expand = True)
paitents_frame = ttk.Frame(panewindow, width = 1600, height = 400, relief = RAISED)
prescription_frame = ttk.Frame(panewindow, width = 1600, height = 300, relief = RAISED)
panewindow.add(paitents_frame, weight = 1)
panewindow.add(prescription_frame, weight = 1)
canvas.grid(row = 0, column = 0)
photo = PhotoImage(file = './logo.gif')
canvas.create_image(55, 55, image=photo)
canvas.create_text(600, 155, text = 'Welcome', font = ('Helvetica', 72, 'bold'), justify = 'center', fill='blue')
canvas.update
root.mainloop()
#
Is there a way I can fix this? I would assume another way would be to have the pic and text on top and then add frames below it but I don't know how to do it. Thanks!
It's not clear to me why you're adding frames to a canvas but going by the later statement;
I would assume another way would be to have the pic and text on top and then add frames below it but I don't know how to do it.
Here is how you could do it:
Make the panewindow child of root instead of child of canvas
The frames resize to fit their content so I added two labels in each
to make them visible, you should replace those labels with whichever
widgets you need.
I used pack for all the widget placements but you can replace them
with grid and provide the appropriate row and column values.
**
from tkinter import *
from tkinter import ttk
root = Tk()
root.title ('iMedic')
canvas = Canvas(root, width = 1600, height = 250)
canvas.pack(fill = BOTH, expand = True)
photo = PhotoImage(file = './logo.gif')
canvas.create_image(55, 55, image=photo)
canvas.create_text(600, 155, text = 'Welcome', font = ('Helvetica', 72, 'bold'), justify = 'center', fill='blue')
canvas.update
# Make panewindow child of root
panewindow = ttk.Panedwindow(root, orient = VERTICAL)
panewindow.pack(fill = BOTH, expand = True)
# paitents_frame with Labels in it
paitents_frame = ttk.Frame(panewindow, width = 1600, height = 400, relief = RAISED)
paitents_label1 = Label(paitents_frame, text="Name Label")
paitents_label1.pack()
paitents_label2 = Label(paitents_frame, text="Name Label")
paitents_label2.pack()
# prescription_frame with Labels in it
prescription_frame = ttk.Frame(panewindow, width = 1600, height = 300, relief = RAISED)
prescription_label1 = Label(prescription_frame, text="Prescription Text")
prescription_label1.pack()
prescription_label2 = Label(prescription_frame, text="Prescription Text")
prescription_label2.pack()
# Add the frames to panewindow
panewindow.add(paitents_frame, weight = 1)
panewindow.add(prescription_frame, weight = 1)
root.mainloop()
Another option is to leave out the canvas entirely and use labels to place image and text inside a frame. See this post on how to use image in labels
This code demonstrates how to place any text on any image in a Frame.
It works by creating a Label inside the Frame to hold your image and text.
Label requires the compound attribute to be set to either bottom, center, left, right, top or none
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title ('iMedic')
photo = tk.PhotoImage(file = "./logo.gif")
frame = ttk.Frame(root, relief = tk.RAISED)
frame.grid(row = 0, column = 0, sticky = tk.NSEW)
label = tk.Label(
frame, image=photo, compound = tk.CENTER,
font = "Helvetica 40 bold",
foreground = "yellow", text = "Welcome")
label.grid(row = 0, column = 0, sticky = tk.NSEW)
root.mainloop()

Cell formatting in Grid Geometry manager

I have this code:
from tkinter import *
from tkinter import ttk
class Application:
def __init__(self, master):#Change to game class when combining code
self.master = master#remove when combining code
self.frame_Canvas = ttk.Frame(self.master, width = 600, height = 600)
self.frame_Canvas.pack(side = 'left')
self.frame_Canvas.pack_propagate(False)
self.frame_Canvas.grid_propagate(False)
self.hangman = Canvas(self.frame_Canvas, width = 600, height = 600,
background = 'white').pack()
self.FullName = ttk.Label(self.frame_Canvas, text = "Full Name", background = 'white')#full name will be entered here
self.FullName.config(font=("TkDefaultFont", 20))
self.FullName.place(x = 10, y = 10)
self.frame_Interact = ttk.Frame(self.master, width = 200, height = 600)
self.frame_Interact.pack(side = 'right')
self.frame_Interact.pack_propagate(False)
self.frame_Interact.grid_propagate(False)
self.QuestionLabel = ttk.Label(self.frame_Interact, text = "Question:")
self.QuestionLabel.config(font=("TkDefaultFont", 20))
self.QuestionLabel.grid(column = 0, row = 0)
self.QuestionShow = Text(self.frame_Interact, height=1, width=8)#input question here
self.QuestionShow.config(font=("TkDefaultFont", 20))
self.QuestionShow.grid(column = 0, row = 1)#FIX THE FORMATTING OF QUESTION, GRID CELL TO LEFT, NOT BIG ENOUGTH?
self.AnswerEntry = ttk.Entry(self.frame_Interact, width = 10)#do later
def main():
root = Tk()
root.wm_title("Hangman")
Menu = Application(root)
root.resizable(width=False, height=False)
root.iconbitmap("windowicon.ico")
root.mainloop()
if __name__ == "__main__": main()
I dont know why, but the Answer box and label on the right side of my tkinter GUI is on the left side of its frame. I want it in the center. Does anyone know a way to frix it, or any improvements for the code so far. Thanks :)
There are two ways you can do this, first way will to be to use .pack() instead of .grid() since pack is very easy to use and does the aligning for you automatically.
So you can just replace:
self.QuestionLabel.grid(column = 0, row = 0)
# and
self.QuestionShow.grid(column = 0, row = 1)
With:
self.QuestionLabel.pack()
# and
self.QuestionLShow.pack()
This way isn't recommended for your situation whatsoever, since that will involve mixing pack and grid together which could cause future errors in your code.
As Bryan Oakley said:
it will cause errors immediately, if the widgets share the same parent. It won't ever cause problems if the widgets have different parents.
You should instead do this:
from tkinter import *
from tkinter import ttk
class Application:
def __init__(self, master):#Change to game class when combining code
self.master = master#remove when combining code
self.frame_Canvas = ttk.Frame(self.master, width = 600, height = 600)
self.frame_Canvas.pack(side = 'left')
self.frame_Canvas.pack_propagate(False)
self.frame_Canvas.grid_propagate(False)
self.hangman = Canvas(self.frame_Canvas, width = 600, height = 600,
background = 'white').pack()
self.FullName = ttk.Label(self.frame_Canvas, text = "Full Name", background = 'white')#full name will be entered here
self.FullName.config(font=("TkDefaultFont", 20))
self.FullName.place(x = 10, y = 10)
self.frame_Interact = ttk.Frame(self.master, width = 200, height = 600)
self.frame_Interact.pack(side = 'right')
self.frame_Interact.pack_propagate(False)
self.frame_Interact.grid_propagate(False)
Grid.columnconfigure(self.frame_Interact, 0, weight=1) # NOTE, THIS CHANGED
self.QuestionLabel = ttk.Label(self.frame_Interact, text = "Question:")
self.QuestionLabel.config(font=("TkDefaultFont", 20))
self.QuestionLabel.grid(column = 0, row = 0)
self.QuestionShow = Text(self.frame_Interact, height=1, width=8)
self.QuestionShow.config(font=("TkDefaultFont", 20))
self.QuestionShow.grid(column = 0, row = 1)
def main():
root = Tk()
root.wm_title("Hangman")
Menu = Application(root)
root.resizable(width=False, height=False)
root.iconbitmap("windowicon.ico")
root.mainloop()
if __name__ == "__main__":
main()
By adding Grid.columnconfigure(self.frame_Interact, 0, weight=1) it will help grid know how to allocate extra space. so that the label will try to take up the whole column. The same goes for rows if you're wondering, you can add Grid.rowconfigure(self.frame_Interact, 0, weight=1) to make the widgets fill the whole row.
And for some improvements to your code, you should change this line:
self.hangman = Canvas(self.frame_Canvas, width = 600, height = 600,
background = 'white').pack()
# to
self.hangman = Canvas(self.frame_Canvas, width = 600, height = 600, background = 'white')
self.hangman.pack()
Or else self.hangman will be None, as it is in your code.

Resources