Tkinter textfield size doesn't reach frame size - text

The textfield does't expand to the size of textfield_frame = frame. Why?
Later I want to place more widgets into more frames, that's why here i started with one frame inside the root frame.
thanks in advance.
import Tkinter
root = Tkinter.Tk()
ScreenSizeX = root.winfo_screenwidth()
ScreenSizeY = root.winfo_screenheight()
FrameSizeX = int(ScreenSizeX * 0.7)
FrameSizeY = int(ScreenSizeY * 0.7)
FramePosX = (ScreenSizeX - FrameSizeX)/2
FramePosY = (ScreenSizeY - FrameSizeY)/2
root.geometry("%dx%d%+d%+d"%(FrameSizeX,FrameSizeY,FramePosX,FramePosY))
frame = Tkinter.Frame(root)
frame.pack()
textfield_frame_height = FrameSizeY
textfield_frame = Tkinter.Frame(frame,width=FrameSizeX,height=ScreenSizeY,bg="yellow")
textfield_frame.pack()
text = Tkinter.Text(textfield_frame)
text.pack(fill="both", expand=1)
root.mainloop()

Textfield fits to textfield_frame exactly. But textfield_frame and frame do not fit to root:
frame.pack(fill="both", expand=1)
textfield_frame.pack(fill="both", expand=1)

Related

Widget in a second frame in a main class does not appear

I am trying to add a second frame inside my main class and put there a few widgets. I created a frame by using a method and assigned one of the widget to that frame but the problem is it does not appear.
I provided below piece of code with window configuration and 2x Labels which are at the main frame (Both appear correctly) and one in the new frame which appearing problem.
If you have some idea, please help me :)
import tkinter as tk
class MainApplication(tk.Tk):
def __init__(self):
super().__init__()
# Adding a background picture
self.background_img = tk.PhotoImage(file="in office.png")
back_ground_img_label = tk.Label(self, image=self.background_img)
back_ground_img_label.pack(fill="both", expand=True)
# Adjusting the window
width_of_window = 1012
height_of_window = 604
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
x_coordinate = int((screen_width / 2) - (width_of_window / 2))
y_coordinate = int((screen_height / 2) - (height_of_window / 2) - 30)
self.geometry(
f"{width_of_window}x{height_of_window}+{x_coordinate}+{y_coordinate}"
)
self.bet_frame()
bet_value_label_bg = tk.Label(self)
bet_value_label_bg.place(x=462, y=300)
coin_button_1 = tk.Button(self.frame)
coin_button_1.place(x=233, y=435)
def bet_frame(self):
self.frame = tk.Frame(width=1012, height=604)
self.frame.pack()
if __name__ == "__main__":
MainApplication().mainloop()
The only thing you put in the self.frame is the coin_button_1, but as you place it at (233, 435) is is hidden below the main window self.
Personally I would not use place but rather either pack or even better grid to place the widgets on the screen (see Setting Frame width and height)
So if you change def bet_frame(self) as follows it will be visible
...
bet_value_label_bg = tk.Label(self, text='value')
bet_value_label_bg.place(x=462, y=300)
def bet_frame(self):
self.frame = tk.Frame(master=self, width=1012, height=604)
self.frame.pack()
coin_button_1 = tk.Button(self.frame, text='coin button')
coin_button_1.pack()
...
Note the bet_value_label_bg shows up in the middle of the picture and you may have to expand the main window to make the self.frame visible, depending on the size of the picture.

Tkinter not able to fill the text box to the frame using grid. Used styling to add shadow and focus

