How do I create internal x padding for an Entry? - python

I have an Entry input_field and I'm trying to create some internal x padding for the Entry so when you input a value the characters aren't so close to the left side of the Entry.
My code:
from tkinter import *
screen = Tk()
input_field = Entry(font=("Calibri", 16, "bold"), width=25,).pack()
screen.mainloop()
My output:
I would like something like this:
I have tried to use ipadx into the .pack() method but simply doesn't change. I've also looked through documentation and found no other replacements to ipadx except padx but this only creates external padding around the Entry.
Is there a way to create internal x padding instead of manually adding in spaces?

You need to use ttk.Entry and configure the Style like this:
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
style = ttk.Style(root)
style.configure('My.TEntry', padding=(20,0, 0,0))
#padding = (padx left, pady up,padx right,pady down)
widget = ttk.Entry(root, style='My.TEntry')
widget.pack(expand=True, fill='both')
root.mainloop()

Related

How can I center a label using Tkinter's grid method in Python

I'm trying to center a Label in Tkinter. I am using the grid() method to show my widgets.
In the code below I created a frame and put the label in that frame.
The sticky method doesn't seem to work for some reason.
I have tried sticky='WE' but the label is still stuck to the left side of the frame.
'''
from tkinter import *
from tkinter import ttk
mw=Tk()
mw.title('Window')
mw_width, mw_height = 300, 200
mw.minsize(mw_width,mw_height)
frame1=Frame(mw)
frame1.grid(row=0,column=0)
main_label=ttk.Label(frame1,text='My label')
main_label.grid(row=0,column=0,sticky='WE')
mw.mainloop()
'''
grid by default will center a widget in the space allocated to it. The problem is that you've not configured the column to grow to fill the window. Also by default, a row or column will be just large enough to fit the widgets in it.
To do that, you need to give column 0 a non-zero weight:
mw.grid_columnconfigure(0, weight=1)
Do you need to use the grid() method for your layout? pack() would automatically center it.
from tkinter import *
from tkinter import ttk
mw=Tk()
mw.title('Window')
mw_width, mw_height = 300, 200
mw.minsize(mw_width,mw_height)
frame1=Frame(mw)
frame1.pack()
main_label=ttk.Label(frame1,text='My label', justify="center")
main_label.pack()
mw.mainloop()
You could also use place().
from tkinter import *
from tkinter import ttk
mw = Tk()
mw.title('Window')
mw_width, mw_height = 300, 200
mw.minsize(mw_width, mw_height)
frame1 = Frame(mw)
frame1.place(width=mw_width, height=mw_height)
main_label = ttk.Label(frame1, text='My label', justify="center")
main_label.place(relx=.5, rely=0, anchor="n")
mw.mainloop()

How to position several widgets side by side, on one line, with tkinter?

By default, after making a tkinter button, it automatically puts the next one on the other line.
How do I stop this from happening?
I want to do something like this:
You must use one of the geometry managers for that:
here with grid:
import tkinter as tk
root = tk.Tk()
b1 = tk.Button(root, text='b1')
b2 = tk.Button(root, text='b2')
b1.grid(column=0, row=0) # grid dynamically divides the space in a grid
b2.grid(column=1, row=0) # and arranges widgets accordingly
root.mainloop()
there using pack:
import tkinter as tk
root = tk.Tk()
b1 = tk.Button(root, text='b1')
b2 = tk.Button(root, text='b2')
b1.pack(side=tk.LEFT) # pack starts packing widgets on the left
b2.pack(side=tk.LEFT) # and keeps packing them to the next place available on the left
root.mainloop()
The remaining geometry manager is place, but its use is sometimes complicated when resizing of the GUI occurs.
Simply use this to make the y coordinates the same and change the x coordinate:
from tkinter import *
root = Tk()
Button(root, text='Submit', width=10, bg='blue', fg='white',
command=database).place(x=70, y=130)
For the second button:
buttonSignIn = Button(root, text="Sign in", width=10, bg='black',
fg='white', command=new_winF).place(x=30, y=130)
I had the same problem once, and found this: two "simple" ways to move widgets around a GUI area, are
i) Using the ".grid" attribute (see example below):
MyButton_FilePath = Button(
master = gui,
text = 'Open',
command = funcion_openfile_findpath,
fg = 'Black', font = ('Arial bold',11)
)
MyButton_FilePath.grid(row = 0, column = 2, padx = 4, pady = 4)
ii) Or using the attribute ".place":
MyButton_FilePath = Button(
master = gui,
text = 'Open',
command = funcion_openfile_findpath,
fg = 'Black', font = ('Arial bold',11)
)
MyButton_FilePath.place(x=300, y=400)
Note that I have separated the "Button" object into two lines - as it is considered to be a better practice whenever placing/gridding widgets...
Hope I have helped.
Try both ways and see which one fits better your wishes! :)
Cheers, Marcos Moro, PhD

Adjust height of a row in Tkinter Treeview depending on wraped strings

