How do I limit tk.DoubleVar to a number of significant figures - python

I am learning/trying out tkinter, and trying to use a DoubleVar to store the data from a Scale widget and have it output through a Label.
This works fine, but it displays to a much higher significant figure level than I would like. Is this something I should control on the Label side or the DoubleVar side, and how would I do this?
coefficient_of_resitution_value = tk.DoubleVar()
coefficient_of_resitution_slider = ttk.Scale(coefficient_of_restitution_frame,
from_ = 0,
to = 1,
orient = "horizontal",
variable = coefficient_of_resitution_value,
style = "white_background_scale.Horizontal.TScale")
coefficient_of_resitution_slider.grid(column = 0, row = 1, columnspan = 1, sticky = tk.NSEW)
coefficient_of_resitution_display = ttk.Label(coefficient_of_restitution_frame,
textvariable = coefficient_of_resitution_value,
background = "#FFFFFF",
font = ("Calibri", 16))
coefficient_of_resitution_display.grid(column = 1, row = 0, sticky = tk.NSEW)

One of the way is to round the value to what you want inside the callback of command option:
coefficient_of_resitution_slider['command'] = \
lambda val: coefficient_of_resitution_value.set(round(float(val), 4))

Related

Resizing pandastable automatically to fit frame width in tkinter in Python

I am trying to create a GUI for a small application I have written in Python 3.10 using Tkinter package. I want to have a single window open with buttons, entry fields, labels and a data table at the bottom that is updated from a database I have created.
I have created the table, and imported it into the frame which is set up into the grid system I have set up for the buttons, as shown in the code below.
What I can't figure out, is how to shrink the pandastable or manipulate it in anyway once it's in the root window? I have tried changing the font, fontsize, and column attributes using the core functions in pandastable on my table variable (.autoResizeColumns(), .setFont(), .zoomOut() and more) but nothing seems to have an effect.
Here is a picture of my current GUI.
I would like for the entire table to be displayed without the horizontal scrollbar, slightly smaller with decreased font size - so it's similar to the top portion of the table.
Am I doing something wrong? Is there something in pandastable I can call to achieve this?
from tkinter import *
from tkinter import ttk
import pandastable as pt
# Tk
root = Tk()
root.resizable(False, False)
#Create GUI
api_entry_btn = Button(root, text = "Add API ", command = lambda: db.get_token(embed = False))
api_entry_btn.grid(row = 0, column = 0, columnspan= 1, sticky='nesw')
api_del_btn = Button(root, text = "Remove API", command = lambda: db.check_del_token())
api_del_btn.grid(row = 1, column = 0, columnspan= 1, sticky='nesw')
scan_now_btn = Button(root, text = "Scan Now", command = db.scan_now)
scan_now_btn.grid(row = 0, column = 1, columnspan= 1, sticky='nesw')
id_list_btn = Button(root, text = "Show ID list", command = db.fetch_id_info)
id_list_btn.grid(row = 1, column = 1, columnspan= 1, sticky='nesw')
id_entry = Entry(root, width = 40,borderwidth=3)
id_entry.grid(row = 0, column = 2, sticky="ns", padx = (3,0))
add_id_btn = Button(root, text = "Add ID", command = lambda: add_id(id_entry.get()))
add_id_btn.grid(row = 0, column = 3, sticky='nesw')
id_del = Entry(root, width = 40,borderwidth=3)
id_del.grid(row = 1, column = 2, sticky="ns", padx = (3,0))
del_id_btn = Button(root, text = "Delete ID", command = lambda: db.remove_id(id_del.get()))
del_id_btn.grid(row = 1, column = 3, sticky='nesw')
frame = Frame(root, width = 150)
frame.grid(row = 3, column = 0, columnspan= 4, sticky = 'nesw')
table = pt.Table(frame, dataframe= db.synth_pandastable())
table.show()
root.mainloop()
Thanks in advance for any help.
Note, I have left out a bit of my code to keep it shorter.

Make an Entry When a Checkbox is Unchecked in Tkinter

I have a check button that is checked by default. If the user unchecks it, a label and an entry should appear. I tried to do so by using the key binding method; however, it has a drawback which is that if the user checks the checkbox again, the new label and entry won't disappear. How do I solve that problem?
checkButtonVar = IntVar(value = 1)
checkButtonIsChnaceDefault = Checkbutton(root, variable = checkButtonVar)
labelIsChanceDefault = Label(root, text="Make chance = 0.9?")
labelIsChanceDefault.grid(row=3, column = 0, sticky = 'w')
checkButtonIsChnaceDefault.grid(row = 3, column = 1)
def checkCheckButton(event):
labelChance = Label(root, text = "Enter chance of winning")
labelChance.grid( row = 3, column = 2)
global entryChance
entryChance = Entry(root, borderwidth = 3)
entryChance.grid(row = 3, column = 3)
checkButtonIsChnaceDefault.bind('<Button-1>', checkCheckButton)
Here's a screenshot of the program to make things clear.
You don't need to bind the Check-button. Use command option. And setting offvalue and onvalue can control the appearance.
See the tkinter.Checkbutton
checkButtonVar = IntVar()
checkButtonIsChnaceDefault = Checkbutton(root, variable = checkButtonVar,offvvalue=0,onvalue=1,command=checkCheckButton)
...
checkButtonIsChnaceDefault.grid(row = 3, column = 1)
#==== Define the widgets here.
labelChance = Label(root, text = "Enter chance of winning")
entryChance = Entry(root, borderwidth = 3)
def checkCheckButton():
if checkButtonVar.get()==0:
labelChance.grid( row = 3, column = 2)
entryChance.grid(row = 3, column = 3)
else:
labelChance.grid_forget()
entryChance.grid_forget()

