from tkinter import *
from datetime import datetime
import pickle
import os
##database will be with these mulas = dict{"name":["value","rate","left"]}
def _price_inputs():
filename = "datas.pk"
rupen = Tk()
rupen.title("Montessori Management System")
rupen.geometry("1600x800")
rupen.configure(bg="black")
framex = Frame(rupen, width=1600, bg="RoyalBlue4", height=100, relief=GROOVE).pack(side=TOP)
# ==++++===========================title=============================
#this is the variable for incoming
names = StringVar()
rates = IntVar()
totals = IntVar()
llb1 = Label(framex, font=("arial", 20, "italic"), bg="black", fg="green", text="STOCK MANAGEMENT",
relief=GROOVE).pack(side=TOP)
now = datetime.now()
hour = str(now.hour)
d = str("\\")
minute = str(now.minute)
second = str(now.second)
year = str(now.year)
month = str(now.month)
day = str(now.day)
time = "\t\t"+year + d + month + d + day + "\n\t\t" + hour + ":" + minute + ":"+second+"\n\n"
showing = str("#") * 100 + "\n"
def add_on():
name = names.get()
rate = float(rates.get())
total = float(totals.get())
with open(filename, "rb") as f:
dic = pickle.load(f)
dic[name] = [rate,total]
with open(filename, "wb") as f:
pickle.dump(dic, f)
names.set("")
rates.set("")
totals.set("")
"""with open(filename, "rb") as f:
dic = pickle.load(f)
lbl.insert(END, "\n")
lbl.insert(END, dic)
print(dic)"""
#_price_inputs()
#add_fun()
rupen.destroy()
_price_inputs()
def _sold():
nam = names.get()
rat = rates.get()
total = totals.get()
total = float(total)
with open(filename, "rb") as f:
dic = pickle.load(f)
sold = dic[nam][1]
dic[nam][1] = sold - rat
with open(filename, "wb") as f:
pickle.dump(dic, f)
names.set("")
rates.set("")
totals.set("")
rupen.destroy()
_price_inputs()
def quit():
# show = "asjdfaskldjflsajdlfj"
lbl.delete(0.0, END)
rupen.destroy()
# lbl.insert(END,"asjdfaskldjflsajdlfj")
'''
rate = str(rate)
total = str(total)
with open(filename, "rb") as f:
dic = pickle.load(f)
if os.path.getsize(filename) >= 1:
dic[name] = [rate,total]
lbl.insert(END, dic)'''
lbl = Text(rupen, wrap=WORD, font=("arial", 16, "bold"), height=100, fg="red", width=100)
lbl.pack(side=RIGHT)
# show = "asjdfaskldjflsajdlfj"
with open(filename, "rb") as f:
ano = pickle.load(f)
lbl.insert(END, time)
for k, v in ano.items():
lbl.insert(END, "\n")
lbl.insert(END, k)
lbl.insert(END, "--> ")
lbl.insert(END, "\t")
lbl.insert(END, v[0])
lbl.insert(END, "\t")
lbl.insert(END, v[1])
lbl.insert(END, "\n")
'''for k, v in dic.items():
show = """{} --> rate:- {} Total:- {}
""".format(k,v[0],v[1])
lbl.insert(END, show)
'''
####################ENTRY############################
ent1 = Entry(rupen,font=("arial",16,"bold"),textvariable=names,bd=5,bg="black",fg="white")
ent1.pack(side=BOTTOM)
ent2 = Entry(rupen,font=("airal",16,"bold"),bd=5,bg="black",textvariable=rates,fg="white")
ent2.pack(side=BOTTOM)
ent3 = Entry(rupen,font=("arial",16,"bold"),bd=5,bg="black",textvariable=totals,fg="white")
ent3.pack(side=BOTTOM)
####################BUTTONS#########################
btn0 = Button(rupen,font=("arial",16,"bold"),bd=5,bg="black",text="sold",fg="white",command=_sold)
btn0.pack(side=BOTTOM)
btn = Button(rupen, font=("arial", 16, "bold"), bd=5, bg="black", fg="white", text="quit", command=quit,
relief=RAISED)
btn.pack(side=BOTTOM)
btn2 = Button(rupen, font=("arial", 16, "bold"), bd=5, bg="black", fg="white", text="Add", relief=RAISED,
command=add_on)
btn2.pack(side=BOTTOM)
def rupen_():
rupen.destroy()
#with open("filename.pk", "wb") as f:
#pickle.dump(f, data)
# pass
rupen.mainloop()
if __name__ == "__main__":
_price_inputs()
I have this tkinter code where i can add the items with the item name rate and Total. I am not getting the float answer while clicking add or sold button.
Suppose i want to add the item1 with 12.3 rate and Total 10.5 and after i click the add button it only adds 12.0 and 10.0 the value after the . is lost.
You can't upcast an integer to a float and not expect to lose data.
rate = float(rates.get())
total = float(totals.get())
The code piece above doesn't get the float values entered back. Because you downcast float values to integers first, losing the data after .. Instead, use DoubleVar as opposed to IntVar from the very beginning:
rates = DoubleVar()
totals = DoubleVar()
You can get that by using string formatting. This "%.2f" means two decimal places after the value.
Replace this
dic[name] = [rate, total]
with this
dic[name] = ["%.2f"%rate, "%.2f"%total]
all you can add all variable for the float with the string formatting
"%.2f"
This small example to demonstrate to you how to use string formatting when use convert an Integer to float want to get two decimal places
from tkinter import *
def sum():
two_decimal = float(e1.get())- float(e2.get())
print(two_decimal) # this will print with only one decimal place
print("%.2f"%two_decimal) # this will print with only two decimal places
root = Tk()
e1 = Entry(root)
e1.insert(0, 400)
e1.pack()
e2 = Entry(root)
e2.insert(0, 200)
e2.pack()
b = Button(root, text="Want to get float value", command=sum)
b.pack()
root.mainloop()
Related
I have two issues.
One:
I can't figure out how to calculate days left until a specific date which the user inputs in a calendar interface.
Secondly:
I want to use the numbers that the user has input in the interface to do some calculations with, and to watch what is going on I print some of the input to the terminal - however, the .value attribute returns "0" and I don't understand why.
Below the #PROXIMITY comment in the code you will find the calendar/date. I just want to subtract the date today from the date specified by the user in the calendar interface and output the days left.
Below the #VALUE is the calculation that prints "0" when i print the .value attribute.
Full code:
from tkcalendar import * # Calendar module
import tkinter.messagebox # Import the messagebox module
import datetime
import pickle
task_list = []
task_types = ['Sparetime', 'School', 'Work']
class Task:
def __init__(self, n, type_, i, m, p, h, v): #(w=8, p, u, n, v):
self.name = n
self.type = type_
self.impact = i
self.manageability = m
self.proximity = p
self.hours = h
self.value = v
#self.connectivity = c
##self.work = w ##hours of work per day
##self.urgency = u
##self.note = n
##self.value = v
def show_tasks():
# DELETED: for task in task_list:
# REPLACED WITH: task = task_list[-1]
task = task_list[-1]
#print(
#'Task:'+task.name + '\n' +
#'Impact:' + task.impact + '\n' +
#'Manageability:' + task.manageability + '\n' +
#'Hours:' + task.hours + '\n'
#'Value:' + task.value +'\n'
#)
print('Task:')
print(task.name)
print('\n')
print('Impact:')
print(task.impact)
print('\n')
print('manageability:')
print(task.manageability)
print('\n')
print('Hours')
print(task.hours)
print('\n')
print('Value:')
print(task.value)
def open_add_task():
taskwin = Toplevel(root)
taskwin.focus_force()
#TITLE
titlelabel = Label(taskwin, text='Title task concisely:', font=('Roboto',11,'bold')).grid(column=1, row=0)
name_entry = Entry(taskwin, width=40, justify='center')
name_entry.grid(column=1, row=1)
#TYPE
typelabel = Label(taskwin, text='Type', font=('Roboto',10)).grid(column=0, row=2)
type_var = StringVar(value=task_types[0])
OptionMenu(taskwin, type_var, *task_types).grid(column=0, row=3, sticky='nsew')
#IMPACT
impactlabel = Label(taskwin, text='Impact', font=('Roboto',10)).grid(column=1, row=2)
imp_var = StringVar(value=0)
OptionMenu(taskwin, imp_var, *range(0, 10+1)).grid(column=1, row=3, sticky='ns')
#MANAGEABILITY
manlabel = Label(taskwin, text='Manageability', font=('Roboto',10)).grid(column=2, row=2)
man_var = StringVar(value=0)
OptionMenu(taskwin, man_var, *range(0, 10+1)).grid(column=2, row=3, sticky='nsew')
#PROXIMITY
proximity_label = Label(taskwin, text = 'Choose a deadline', font=('Roboto',10), justify='center')
proximity_label.grid(column=1, row=4)
cal = Calendar(taskwin, selectmode='day', year=2021, month=4, day=27)
cal.grid(column=1, row=5)
def get_date():
proximity_output_date.config(text=cal.get_date()) ##the .config didn't work until i did .grid(column=, row=) on seperate lines
#HOURS(required)
hourlabel = Label(taskwin, text='Whole hours \n required', font=('Roboto',10)).grid(column=1, row=16)
hour_entry = Entry(taskwin, width=4, justify='center')
hour_entry.grid(column=1, row=17)
#CONNECTIVITY
#for index, task in enumerate(task_list):
#Checkbutton(taskwin, **options).grid(column=0, row=index)
C_lab = Label(taskwin,text="Check tasks this task is related to").grid(column=1, row=18)
placement=19
for task in task_list:
Checkbutton(taskwin, text=(task.name)).grid(column=1, row=placement, sticky="w")
placement+=1
#VALUE
val_var = (int(imp_var.get()))+ (int(man_var.get()))
def add_task():
if name_entry.get() != '': # If textbox inputfield is NOT empty do this:
task_list.append(Task(name_entry.get(), type_var.get(), imp_var.get(), man_var.get(), cal.get_date(), hour_entry.get(), val_var))
show_tasks()
listbox_tasks.insert(tkinter.END, name_entry.get())
name_entry.delete(0, tkinter.END)
taskwin.destroy()
else:
tkinter.messagebox.showwarning(title='Whoops', message='You must enter a task')
next_button = Button(taskwin, text='Next', font=('Roboto',10), command=add_task).grid(column=2, row=placement, sticky="e")
placement+=1
def sort_tasks():
pass
def delete_task():
try:
task_index = listbox_tasks.curselection()[0]
listbox_tasks.delete(task_index)
except:
tkinter.messagebox.showwarning(title='Error', message='You must select a task to delete')
def save_tasks():
pass
#tasks = listbox_tasks.get(0, listbox_tasks.size())
#pickle.dump(tasks, open('tasks.dat', 'wb'))
root = Tk()
task_frame = Frame()
# Create UI
your_tasks_label = Label(root, text='THESE ARE YOUR TASKS:', font=('Roboto',10, 'bold'), justify='center')
your_tasks_label.pack()
scrollbar_tasks = tkinter.Scrollbar(root)
scrollbar_tasks.pack(side=tkinter.RIGHT, fill=tkinter.Y)
listbox_tasks = tkinter.Listbox(root, height=10, width=50, font=('Roboto',10), justify='center') # tkinter.Listbox(where it should go, height=x, width=xx)
listbox_tasks.pack()
listbox_tasks.config(yscrollcommand=scrollbar_tasks.set)
scrollbar_tasks.config(command=listbox_tasks.yview)
try:
#tasks = pickle.load(open('tasks.dat', 'rb'))
listbox_tasks.delete(0, tkinter.END)
for task in task_list:
listbox_tasks.insert(tkinter.END, task)
except:
tkinter.messagebox.showwarning(title='Phew', message='You have no tasks')
#BUTTONS
Add_Button = Button(root, text='Add New', width=42, command=open_add_task)
Add_Button.pack()
button_delete_task = Button(root, text='Delete task', width=42, command=delete_task)
button_delete_task.pack()
button_save_tasks = Button(root, text='Save tasks', width=42, command=save_tasks)
button_save_tasks.pack()
#sort_type = StringVar(value='All')
#OptionMenu(btn_frame, sort_type, 'All', *task_types).grid(column=0, row=0, sticky='nsew')
#sort_imp = StringVar(value='Any')
#OptionMenu(btn_frame, sort_imp,'Any', *range(0, 10+1)).grid(column=1, row=0, sticky='nsew')
#Button(btn_frame, text='Sort', command=sort_tasks).grid(column=1, row=1, sticky='nsew')
root.mainloop()
how to calculate days left until a specific date
You might subtract datetime.date from datetime.date to get datetime.timedelta object holding numbers of days, consider following example
import datetime
d1 = datetime.date(2021, 1, 1) # year, month, day
d2 = datetime.date(2021, 1, 10)
diff21 = (d2-d1).days
diff12 = (d1-d2).days
print(diff21)
print(diff12)
output
9
-9
For getting current date you might use datetime.date.today().
For your first issue, you can use cal.selection_get() to return the selected date in datetime.date type. Then you can calculate the days left easily:
selected = cal.selection_get()
delta = (selected - datetime.date.today()).days
status = "overdue" if delta <= 0 else f"{delta} days left"
print(f"{selected} ({status})")
For second issue, you need to move the line val_var = (int(imp_var.get()))+ (int(man_var.get())) into add_task() function:
def add_task():
if name_entry.get() != '':
val_var = int(imp_var.get()) + int(man_var.get())
...
else:
...
Note that you need to do some validations on the values returned by imp_var.get() and man_var.get() to avoid exception due to invalid values.
I originally created a python word sort function that was meant to record all the words in a txt file and read back while counting the occurence of each word. This program worked correctly, I then sought out to modify this program to count only the top 20 words of a html file and read back the occurrence of only those top 20 words. However after working through the bugs it's not giving me the correct formatting and the correct count. I'm seeking a count that looks like this:
however my count appears as so:
and doesn't give the correct count. I've debugged all the errors however I don't understand what's occurring to cause this difference in output.
#Imports
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from collections import Counter
#Functions
def countWords(s):
signos = [',', '.', ';', ':']
cleanstr = ''
for letra in s.lower():
if letra in signos:
cleanstr += ''
else:
cleanstr += letra
strlist = cleanstr.split(' ')
return dict(Counter(strlist))
def open_file():
text = mainWindow.e2.get()
count = countWords(s)
myLabel = Label(root, text=open_file)
myLabel.pack()
#Graphics
fullString = ""
root = tk.Tk()
root.title("Count words")
root.geometry('400x400')
root.fileToRead = filedialog.askopenfilename(initialdir="c:/temp/", filetypes=(("HTML File", "*.html"),("All Files","*.*")), title = "choose a file.")
wordCount = {}
fileName = root.fileToRead.split('/')
fileName = fileName[len(fileName)-1]
label = tk.Label(root, text="Top 20 Words For: " + fileName + '\n' + fullString, foreground="black", font=("Times New Roman", 16))
#Background Image Label
#bg = PhotoImage(file = "./guibackground.gif")
# Show image using label
#label1 = Label( root, image = bg)
#label1.place(relx=0.5, rely=0.5, anchor=CENTER)
#Class Window
class Window:
def __init__(self):
self.root = tk.Tk()
self.btn = tk.Button(text='Open File', command=self.open_file)
self.btn.pack()
self.btn = tk.Button(text='Exit', command=root.quit)
self.btn.pack()
self.lbl = tk.Label()
self.lbl.pack()
self.root.mainloop()
def open_file(self):
filename = filedialog.askopenfilename(initialdir='/', title='Select file', filetypes=(('html files','*.html'), ('all files','*.*')))
with open(filename, 'r') as f:
self.lbl.configure(text=f'{Counter(f.read().split())}')
def word_count(self):
sorted_wordCount = sorted(wordCount.items(), key = lambda kv:(kv[1], kv[0]), reverse=True)
count = 1
fullString = ""
for item in sorted_wordCount:
if count < 20:
fullString = fullString + str(count) + ": "+ str(item) + '\n'
elif count == 20:
fullString = fullString + str(count) + ": " + str(item)
else:
break
count = count + 1
self.button = Button(root, text="Open File", command=open_file)
self.button.pack()
self.exit_button = Button(root, text="Exit", command=root.quit)
self.exit_button.pack()
if __name__ == '__main__':
mainWindow = Window()
root.mainloop()
I took out the gif image background in order to eliminate the error that would cause.
change self.lbl = tk.Label() to self.lbl = tk.Message(self.root). then use the following code:
class Window:
def __init__(self):
...
def open_file(self):
filename = filedialog.askopenfilename(initialdir='/', title='Select file', filetypes=(('html files','*.html'), ('all files','*.*')))
with open(filename, 'r') as f:
self.lbl.configure(text=f'{self.formatFun(Counter(f.read().split()).most_common(20))}')
def formatFun(self, var):
string = "Top 20 words for: mathbeth.html \n"
for index, item in enumerate(var, start=1):
string += f'{index}: {item} \n'
return string
I was making a simple flashcard tkinter application and I've encountered a problem such that when I manage the subjects, only every second item is added to the file.
For example, say I went to the manage subject page and I wanted to add the subjects: subject1, subject2, subject3, subject4, ... subjectN.
The only subjects that would add to the file are the subjects with the odd endings, is there a fix for this?
The code responsible for this:
#subjects window
def managesubjectsF():
def addF():
f = open ('subjectlist.txt', 'a')
f.write(addsubjectE.get() + '\n')
f.close()
addsubjectE.delete('0', 'end')
subjectPage = Tk()
subjectPage.title('Add subject')
subjectPage.resizable(False, False)
subjectPage.configure(background = 'light blue')
subjectPage.geometry('260x70')
addsubjectE = Entry(subjectPage, width=23, font=('bold', 14))
addsubjectE.grid(column=1, row=1)
addS = Button(subjectPage, text='Add', font=('bold', 15), command = addF)
addS.grid(column=1, row=2, sticky = N)
Minimal example of implementation:
#modules
from tkinter import *
import os.path
#implementations
count=0
subjectlist = []
#main window details
root = Tk()
root.geometry('225x350')
#list of available subjects
choice = Listbox(root, font = ('bold', 15))
choice.grid(column=1, row=2)
if os.path.exists('./subjectlist.txt') == True:
with open('subjectlist.txt', 'r') as f:
for line in f:
count += 1
f.close()
f = open('subjectlist.txt', 'r')
for i in range(count):
choice.insert(END, (f.readline().strip()))
subjectlist.append(f.readline().strip())
f.close()
else:
f = open('subjectlist.txt', 'w')
f.close()
#subjects window
def managesubjectsF():
def addF():
f = open ('subjectlist.txt', 'a')
f.write(addsubjectE.get() + '\n')
f.close()
addsubjectE.delete('0', 'end')
subjectPage = Toplevel()
subjectPage.geometry('260x70')
addsubjectE = Entry(subjectPage, width=23, font=('bold', 14))
addsubjectE.grid(column=1, row=1)
addS = Button(subjectPage, text='Add', font=('bold', 15), command = addF)
addS.grid(column=1, row=2, sticky = N)
#buttons
addsubjectsB = Button(root, text = 'Manage subjects', font = ('bold', 15), command = managesubjectsF)
addsubjectsB.grid(column=1, row=3, sticky = N)
root.mainloop()
(moving comment to answer)
You are calling readline twice which is moving the file pointer and skipping subjects.
for i in range(count):
choice.insert(END, (f.readline().strip()))
subjectlist.append(f.readline().strip()) # reading next line
Try reading the value once then storing in both lists:
for i in range(count):
s = f.readline().strip() # read once
choice.insert(END, (s))
subjectlist.append(s)
I have been trying to learn tkinter and have created something that post the results of a bunch of functions, and in the terminal the string formats works, but in the gui the string format does not work at all. I am super confused on why?
The code is below:
from tkinter import *
import ForFeesCovered
root = Tk()
root.title("Staff Fee Calculator")
root.geometry("375x400")
myLabel = Label(root,
text="Staff Fee Calculator")
e = Entry(root,
width=50,
borderwidth=5)
def output():
input_file = e.get()
f = ForFeesCovered.readfile(input_file)
file = ForFeesCovered.readfile(input_file)
staff = ForFeesCovered.getnamesofstaff(f)
staff.sort(reverse=False)
dic = ForFeesCovered.sort_dic(staff)
line_skip = 1
for lines in file:
line = lines.strip().split(",")
if line_skip != 1:
total = float("
{:.2f}".format(ForFeesCovered.getfeesforline(line)))
name = ForFeesCovered.get_name_of_staff(line, staff)
dic = ForFeesCovered.populating_dic(dic, name, total)
else:
line_skip += 1
string_dic = ""
result_file = open("result.txt", "w+")
for key in dic:
result_file.write("{} : {}\n".format(key, dic[key]))
string_dic = string_dic + "{:30} : {:>30}\n".format(key,
dic[key])
print(string_dic)
result_file.close()
output_dic = Label(root, text=string_dic, justify=LEFT)
output_dic.grid(row=2, column=0, pady=20)
submit = Button(root, text="Submit", command=output)
myLabel.grid(row=0, column=0)
e.grid(row=1, column=0,)
submit.grid(row=1, column=2)
root.mainloop()
The terminal is using a fixed-width font, the GUI is using a variable-width font.
If you are trying to line things up with spaces, you will need to used a fixed-width font.
please help me run arithmetic summation in the file operations using Python Tkinter
input should be here (in the textbox)
summation output should be in TXT file
Source Code :
INPUT
topup = tkinter.StringVar()
TextBox_1 = ttk.Entry(jendela, width=20, textvariable=topup)
TextBox_1.grid(column = 1, row = 3)
BUTTON
def clickhere():
f = open("TOPUP", "r")
w = f.readline()
f.close()
f = open("TOPUP", 'r+')
t=int(w)+ (topup.get())
f.write(str(t))
f.close()
button_ = ttk.Button(jendela, text='Top up!', command=lambda : clickhere, width=17)
button_.grid(column=2, row=3)
try this code:
from tkinter import *
root= Tk()
topup = StringVar()
TextBox_1 = Entry(root, width=20, textvariable=topup)
TextBox_1.grid(column = 1, row = 3)
def clickhere():
f = open("TOPUP.txt", "r+")
w = f.readline()
t=int(w)+ int(topup.get())
f.seek(0)
f.truncate()
f.write(str(t))
f.close()
button_ = Button(root, text='Top up!', command=clickhere, width=17)
button_.grid(column=2, row=3)