I was making a treeview for my tkinter program, and when I insert the data into it, there are some rows with too many characters and some of them are unseen.
Is there any way to set an auto line feed for the row height? I don't want to add a horizontal scrollbar to solve this. This means when the width of a strings is bigger then th columns with a newline should be iserted (automaticly). In that case the height of the row should be adjusted (automaicly) in that case to display more then one line.
from tkinter import *
import tkinter.ttk as ttk
root = Tk()
frame = Frame(root)
frame.pack()
tree = ttk.Treeview(frame, height=15,
columns=('c1', 'c2'),
show="headings")
tree.column('c1', width=100, anchor='center')
tree.column('c2', width=200, anchor='center')
tree.heading('c1', text='text1')
tree.heading('c2', text='text2')
tree.pack()
tree.insert('', 1, values=['edew', 'dewd'])
tree.insert('', 2, values=['abcd'*10, 'wxyz'*10])
root.resizable(width=False, height=False)
root.mainloop()
The height of alls row can be modified with this code.
root = Tk()
style = ttk.Style(root)
style.configure('Treeview', rowheight=45)
It would be very nice to know if each row in a Treeview can have it's own style to defined individual rowheight (depending on newline characters).
In response to Aleksandar Beat's question:
In order to change the style of a specific Treeview, you have to define a different identifier before the ttk widget name:
Style().configure('AnythingYouWantHere.Treeview', rowheight=45)
# The '.Treeview' can not be changed
However, if you do it this way, you have to specify the style option of the ttk widget.
Sample usage:
root = Tk()
Style().configure('MyStyle1.Treeview', rowheight=45)
styledTreeView = Treeview(root, style='MyStyle1.Treeview')
normalTreeView = Treeview(root) # Style will not automatically apply
This also applies to any ttk widgets.

Python: Listbox without border

I want to get a table, but when I realized, that there's no table in python, I decided to fix it with two listboxes.
The point is, that I don't want a border between them.
So my Question is: How to remove the border from the Tk Listbox in Python?
Even if it'll become white I had a solution...
You want to set the borderwidth to zero, but you also want to set highlightthickness to zero. Highlightthickness represents a rectangle that surrounds the whole widget when it has keyboard focus. Finally, when you use pack or grid, make sure you don't add any padding between them.
If you want to complete the illusion that the two widgets are one, put them in a frame and give the frame a borderwidth and relief.
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent, borderwidth=1, relief="sunken")
lb1 = tk.Listbox(self, borderwidth=0, highlightthickness=0)
lb2 = tk.Listbox(self, borderwidth=0, highlightthickness=0)
lb1.pack(side="left", fill="both", expand=True)
lb2.pack(side="left", fill="both", expand=True)
lb1.insert(0, "left")
lb2.insert(0, "right")
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True, padx=8, pady=8)
root.mainloop()
I think the best you can achieve would be this:
import tkinter as tk
root = tk.Tk()
wrapper = tk.Frame(root, bd=2, relief="sunken")
L1 = tk.Listbox(wrapper, bd=0)
L2 = tk.Listbox(wrapper, bd=0)
L1.grid(column = 1, row = 1)
L2.grid(column = 2, row = 1)
wrapper.pack()
root.mainloop()
note setting the border of each listbox to 0, (bd=0) and to give the overall widget a similar look to the original listbox i've wrapped it in a frame and given that the same border style as the default listbox.
also worth nothing that you need to get the bindings right to make them scroll as expected, just binding to the scroll wheel and scroll bar is insufficient as the lists can be moved with the arrow keys when an item is highlighted, like in the second example on this page:
scrolling multiple listboxes together
by Santiclause
Speicfy borderwidth as 0 when you create a listbox.
For example:
from Tkinter import * # from tkinter import * (Python 3.x)
root = Tk()
lb = Listbox(borderwidth=0) # <---
lb.pack()
root.mainloop()

Change position of checkbox relative to text in Tkinter's Checkbutton

How can I change where the text is relative to the checkbox for a Tkinter Checkbutton?
By default, the text is to the right of the checkbox. I would like to change that, so the text is on the left or above of the checkbox.
I know this can be done by creating a Label with the required text and delicately positioning the two near each other, but I'd prefer to avoid that method.
Some sample code:
from Tkinter import *
root = Tk()
Checkbutton(root, text="checkButon Text").grid()
root.mainloop()
Well, I don't think you can do it directly, but you can do something that looks as it should. It is the Label-solution, but I altered it slightly, so the resulting compound of Checkbutton and Label is treated as a single Widget as wrapped in a Frame.
from Tkinter import *
class LabeledCheckbutton(Frame):
def __init__(self, root):
Frame.__init__(self, root)
self.checkbutton = Checkbutton(self)
self.label = Label(self)
self.label.grid(row=0, column=0)
self.checkbutton.grid(row=0, column=1)
root = Tk()
labeledcb = LabeledCheckbutton(root)
labeledcb.label.configure(text="checkButton Text")
labeledcb.grid(row=0, column=0)
root.mainloop()
When you create multiple frames (with their respective content - Checkbutton and Label) you can handle them easily. That way you would just have to position the Frames like you would do it with the Checkbuttons.

Categories

Resources