Description
I am creating a canvas with scrollbar and adding frames with a text box in the frame and to fill the entire frame with no border. This will make it look as if the frame is the textbox. I have added shadow and styling to the frame (as coded by Bryan). This is added dynamically in for loop.
When I am trying to expand the text box to the frame, it is not expanding to fill the entire frame. There are extra spaces left.
Question
How do I fill up the entire frame with the textbox using a grid?
Code
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"})])
root.configure(background="white")
canvas = tk.Canvas(root)
scroll = tk.Scrollbar(root, orient='horizontal', command=canvas.xview)
canvas.configure(xscrollcommand=scroll.set)
frame = tk.Frame(canvas) # frame does not get pack() as it needs to be embedded into canvas throught canvas.
scroll.pack(side='bottom', fill='x')
canvas.pack(fill='both', expand='yes')
canvas.create_window((0,0), window=frame, anchor='nw')
frame.bind('<Configure>', lambda x: canvas.configure(scrollregion=canvas.bbox('all'))) # lambda function
for i in range(5):
frame1 = ttk.Frame(frame, style="RoundedFrame", padding=10)
journal1 = tk.Text(frame1, borderwidth=2, highlightthickness=0, width = 40, height = 38)
# journal1.configure(borderwidth="3")
journal1.configure(relief="groove")
journal1.configure(background="white")
journal1.grid(row=0, column=0, padx=(100, 10), sticky = 'nswe') # grid instead
journal1.bind("<FocusIn>", lambda event: frame.state(["focus"]))
journal1.bind("<FocusOut>", lambda event: frame.state(["!focus"]))
frame1.grid_columnconfigure(0, weight=1)
frame1.grid_rowconfigure(0, weight=1)
frame1.grid(row=0,column=i, sticky = 'nswe')
root.mainloop()
Output
I had troubles with the focus of the frame, it complained frame has no attribute 'state'. It works in Bryans original answer. I fixed it with closures.
def frameFocusCreator(frame, focusState):
def changeState(event):
frame.state([focusState])
return changeState
for i in range(5):
frame1 = ttk.Frame(frame, style="RoundedFrame", padding=10)
journal1 = tk.Text(frame1, borderwidth=0, highlightthickness=0, width = 40, height = 38)
journal1.configure(relief="groove")
journal1.configure(background="white")
journal1.pack(fill='both', expand=True)
journal1.bind("<FocusIn>", frameFocusCreator(frame1, "focus"))
journal1.bind("<FocusOut>", frameFocusCreator(frame1, "!focus"))
frame1.grid(row=0,column=i, sticky = 'nswe')

python3 & tkinter - creating a zoom button to zoom on the loaded image

