I am writing a calendar program using the tkinter module and clicking on each day on the grid will print out the current day's date (month/day/year). However, I also want to add another section at the bottom that will show what day of the year it is. Like this:
For example, January 1, 2020 would be the first day of the year, March 20 will be the 80th day of the year, etc. I want my radio buttons to be able to control both of these variables, the date as a string, and the day of the year as an integer. Is this possible?
strDate = StringVar()
labelDate = Label(frameDay, textvariable=strDate, width=28,
font=("Consolas", "15", "bold")).grid(row=1, column=1)
# Creating the calendar grid
while day <= self.returnMaxDay():
currentDay = Date(self.month, day, self.year)
radDay = Radiobutton(frameCalendar, text=str(day),
font=("Consolas", "15", "bold"), indicatoron=0, width=4, height=1,
variable=strDate, value=str(currentDay.returnDayName()) + ", "
+ str(currentDay.returnMonthName()) + " "
+ str(day) + ", " + str(currentDay.year))
radDay.grid(row=row, column=weekDay)
day += 1
weekDay += 1
if weekDay == 7:
row += 1
weekDay = 0
labelDayOfYear = Label(window, text=str(self.dayOfYear()), font=("Consolas", "20")).pack()
It is simple example which uses command= in Radiobutton to run function which changes text it three Labels.
Normally command= expect function's name without () and arguments so I use lambda to assing function with arguments.
command=lambda d=current_day:on_click(d))
I also use d=current_day to create new variable d for every function. Without d=current_day all functions would use reference to the same variable current_day and all functions would use the same (last) value in current_day.
import tkinter as tk
import datetime
# --- functions ---
def on_click(value):
print(value)
label_date['text'] = value.strftime('%a, %b %d, %Y')
label_day['text'] = value.strftime('Day: %d')
label_weekday['text'] = value.strftime('Weekday: %a')
# --- main ---
root = tk.Tk()
radiobutton_var = tk.StringVar()
year = 2020
month = 4
row = 0
for day in range(1, 32):
try:
current_day = datetime.datetime(year, month, day)
date_str = current_day.strftime('%a, %m %d, %Y')
weekday = current_day.weekday()
radiobutton_day = tk.Radiobutton(root,
text=str(day),
indicatoron=0,
variable=radiobutton_var,
value=date_str,
#value=day,
command=lambda x=current_day:on_click(x))
radiobutton_day.grid(row=row, column=weekday, sticky='we')
if weekday == 6:
row += 1
radiobutton_day['bg'] = '#faa'
except ValueError as ex:
print(ex)
break
label_date = tk.Label(root, text='?')
label_date.grid(row=10, columnspan=10)
label_day = tk.Label(root, text='Day: ?')
label_day.grid(row=11, columnspan=10)
label_weekday = tk.Label(root, text='Weekday: ?')
label_weekday.grid(row=12, columnspan=10)
root.mainloop()
BTW: I use datetime to generate dates and try/except to catch error when date is incorrect.
I also use strftime to format date - see more on page strftime.org
Related
Good,
I'm trying to sum the values of a column, while inputting it. Since I put a code in the entry and check if it exists and put it in columns in treeview, and I would like to add only the "price" values, but I can't do it, I get the data from the price column, but I can't get if This 5.99 I have entered another 5.99 add up and give me a total, as I add a price.
What I can be doing wrong? or what I have wrong
Any additional information would be appreciated.
def Cesta(self):
self.conex()
self.b_codigo = self.s_Codigo.get()
self.sql3 = "SELECT * FROM productos WHERE codigo = %s"
self.mycursor.execute(self.sql3,[(self.b_codigo)])
self.r_codigo = self.mycursor.fetchall()
self.row3 = [item['nombre'] for item in self.r_codigo]
if self.s_Codigo.get() == "":
MessageBox.showinfo("ERROR", "DEBES INTRODUCIR DATOS", icon="error")
elif self.r_codigo:
for self.x2 in self.r_codigo:
print (self.x2["nombre"], self.x2["talla"], self.x2["precio"]+"€")
self.tree.insert('', 'end', text=self.x2["nombre"], values=(self.x2["talla"],self.x2["precio"]+" €"))
print(self.x2["fecha"])
for self.item in self.tree.get_children():
self.resultado = 0
self.celda = int(self.tree.set(self.item,"col2"))
self.total = int(self.resultado) + int(float(self.celda))
print(self.total)
else:
MessageBox.showinfo("ERROR", "EL CODIGO INTRODUCIDO NO ES CORRECTO", icon="error")
self.clear_entry()
`
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
return self.func(*args)
File "/Users/tomas/Downloads/PROYECTO/main.py", line 205, in Cesta
self.celda = int(self.tree.set(self.item,"col2"))
ValueError: invalid literal for int() with base 10: '134,99 €'
[Finished in 6.7s]
`
self.tree = ttk.Treeview(self.pagina1,columns=("col1","col2"), height=50)
self.tree.grid(column=0, row=2, padx=50, pady=100)
### COLUMNAS ###
self.tree.column("#0",width=250)
self.tree.column("col1",width=150, anchor=CENTER)
self.tree.column("col2",width=150, anchor=CENTER)
### NOMBRES COLUMNAS ###
self.tree.heading("#0", text="Articulo", anchor=CENTER)
self.tree.heading("col1", text="Talla", anchor=CENTER)
self.tree.heading("col2", text="Precio", anchor=CENTER)
Everything else is going well for me, but the part in which I want to add the results of the price column does not
What am I doing wrong, to be able to add the values of the prices column every time I insert a new product?
I have already managed to solve the error, the new price is already added to the old one, thanks for making me reflect on it.
for self.x2 in self.r_codigo:
print (self.x2["nombre"], self.x2["talla"], self.x2["precio"]+"€")
self.tree.insert('', 'end', text=self.x2["nombre"], values=(self.x2["talla"],self.x2["precio"]))
self.total = 0
for self.item in self.tree.get_children():
self.celda = float(self.tree.set(self.item,"col2"))
self.total+=self.celda
print(self.total)
I am trying to update a listbox line, based on a condition, but get this error:
_tkinter.TclError: bad listbox index "Wednesday 15 April 2020 ": must be active, anchor, end, #x,y, or a number
These are the script lines. I get the same error when I use i, or tk.END with listboxMain.delete
for i, dt in enumerate(daterange(date1, date2)):
holiday = us_holidays.get(dt)
if not holiday:
holiday = ""
day, date, month, year = dt.strftime('%A %d %B %Y').split()
line = f'{day:10s} {date} {month:>10s} {year:>7} {holiday}'
if (datetime.date.today() - dt).days == 0:
TODAY_INDEX = i
listboxMain.insert(tk.END, line)
for b in list_birthdays:
if b == dt:
listboxMain.delete(i, line) <====== Error is here.
listboxMain.insert(i, line + " Birthday of ")
listboxMain.itemconfig(i, {'bg': '#999966'})
listboxMain.itemconfig(i, {'fg': '#000066'})
break
listboxMain.itemconfig(TODAY_INDEX, {'bg': '#cc9900'})
listboxMain.itemconfig(TODAY_INDEX, {'fg': '#000099'})
I'm making a code that when running through is giving me a list dropd with just 1 item and a variable age that was supposed to be a int continues a string.
When I work with the code in Debug mode I notice that If I execute only the list dropd line then It gives me the correct items and if I execute the age = int(agee) alone then It gives me an int as result.
What`s going on here?
if sistema_selected == 2:
self.driver.switch_to.frame(self.driver.find_element_by_xpath("//iframe[#data-id='1']"))
...
time.sleep(3)
try:
print('CPF Valido')
self.driver.find_element_by_xpath('//*[#id="mudarMatricula"]/div/div/select').click()
dropd = self.driver.find_elements_by_xpath(
'/html/body/div[2]/div[2]/div[2]/div[4]/div/form/
div[1]/div/div/div/div[2]/div[1]/h3/span[1]/div/div/select/option')
i = 0
for item in dropd:
time.sleep(1)
item.click()
...
agee = idade_split[idade_split.index('Anos') - 1]
age = int(agee)
...
if age < 75:
idade_plc = Label(frame_idade, text=age, borderwidth=1, relief="groove")
idade_plc.grid(row=i + 1, column=0, sticky=EW)
elif age > 75:
idade_plc = Label(frame_idade, text=age, borderwidth=1, relief="groove", bg='red')
idade_plc.grid(row=i + 1, column=0, sticky=EW)
nome_plc = Label(frame_nome, text=nome)
nome_plc.grid(row=0, column=1, sticky=EW)
...
# IF THE CLIENT CODE IS WRONG
except (NoSuchElementException, UnexpectedAlertPresentException):
print('CPF Invalido')
I am writing a code that somehow resembles the Persian calendar. there are 3 drop down lists for year,month and day. here are the rules I'd like to include:
months 1 to 6 have 31 days
months 7 to 11 have 30 days
month 12 has 29 days
every 4 years, 12th month has 30 days(leap year)
if the user chooses on of the (1 - 2 - 3 - 4 - 5 - 6) months, the drop down list for days must have 31 days
if the user chooses on of the (7 - 8 - 9 - 10 - 11 ) months, the drop down list for days must have 30 days
if the user chooses the 12th month, the drop down list for days must have 29 days
if the user chooses one of (1375 – 1379 – 1383 – 1387 – 1391 – 1395) year and if he chooses the 12th month, the drop down list for days must have 30 days
here is the code I have written so far but my code doesn't work, please help me with it.
from tkinter import *
x=StringVar()
def ok():
if months == months[0:5]:
x = dayoptions1
if months == months[6:10]:
x = dayoptions2
if months == months[11] and years == 1375 or 1379 or 1383 or 1387 or 1391 or 1395:
x = dayoptions3
root = Tk()
label1 = Label(root, text="year",width=15)
label1.grid(row=0, column=0)
yearoptions = ["1397", "1396","1395","1394","1393","1392","1391","1390","1389","1388","1387","1386","1385","1384","1383","1382","1381","1380","1379","1378","1377","1376","1375"]
yearvariable = StringVar(root)
yearvariable.set(yearoptions[0])
years = OptionMenu(root, yearvariable, *yearoptions)
years.grid(row=0,column=1,padx=5, pady=5)
label2 = Label(root, text="month",width=15)
label2.grid(row=0, column=2)
monthoptions = ["1", "2","3","4","5","6","7","8","9","10","11","12"]
monthvariable = StringVar(root)
monthvariable.set(monthoptions[0])
months = OptionMenu(root, monthvariable, *monthoptions)
months.grid(row=0,column=3,padx=5, pady=5)
label1 = Label(root, text="day",width=15)
label1.grid(row=0, column=4)
dayoptions1 = ["1", "2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"]
dayoptions2 = ["1", "2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30"]
dayoptions3 = ["1", "2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29"]
dayvariable = StringVar(root)
dayvariable.set("1")
days = OptionMenu(root, dayvariable, *x)
days.grid(row=0,column=5,padx=5, pady=5)
root.mainloop()
I am writing a code that somehow resembles the Persian calendar. there are 3 drop down lists for year, month and day. Here are the rules I'd like to include:
Months 1 to 6 have 31 days
Months 7 to 11 have 30 days
Month 12 has 29 days every 4 years
12th month has 30 days (leap year)
If the user chooses one of the (1 - 2 - 3 - 4 - 5 - 6) months, the drop down list for days must have 31 days.
If the user chooses one of the (7 - 8 - 9 - 10 - 11 ) months, the drop down list for days must have 30 days.
If the user chooses the 12th month, the drop down list for days must have 29 days.
If the user chooses one of (1375 – 1379 – 1383 – 1387 – 1391 – 1395) year and if he chooses the 12th month, the drop down list for days must have 30 days.
Here is the code I have written so far but my code doesn't work, please help me with it.
from tkinter import *
x=StringVar()
def ok():
if months == months[0:5]:
x = dayoptions1
if months == months[6:10]:
x = dayoptions2
if months == months[11] and years == 1375 or 1379 or 1383 or 1387 or 1391 or 1395:
x = dayoptions3
root = Tk()
label1 = Label(root, text="year",width=15)
label1.grid(row=0, column=0)
yearoptions = ["1397", "1396","1395","1394","1393","1392","1391","1390","1389","1388","1387","1386","1385","1384","1383","1382","1381","1380","1379","1378","1377","1376","1375"]
yearvariable = StringVar(root)
yearvariable.set(yearoptions[0])
years = OptionMenu(root, yearvariable, *yearoptions)
years.grid(row=0,column=1,padx=5, pady=5)
label2 = Label(root, text="month",width=15)
label2.grid(row=0, column=2)
monthoptions = ["1", "2","3","4","5","6","7","8","9","10","11","12"]
monthvariable = StringVar(root)
monthvariable.set(monthoptions[0])
months = OptionMenu(root, monthvariable, *monthoptions)
months.grid(row=0,column=3,padx=5, pady=5)
label1 = Label(root, text="day",width=15)
label1.grid(row=0, column=4)
dayoptions1 = ["1", "2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"]
dayoptions2 = ["1", "2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30"]
dayoptions3 = ["1", "2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29"]
dayvariable = StringVar(root)
dayvariable.set("1")
days = OptionMenu(root, dayvariable, *x)
days.grid(row=0,column=5,padx=5, pady=5)
root.mainloop()
Okay I don't tkinter, so I wrote a function but it works. Days depends on what month & year user choose. So scenario is, user choose 1383 - 12 (Year 1383 of Month 12), you need to find if 1383 is a leap year and then fill up the day list with 30 days, or else it would be 29 days. If use choose between month 1 to 6, fill the array with 31 days and the rest of the month has 30 days. I have written a short helper function to check this out and I think it works.
def persian_calender():
user_input = input("year - month:: ")
date_list = user_input.split("-")
leap_year = [1375, 1379 ,1383, 1387 ,1391 ,1395]
year = int(date_list[0])
month = int (date_list[1])
if year in leap_year:
is_leap = True
else:
is_leap = False
if month >= 1 and month <= 6:
number_of_days = "31"
elif month >= 7 and month <= 11:
number_of_days = "30"
else:
if is_leap:
number_of_days = "30"
else:
number_of_days = "29"
print ("Year: " + date_list[0] + " Month: "+ date_list[1] + " Days: "
+ number_of_days)
Check the code file in here
Hope it helps. Cheers!
[Edit 2]
You wrote a helper function Ok that finds out what month it is. Instead writing your list manually, just declare the number of days in there. When you want to or it's time to fill up the drop down list of days, run and fill up the list with equivalent number of days. Do I make sense?!