Python Tkinter input date subtraction - python

I've been trying to get my Tkinter dialog to do a simple date subtraction, but something is holding it up. The date subtraction seems to hold up when run from the shell, but I'm getting nothing from this is Tk.
The code is borrowed from another script that I have running successfully with all the form and windows setup.
#!/usr/bin/python
from Tkinter import *
import datetime
import math
fields = ('Enter Date (mm/dd/yy)', 'Days Since 10/30/14')
def Calc(entries):
d = raw_input(entries['Enter Date (mm/dd/yy)'].get())
nd = datetime.datetime.strptime(d, "%m/%d/%y").date()
d1 = "10/30/14"
od = datetime.datetime.strptime(d1, "%m/%d/%y").date()
diff = (nd - od).days
diff = ('%8.2f' % diff).strip()
entries['Days Since 10/30/14'].delete(0,END)
entries['Days Since 10/30/14'].insert(0, diff)
def makeform(root, fields):
root.title('Date Difference')
entries = {}
for field in fields:
row = Frame(root)
lab = Label(row, width=22, text=field+": ", anchor='w', font=('arial', 12))
ent = Entry(row, font=('arial', 12))
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT, padx=10)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries[field] = ent
return entries
if __name__ == '__main__':
root = Tk()
root.geometry("400x400+300+300")
ents = makeform(root, fields)
root.bind('<Return>', (lambda event, e=ents: Calc(e)))
b1 = Button(root, text='Calculate', font=('arial',12), command=(lambda e=ents: Calc(e)))
b1.pack(side=LEFT, padx=5, pady=5)
b2 = Button(root, text='Quit', font=('arial',12), command=root.quit)
b2.pack(side=LEFT, padx=5, pady=5)
root.mainloop()
Any help would be appreciated...
Even now I messed it up more, somehow it doesn't even start at all and highlights the "lab" variable under makeform(root,fields): it was running a minute ago, though would not do the calculation...
Help?

d = raw_input(entries['Enter Date (mm/dd/yy)'].get())
raw_input gets data from the user via the command line. Is that intentional? You don't need it if you just want to find what the user typed into the entry.
d = entries['Enter Date (mm/dd/yy)'].get()

Related

Values not stored in Tkinter Variables