I would like to create a zoom button. On clicking on that zoom button, the image would be zoomed in by a factor represented by an integer (1,2,3,4,5...). With this piece of code, by clicking on the zoom button, another panel is created underneath the already loaded picture. Inside it is blank. What would be needed is to:
1. kill the first (non-zoomed window) and 2. load the zoomed image on the updated panel
from tkinter import *
from tkinter.filedialog import askopenfilename
import tkinter as tk
event2canvas = lambda e, c: (c.canvasx(e.x), c.canvasy(e.y))
root = Tk()
#setting up a tkinter canvas with scrollbars
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscroll = Scrollbar(frame, orient=HORIZONTAL)
xscroll.grid(row=1, column=0, sticky=E+W)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set,yscrollcommand=yscroll.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscroll.config(command=canvas.xview)
yscroll.config(command=canvas.yview)
frame.pack(fill=BOTH,expand=1)
#adding the image
image_str="image.png"
image = tk.PhotoImage(file=image_str)
image = image.zoom(1,1)
canvas.create_image(0,0,image=image,anchor="nw")
canvas.config(scrollregion=canvas.bbox(ALL))
def zoomin():
root = Tk()
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscroll = Scrollbar(frame, orient=HORIZONTAL)
xscroll.grid(row=1, column=0, sticky=E+W)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, bd=0, xscrollcommand = xscroll.set, yscrollcommand = yscroll.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscroll.config(command=canvas.xview)
yscroll.config(command=canvas.yview)
frame.pack(fill=BOTH,expand=1)
image = tk.PhotoImage(file=image_str)
image = image.zoom(1,1)
canvas.create_image(0,0,image=large_img,anchor="nw")
canvas.config(scrollregion=canvas.bbox(ALL))
toolbar = Frame(root, bg="blue")
insertButt = Button(toolbar, text="zoomin", command=lambda:zoomin())
insertButt.pack(side = LEFT, padx=2, pady=2)
toolbar.pack(side=TOP, fill = X)
#function to be called when mouse is clicked
def printcoords(event):
#outputting x and y coords to console
print (event.x,event.y)
#mouseclick event
canvas.bind("<Button 1>",printcoords)
#mouseclick event
canvas.bind("<ButtonPress-1>",printcoords)
canvas.bind("<ButtonRelease-1>",printcoords)
root.mainloop()
I would like to thank #Symon for his stackoverflow question. I largely inspired myself from his code
Well, the reason that the function zoomin(img) does not work properly is that it returns in the first line:
def zoomin(img):
return # Function returns here
... rest of code is never executed
I suspect this is due to the function being run when you create the button, not when you press it. Try cretating the button in this way instead:
insertButt = Button(toolbar, text="zoomin", command=lambda:zoomin(img))
Now the button will call zoomin(img) when it's pressed and not when the button is created.
Zooming with Tkinter
PhotoImage zoom only allows integer values, wich makes it a bit limited. But here's an example:
from tkinter import *
root = Tk()
root.geometry('300x200')
field = Canvas(root, bg='tan1', highlightthickness=0)
field.grid(sticky='news')
photo = PhotoImage(file='test.gif')
field.create_image(0, 0, image=photo, anchor='nw')
scale = 1
def zoom(event=None):
global scale, photo
scale = scale * 2
field.delete('all')
photo = photo.zoom(x=scale, y=scale)
field.create_image(0, 0, image=photo, anchor='nw')
field.image = photo
root.bind('z', zoom) # Bind "z" to zoom function
root.mainloop()
If you want to zoom by float you'll have to import a module for that. Pillow seems popular. But I haven't worked with any of them so you'll have to research them yourself.

How to attach my scrollbar to my listbox widget

here is a picture of what i want to be:
scrollbar
Actual code:
lb = Listbox(self.master, width=120, height=6)
scrollbar = Scrollbar(self.master, orient="vertical",command=lb.yview)
scrollbar.pack(side="right", fill="y")
lb.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=lb.yview)
lb.place(x=5,y=5)
Thanks!
You can create a new frame with listbox and scrollbar in it:
from tkinter import *
root = Tk()
root.geometry('500x300')
frame = Frame(root)
frame.place(x = 5, y = 5) # Position of where you would place your listbox
lb = Listbox(frame, width=70, height=6)
lb.pack(side = 'left',fill = 'y' )
scrollbar = Scrollbar(frame, orient="vertical",command=lb.yview)
scrollbar.pack(side="right", fill="y")
lb.config(yscrollcommand=scrollbar.set)
for i in range(10):
lb.insert(END, 'test'+str(i))
root.mainloop()
or since you're using place (which is not recommended), you can simply calculate the position of the scrollbar. grid would be the best layout manager in this case.
The problem is if you use only the 'place' positioning, the scrollbar doesn't appear.
The solution is to make two frames - one master frame with a widget scrollbar and
a second frame inside the master frame, where you can get the listbox. The frames can be positioned with place, the widget inside the frames with pack or grid.
Below is my source code, what works perfectly.
from tkinter import *
root = Tk()
root.geometry('500x300')
frame1 = Frame(root)
frame1.place(x = 10, y = 5,width=100,height=100) # Position of where you would place your listbox
frame1a=Frame(master=frame1)
frame1a.place(x=0,y=0,height=100,width=100)
lb = Listbox(frame1a, width=50, height=6)
lb.grid(row=0,column=0 )
scrollbar = Scrollbar(frame1, orient="vertical",command=lb.yview)
scrollbar.pack(side="right", fill="y")
lb.config(yscrollcommand=scrollbar.set)
for i in range(10):
lb.insert(END, 'test'+str(i))
root.mainloop()

Tkinter Label: Retain Height when I change font to smaller size

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()

Resources