How to position a Textbox with Tkinter in Python? - python

I'm learning Tkinter for GUI. I write the following simple code, I can't change the location of the Textbox even if I try different values in the grid. Whatever value I write, the Textbox always comes at the left up corner.
from tkinter import *
startingWindow = Tk()
startingWindow.title("Hello")
startingWindow.geometry("400x300")
myEntry = Entry(startingWindow, width=10)
myEntry.grid(column=15, row=15)
startingWindow.mainloop()
Instead, I get the following output.
Note: I'm using Python 3.6 under Windows 7

use place instead of grid like this:
from tkinter import *
startingWindow = Tk()
startingWindow.title("Hello")
startingWindow.geometry("400x300")
myEntry = Entry(startingWindow, width=10)
myEntry.place(x=15,y=15) # here
startingWindow.mainloop()

Related

Is there a way to alter the size and position of a window after opening it through tkinter?

Here is my code so far:
import os
from tkinter import *
import tkinter as tk
system_properties=("C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\System Information.lnk")
device_manager=("devmgmt.msc")
root = Tk()
#root.title()
window = tk.Tk()
root.geometry("200x200")
def open_app():
os.startfile(system_properties)
os.system(device_manager)
Button(root, text ='Open',
command = open_app).pack(side = TOP,
pady = 10)
root.mainloop()
To clarify I am not looking to change the tkinter window. What I want to do is open multiple applications at once on Windows 11 with no overlap like in a split screen format, but I am not sure how to incorporate code to make the windows display with my desired size and position. Currently, they are opening on top of each other with different window sizes.

Unable to update Label text in Python Tkinter without calling pack() again

from tkinter import *
from tkinter.ttk import *
root = Tk()
first_run = True
def update(txt):
global first_run
text1 = Label(root, text='')
if first_run:
text1.pack()
text1['text'] = txt
first_run = False
update('1')
update('2')
update('3')
root.mainloop()
When I run this, the text stays at '1', and the following 2 function calls are ignored. I find out that only if I use pack() again then it will be updated, but it creates a duplicate label and I do not want that.
Of course, I know that I am supposed to use a StringVar, but I have been using this method for all other widgets (buttons, label frames etc) and all of them works. I do not know why this particular case does not work.
Running on Python 3.9.9 on Windows 11
You aren't updating the label, you are creating a new label each time the function is called. To update any widget, use the configure method. For that, you need to create the label outside of the function (or, leave it in the function but add logic so that it's only created once). Usually it's best to create it outside the function so that the function is only responsible for the update.
from tkinter import *
from tkinter.ttk import *
root = Tk()
def update(txt):
text1.configure(text=txt)
text1 = Label(root, text='')
text1.pack()
update('1')
update('2')
update('3')
root.mainloop()
Note: since you call your function multiple times before the window is drawn you'll only see the final value. There are plenty of solutions to that on this site. Without knowing more about what your real program looks like it's hard to recommend the best solution to that problem.

How to place a button on the left in TkInter

I am doing a simple UI with TkInter in Python. I want a button at the top left, so I did something like
back = Button(explorer, text="Back")
back.pack(side="top", anchor="w")
where explorer is a frame, and I expected to see the button on top left, but it's stuck in the center. Any suggestions? I already tried to add side=TOP but it didn't work. What's the right way to do that?
As mentioned above, your parent frame should fill the x space.
This is an example of the parent frame not filling x:
import tkinter as tk
root = tk.Tk()
root.geometry('200x200')
element = tk.Frame(root)
element.pack() # No fill
tk.Button(element, text='No Fill').pack(anchor='w')
# To show the fill
tk.Label(root, text='Fill X', bg='green').pack(fill='x')
root.mainloop()
And the result is the button is in the center despite the anchor:
https://i.stack.imgur.com/DAgmH.png
But, make this change:
element.pack(fill='x')
And now your button will be in the top left like here:
https://i.stack.imgur.com/HoGGj.png
Your frame has to occupy all the horizontal space if you want to align its children. Something like (if you imported tkinter elements with from tkinter import *):
explorer.pack(fill=X)
Tkinter has 3 modules to set items:
.pack which puts everything more or less random
.grid where you can define the row and column
.place where you define everything in pixels
so you could use something like
import tkinter as tk
from tkinter import *
root = Tk()
button = Button(text = 'back')
button.grid(row = 1, column = 1)
root.mainloop()
This shows how to use the .grid function. Keep in mind that the size of each grid is defined by its largest content. If you have a long entry field , the column its placed in is going to be as wide as the entry.
you could also use the .place function, but this one requires the most work. For me its always guessing and rerunning until im happy with it.
import tkinter as tk
from tkinter import *
root = Tk()
button = Button(text = 'back')
root.geometry("150x100")
button.place(x=30, y=30)
root.mainloop()
So in summary, use .pack if you dont care, .grid if you want some kind of control and .place if you want to be accurate. And keep in mind to use only ONE at a time.

My python code is not working

This simple code is not working.
I mean its running without errors but
is not showing any gui window for text entry.
from Tkinter import *
from tkMessageBox import *
root=Tk()
Label(root,text="first").grid(row=0)
Label(root,text="second").grid(row=2)
e1=Entry(root)
e1.grid(row=0,column=2)
e2=Entry(root)
e2.grid(row=2,column=3)
def info():
s=showinfo(title="wish",message=e1.get()+''+"welcome to python")
Button(root,text="ok",command=info).pack()
root.mainloop()
You can't use grid and pack on two widgets owned by the same parent. This causes the geometry manager to loop forever.
Change your Button positioning to:
Button(root,text="ok",command=info).grid(row=3, column=0)
(or whatever row/column you want it to be in).
Result:

label layout using grid in tkinter

I'm having some trouble figuring out how to use grid properly with tkinter. I just want two labels to appear side by side.
When I do the following, they appear in a separate window from my app. I'm confused because I have buttons on my app that appear as I want them(not using grid), but I can't quite figure out the labels in a grid.
//this is just a snippet from a function
self.root = tk.Tk()
tk.Label(master=self.root, text=directory).grid(row=0,column=0)
tk.Label(master=self.root, text=directory).grid(row=0,column=1)
The root window is created in a different part of the app, so all I'm doing here is making another one (I think). I just want the labels to appear in the window that has already been created but I can't figure out what I'm supposed to reference it to.
This is in a separate file that includes the file with the code above
from Tkinter import *
import tkinter as tk
import widgetActions
import shutil
class mywidgets(widgetActions.Actions):
def __init__(self,root):
frame = tk.Frame(root)
self.makeMenuBar(frame)
frame.pack()
frame.config(width=400)
self.body()
return
def makeMenuBar(self,frame):
menubar = Frame(frame,relief=RAISED,borderwidth=1)
menubar.pack()
mb_file = Menubutton(menubar,text='file')
mb_file.pack(side=LEFT)
mb_file.menu = Menu(mb_file)
mb_file.menu.add_command(label='open', command = self.openfile)
mb_file.menu.add_command(label='close', command = menubar.quit)
mb_file['menu'] = mb_file.menu
return
def body(self):
self.filename()
def main():
root = tk.Tk()
k=mywidgets(root)
root.title('menu bar')
root.mainloop()
main()
You cannot create two instances of Tk. As you observed, you will get two windows. That's not the only problem, just the most obvious one.
You need to pass in a reference to the winget that is to contain these labels. Or, store the root window as a global variable, or as an attribute of an object.
To position the 2 labels side by side i.e label1 and label2:
label1.grid(column=0, row=0)
label2.grid(column=1, row=0)
That should do it

Categories