In my code, I have tried to get the user input through text fields, store them in variables and finally print them in a tabular form.
The problem I am facing is that none of the values I enter through the text fields get displayed; when I try printing the variables, they come up empty.
Here's part of my code:
# SPASC
from tkinter import *
import tkinter as tk
import tkinter.ttk as tktrv
root = tk.Tk()
root.title("SPASC")
root.geometry("410x400")
lb1 = Label(root, text="SPASC \n Welcomes You !!!", fg="red", bg="sky blue"
, font=('Arial Black', 20), width=22, anchor=CENTER)
lb2 = Label(root, text="What would you like to compare?",
font=('Arial', 18), anchor=CENTER)
space1 = Label(root, text="\n\n")
lb1.grid(row=0)
lb2.grid(row=5)
space1.grid(row=1)
hpw, mil = StringVar(), StringVar()
def bt_cars():
w1 = Toplevel()
w1.title("Choose Features")
w1.geometry("430x200")
lb3 = Label(w1, text="Choose features for comparison", bg="yellow"
, font=('Arial Black', 18), width=25)
lb4 = Label(w1, text=" ", anchor=CENTER)
fr1 = LabelFrame(w1, width=20, padx=100)
hpw_cb = Checkbutton(fr1, text="Horsepower", variable=hpw, anchor='w', onvalue="Horsepower", offvalue="")
hpw_cb.grid()
hpw_cb.deselect()
mil_cb = Checkbutton(fr1, text="Mileage", variable=mil, anchor='w', onvalue="Mileage", offvalue="")
mil_cb.grid()
mil_cb.deselect()
var_stor = [hpw, mil]
print(hpw)
print(mil)
var_fill = []
for itr1 in var_stor:
if itr1 != "":
var_fill.append(itr1)
print(var_fill)
def car_1():
name1 = StringVar()
c1 = Toplevel()
c1.title("Car 1")
c1.geometry("430x200")
car1_lb1 = Label(c1, text="Car Name:")
name1_ifl = Entry(c1)
name1 = name1_ifl.get()
elm_var_fill = len(var_fill)
ct1 = 0
car1_val = []
for itr2 in var_fill:
if ct1 == elm_var_fill:
break
lb5 = Label(c1, text=itr2.get())
#Creating text field
ftr1_ifl = Entry(c1)
car1_ftr = ftr1_ifl.get()
car1_val.append(car1_ftr)
car1_ftr = None
lb5.grid(row=ct1 + 2, column=1)
ftr1_ifl.grid(row=ct1 + 2, column=2)
ct1 += 1
print(car1_val)
def display():
dp = Toplevel()
dp.title("Results")
dp.geometry("500x200")
car1_pt = 0
car2_pt = 0
car_tree = tktrv.Treeview(dp)
car_tree["columns"] = ("car1col")
car_tree.column("#0", width=120, minwidth=30)
car_tree.column("car1col", width=120, minwidth=30)
car_tree.heading("#0", text="Features" )
car_tree.heading("car1col", text=str(name1))
car_tree.pack()
c1.withdraw()
print(var_fill)
done1_bt = Button(c1, text="Continue", command=display)
name1_ifl.grid(row=0, column=2)
car1_lb1.grid(row=0, column=1)
done1_bt.grid(row=5,column=1)
w1.withdraw()
done_bt = Button(w1, text="Done", command=car_1)
done_bt.grid(row=3, column=1)
lb3.grid(row=0, column=1)
lb4.grid(row=1, column=1)
fr1.grid(row=2, column=1)
root.withdraw()
bt1 = Button(root, text="CARS", width=5, font=('Calibri', 15), command=bt_cars)
bt1.grid(row=7)
space2 = Label(root, text="\n\n")
space2.grid(row=6)
root.mainloop()
I am facing trouble with the variables named: hpw, mil, name1.
Any help would be welcome.
NOTE:- Please excuse the amount of code; I wanted others to replicate the error and see it for themselves
For the variables hpw and mil, these variables are empty strings that's why you are not getting any value from those checkboxes. To get values from the checkboxes replace these lines of code:
var_stor = [hpw, mil]
with
var_stor = [hpw_cb.cget('onvalue'), mil_cb.cget('onvalue')]
since you want the onvalue then you must use cget() method to access those values.
also, replace
lb5 = Label(c1, text=itr2.get())
with
lb5 = Label(c1, text=itr2)
because now you have required values (not objects) in a list, so just need to access those values.
For the variable name1 you can use #BokiX's method.
The problem is you are using get() wrong. You cannot use get() right after Entry() because as soon as entry is created it's getting the input before the user can even input something.
Use this code:
def get_input(text):
print(text)
e = Entry(root)
e.pack()
b = Button(root, text="Print input", command=lambda: get_input(e.get()))
b.pack()
Now get() method will not be executed before you click the button.

Store variables entered in tkinter form