how to format 2 check buttons in same row and column python

I have created two check buttons and I want them both in row 5 and column 1. But I want the 'YES' check button to be formatted on the left side and the 'NO' check button to be on the right.
I have used sticky but it will not work. I also tried changing the width of the check buttons but this did not work either.
Do you have any suggestions?
Thank you!
self.yes_checkbtn = Checkbutton(self.entry_frame, width = 20, variable = checkbutton1,
anchor = W, text = "YES")
self.no_checkbtn = Checkbutton(self.entry_frame, width = 20, variable = checkbutton2,
anchor = E, text = "NO")
self.yes_checkbtn.grid(row = 5, column = 1, sticky = W)
self.no_checkbtn.grid(row = 5, column = 1, sticky = E)
Outcome:
I dont have enough points yet to show the image without a link - sorry
Put both check buttons under another new frame, then you can grid this new frame to column 1 of row 5, also change option width of Checkbutton to a small number, like 5.
Example code
from tkinter import *
root = Tk()
entry_frame = Frame(root)
entry_frame.grid(row=0, column=0)
for i in range(4):
for j in range(2):
label = Label(entry_frame, text=f'Row {i} Column {j}')
label.grid(row=i, column=j)
frame = Frame(entry_frame)
frame.grid(row=4, column=1)
checkbutton1 = BooleanVar()
checkbutton2 = BooleanVar()
yes_checkbtn = Checkbutton(frame, width = 5, variable = checkbutton1,
anchor = W, text = "YES", bg='green')
no_checkbtn = Checkbutton(frame, width = 5, variable = checkbutton2,
anchor = E, text = "NO", bg='blue')
yes_checkbtn.grid(row = 0, column = 1, sticky = W)
no_checkbtn.grid(row = 0, column = 2, sticky = W)
root.mainloop()

how to show/hide widget in tkinter without moving other widget

I'm using grid_remove() and grid() command to hide/show the widget but the result is the other widget is move out of the original position.
How to hide/show the widget without moving widget
Example:
from tkinter import *
from tkinter import ttk
GUI = Tk()
GUI.title("myTest")
GUI.geometry("700x700")
Nameget = StringVar()
Priceget = StringVar()
Quantityget = StringVar()
Unitget = StringVar()
Partnumget = StringVar()
L_Partnum = ttk.Label(GUI, text = 'Part number')
L_Partnum.grid(row = 0, column = 0)
L_namme = ttk.Label(GUI, text = 'Name')
L_namme.grid(row = 0, column = 1)
L_quan = ttk.Label(GUI, text = 'Quantity')
L_quan.grid(row = 1, column = 2)
L_quan.grid_remove()
L_price = ttk.Label(GUI, text = 'Price')
L_price.grid(row = 3, column = 3)
E_partnum = ttk.Entry(GUI, textvariable = Partnumget)
E_partnum.grid(row = 1, column = 0)
E_namme = ttk.Entry(GUI,textvariable = Nameget)
E_namme.grid(row = 1, column = 1)
E_unit = ttk.Entry(GUI,textvariable = Unitget)
E_quan = ttk.Entry(GUI,textvariable = Quantityget)
E_quan.grid(row = 2, column = 2)
E_quan.grid_remove()
E_price = ttk.Entry(GUI,textvariable = Priceget)
E_price.grid(row = 4, column = 3)
I_check_vat = IntVar()
def d_check_vat_1():
E_partnum.focus()
if I_check_vat.get() == 1:
L_quan.grid()
E_quan.grid()
elif I_check_vat.get() == 0:
L_quan.grid_remove()
E_quan.grid_remove()
C_CHECK_VAT = ttk.Checkbutton(GUI, text="click here to see the result", variable=I_check_vat, command=d_check_vat_1)
C_CHECK_VAT.grid(row = 5, column = 0)
GUI.mainloop()
Before clicking:
After clicking:
image with the expected output:
The problem is grid() does not take up empty space by default, it gives the last empty row/col to the widget(if previous rows before it are empty).
So what you can do is, set minimum space for your column and row so that those space will remain empty, so change your function to:
def d_check_vat_1():
E_partnum.focus()
if I_check_vat.get():
L_quan.grid(row=2, column=2)
E_quan.grid(row=3, column=2)
width = E_quan.winfo_reqwidth() # Get widget width
height = L_quan.winfo_reqheight() # Get widget height
GUI.rowconfigure(2,minsize=height) # Now apply the values
GUI.rowconfigure(3,minsize=height)
GUI.columnconfigure(2,minsize=width)
else:
L_quan.grid_remove()
E_quan.grid_remove()
Now its dynamic as well, it takes the width of widget and applies that as the minsize of that row so that row will have that empty space.

Laying out Labels properly in Tkinter

I have the following code:
from Tkinter import *
master = Tk()
center(master, 300, 200)
#Label(text = 'Clients').grid(row = 0, column = 1)
lb = Listbox(master, selectmode = BROWSE)
sb = Scrollbar(master)
sb.grid(row = 0, column = 0, sticky =NS, rowspan = 1)
lb.grid(row = 0, column = 1)
sb['command'] = lb.yview
lb['yscrollcommand'] = sb.set
Label(master, text = "AAAAA").grid(row = 0, column = 2)
Label(master, text = "BBBBB").grid(row = 1, column = 3)
mainloop()
Which creates this window:
I know I can use sticky = N to make AAAAA cling to the top of the cell and be at the top of the window.
But my question is: How do I make it so that I can put multiple labels next to my listbox widget in a sort of grid of their own? Can I use .grid for this? Or do I have to use .place?
Or am I going about this entirely wrong?

Categories