I am creating a Tkinter-based form where I want to store each item that the user types in as a separate variable. I understand how to generate the form, but I am lost on how to handle the program after the user presses the Enter button. I really just need everything stored as a string.
from tkinter import *
import pandas as pd
fields = ('Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)', 'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)')
def saveVars(entries):
locals().update(entries)
return
def makeform(root, fields):
entries = {}
for field in fields:
row = Frame(root)
lab = Label(row, width=22, text=field+": ", anchor='w')
ent = Entry(row)
ent.insert(0,"")
row.pack(side = TOP, fill = X, padx = 5 , pady = 5)
lab.pack(side = LEFT)
ent.pack(side = RIGHT, expand = YES, fill = X)
entries[field] = ent
return entries
if __name__ == '__main__':
root = Tk()
ents = makeform(root, fields)
b1 = Button(root, text = 'Enter', command = lambda e = ents: saveVars(e))
b1.pack(side = LEFT, padx = 5, pady = 5)
root.mainloop()
What you need to do is build a function that does something with your entry fields. That said you may want to change up you code a little bit to make this easier. Instead of building your labels and entry fields in a function build them in the global namespace and then store the entry fields in a list.
import tkinter as tk
fields = ('Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)',
'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)')
def do_something_with_entries():
for ndex, entry in enumerate(entry_list):
print(fields[ndex], ': ', entry.get())
if __name__ == '__main__':
root = tk.Tk()
entry_list = []
for field in fields:
row = tk.Frame(root)
lab = tk.Label(row, width=22, text=field + ": ", anchor='w')
ent = tk.Entry(row)
entry_list.append(ent)
row.pack(side='top', fill='x', padx=5, pady=5)
lab.pack(side='left')
ent.pack(side='right', expand='yes', fill='x')
tk.Button(root, text='Enter', command=do_something_with_entries).pack(side='left', padx=5, pady=5)
root.mainloop()
Results:
Here is an example using pandas:
import tkinter as tk
import pandas as pd
fields = ['Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)', 'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)']
df = pd.DataFrame(columns=fields)
def do_something_with_entries():
global df
stored_values = []
for ndex, entry in enumerate(entry_list):
stored_values.append(entry.get())
series = pd.Series(stored_values, index=fields)
df = df.append(series, ignore_index=True)
if __name__ == '__main__':
root = tk.Tk()
entry_list = []
for field in fields:
row = tk.Frame(root)
lab = tk.Label(row, width=22, text=field + ": ", anchor='w')
ent = tk.Entry(row)
entry_list.append(ent)
row.pack(side='top', fill='x', padx=5, pady=5)
lab.pack(side='left')
ent.pack(side='right', expand='yes', fill='x')
tk.Button(root, text='Enter', command=do_something_with_entries).pack(side='left', padx=5, pady=5)
root.mainloop()
You are storing the questions as keys and Entry widgets as values of the entries dict.
Firstly, put the entries dict out of the makeform function (otherwise, only makeform function would be able to use it)
Secondly, create the answer dict. We are going to store the answers here.
Thirdly, create a fetch function which is to be called when the user clicks Enter button. It will go through the entries dict and set the values of the answers dict to the entered answers (using Entry.get(...) method)
Now you can process the form answers.
Here is an example:
from tkinter import *
import pandas as pd
fields = ('Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)',
'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)')
entries = {}
answers = {}
def makeform(root, fields):
for field in fields:
row = Frame(root)
lab = Label(row, width=22, text=field + ": ", anchor='w')
ent = Entry(row)
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries[field] = ent
return entries
def fetch():
for question in entries:
answers[question] = entries[question].get()
print(answers) # do something with the results now
if __name__ == '__main__':
root = Tk()
ents = makeform(root, fields)
root.bind('<Return>', fetch)
b1 = Button(root, text='Enter', command=fetch)
b1.pack(side=LEFT, padx=5, pady=5)
root.mainloop()
PS: You don't need to use a lambda-function as the button command. Simply use the fetch function as a command.
PS 1: And why do you call ent.insert(0, "")? It has no effect.

how to get the values from fields as a variable

I got a piece of code and I want to change it for my project, but I don't know how to get the value of my entries has a variable to be used in the start function. Here is my code:
#!/usr/bin/python3
import wiringpi
from time import sleep
gpio = wiringpi.GPIO(wiringpi.GPIO.WPI_MODE_GPIO)
shutterpin = 17
flashpin = 18
solenoidpin = 22
gpio.pinMode(shutterpin,gpio.OUTPUT)
gpio.pinMode(flashpin,gpio.OUTPUT)
gpio.pinMode(solenoidpin,gpio.OUTPUT)
wiringpi.pinMode(shutterpin,1)
wiringpi.pinMode(flashpin,1)
wiringpi.pinMode(solenoidpin,1)
from Tkinter import *
fields = 'size_drop1', 'interval_drop', 'size_drop2', 'lapse_before_flash', 'shutter_time'
def fetch(entries):
for entry in entries:
field = entry[0]
text = entry[1].get()
print('%s: "%s"' % (field, text))
def start(entries):
size_drop1 : float(size_drop1)
interval_drop : float(interval_drop)
size_drop2 : float(size_drop2)
lapse_before_flash : float(lapse_before_flash)
shutter_time : float(shutter_time)
sleep(lapse_before_flash)
gpio.digitalWrite(shutterpin,gpio.HIGH)
sleep(0.5)
gpio.digitalWrite(shutterpin,gpio.LOW)
gpio.digitalWrite(solenoidpin,gpio.HIGH)
sleep(size_drop1)
gpio.digitalWrite(solenoidpin,gpio.LOW)
gpio.digitalWrite(solenoidpin,gpio.HIGH)
sleep(interval_drop)
gpio.digitalWrite(solenoidpin,gpio.LOW)
gpio.digitalWrite(solenoidpin,gpio.HIGH)
sleep(size_drop2)
gpio.digitalWrite(solenoidpin,gpio.LOW)
sleep(lapse_before_flash)
gpio.digitalWrite(flashpin,gpio.HIGH)
sleep(0.5)
gpio.digitalWrite(flashpin,gpio.LOW)
def makeform(root, fields):
entries = []
for field in fields:
row = Frame(root)
lab = Label(row, width=15, text=field, anchor='w')
ent = Entry(row)
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries.append((field, ent))
return entries
if __name__ == '__main__':
root = Tk()
ents = makeform(root, fields)
root.bind('<Return>', (lambda event, e=ents: fetch(e)))
b1 = Button(root, text='Show',
command=(lambda e=ents: fetch(e)))
b1.pack(side=LEFT, padx=5, pady=5)
b2 = Button(root, text='start', command=(lambda e=ents: start(e)))
b2.pack(side=LEFT, padx=5, pady=5)
b3 = Button(root, text='Quit', command=root.quit)
b3.pack(side=LEFT, padx=5, pady=5)
root.mainloop()
You seem to have the right idea on the fetch function part of your code, to access the typed text in a Entry Box on Tkinter, you can use the .get() function, like so:
# main tk window
root = Tk()
# creates the entry_box
entry_box = Entry(root, text='')
# places the entry_box on the program
entry_box.grid()
# changes the text, starting on the first char of the entry_box to 'test'
# (for testing purposes)
entry_box.insert(0, 'test')
# prints the typed test, in this case 'test'
print(entry_box.get())
# run the program
mainloop()
This will print the inserted string, just so you get the hang of it.
Also remember to assign the Entry to a variable, so you can call the .get() function.

How can I add a tkinter combobox widget to a gui that also has text entry widgets?

I am developing a gui with text entry widgets that regenerate based on the number of a records in a table. I am using a list of fields that are each created as an entry widget. For at least one of these fields, I want to set up a combobox with values for the user to choose from. I've been playing around with adding a combobox to the root (I've just inserted a sample one for now) but it doesn't show up when I run the script. I don't get an error, the gui shows up with all the entry boxes, but not the combobox. Does anyone have any ideas: Here is some of the code:
import arcpy, tkMessageBox, ctypes, ttk
from Tkinter import *
mosaicD = r'C:\temp\temp.gdb\mapIndex_MD_test'
mapIndexTbl = r'C:\temp\temp.gdb\mapIndexTestTable'
formFields = ['County', 'Route', 'PMB', 'PME', 'Map_Sheet_Desc', 'HangingFileGroup', 'MapSubSet', 'MapSubSetStatus', 'Shtext', 'Status',
'SubStatus', 'MapDatum', 'Geo_Referenced_Datum', 'MapScale', 'CAD', 'DrawingDate', 'FileExtention','Original_MrSID_Filename']
fields = arcpy.ListFields(mapIndexTbl)
with arcpy.da.SearchCursor(mosaicD,'name') as cursorB:
for rowB in cursorB:
inputValues = []
def fetch(entries):
for entry in entries:
field = entry[0]
text = entry[1].get()
inputValues.append(text)
root.destroy()
def makeform(root, fields):
entries = []
for field in fields:
row = Frame(root)
lab = Label(row, width=20, text=field, anchor='w')
ent = Entry(row)
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries.append((field, ent))
return entries
if __name__ == '__main__':
root = Tk()
root.iconbitmap(r'\\sv04docifs5\data5\vol2\Records\GIS\Logos\CT.ico')
root.geometry('375x650')
root.wm_title('Enter values for '+rowB[0])
cities = ('Toronto', 'Ottawa', 'Montreal', 'Vancouver', 'St. John')
cblist = Frame(root)
cbp3 = ttk.Labelframe(cblist, text='Pre-defined List')
cb3 = ttk.Combobox(cbp3, values=cities, state='readonly')
cb3.current(1) # set selection
cb3.pack(side=LEFT, expand=YES, fill=X)
# position and display
cbp3.pack(in_=cblist, side=TOP, pady=5, padx=10)
ents = makeform(root, formFields)
root.bind('<Return>', (lambda event, e=ents: fetch(e)))
b1 = Button(root, text='Submit',
command=(lambda e=ents: fetch(e)))
b1.pack(padx=5, pady=5,anchor=CENTER)
#b2 = Button(root, text='Quit', command=root.quit)
#b2.pack(side=LEFT, padx=5, pady=5)
root.mainloop()
The combobox cb3 is packed in the frame cbp3. That frame is packed in frame cblist. Nowhere do you call pack or grid on cblist. Since cblist is invisible, so are its children.

Cannot get the updated value from entry python tkinter

I am new in python GUI. I was trying to get the value from 'abc' entry box. However, it can only get the default value (which is 58 now). If I change the value then it cannot get the changed (or current) value. Your input would be highly appreciated.
fields = ('abc', 'def', 'ghi','jkl')
def outputdata(master, fields):
entries = {}
helpLf = LabelFrame(master, text="2. Bill of Materials:")
helpLf.grid(row=0, column=9, columnspan=5, rowspan=8, \
sticky='NS', padx=5, pady=5)
for n in range(len(fields)):
lab = Label(helpLf, text= fields[n]+": ", anchor='w')
lab.grid(row=n, column=5, padx=5, pady=5)
ent = Entry(helpLf, bg="yellow")
ent.insert(0,"58")
ent.grid(row=n, column=7, padx=5, pady=5)
entries[fields[n]] = ent
return entries
if __name__ == '__main__':
master = Tk()
ents = outputdata(master, fields)
t = outputdata(master, fields)['abc'].get()
Button(master, text='Show me the BoM', command = (lambda e=ents:clamp_number(e))).grid(row=10, column=0, sticky=W, pady=4)
Without knowing what clamp_number is, I cannot comment on your code in particular.
But, if you want to know how to get the "current" value of a Entry widget, you will have to use a StringVar variable.
>>> from tkinter import Tk, StringVar, Entry
>>> root = Tk()
>>> sv = StringVar(root)
>>> entry = Entry(root, textvariable=sv)
>>> sv.get()
''
>>> entry.insert('insert', 'hello')
>>> sv.get()
'hello'
>>>
Whats happening here is, you are binding an Entry widget to a StringVar. You can call the StringVar's get() and set() methods as required.

Categories

Resources