У меня возникла проблема с Tkinter, и я не могу разобраться с часами поиска в Google. Я нашел большой кусок кода, который создает календарь в Tkinter и возвращает дату в определенном формате. Когда я использую другой класс для доступа к этим данным, он возвращает либо ошибки, место хранения текста, либо просто не то, что мне нужно вообще.
Вот базовый код, который создает приложение календаря tkinter (кредит Rambarun Komaljeet)
import calendar
import tkinter as tk
import time
from tkinter import ttk
import sys
class MyDatePicker(tk.Toplevel):
"""
Description:
A tkinter GUI date picker.
"""
def __init__(self, widget=None, format_str=None):
"""
:param widget: widget of parent instance.
:param format_str: print format in which to display date.
:type format_str: string
Example::
a = MyDatePicker(self, widget=self.parent widget,
format_str='%02d-%s-%s')
"""
super().__init__()
self.widget = widget
self.str_format = format_str
self.title("Date Picker")
self.resizable(0, 0)
self.geometry("+630+390")
self.init_frames()
self.init_needed_vars()
self.init_month_year_labels()
self.init_buttons()
self.space_between_widgets()
self.fill_days()
self.make_calendar()
def init_frames(self):
self.frame1 = tk.Frame(self)
self.frame1.pack()
self.frame_days = tk.Frame(self)
self.frame_days.pack()
def init_needed_vars(self):
self.month_names = tuple(calendar.month_name)
self.day_names = tuple(calendar.day_abbr)
self.year = time.strftime("%Y")
self.month = time.strftime("%B")
def init_month_year_labels(self):
self.year_str_var = tk.StringVar()
self.month_str_var = tk.StringVar()
self.year_str_var.set(self.year)
self.year_lbl = tk.Label(self.frame1, textvariable=self.year_str_var,
width=3)
self.year_lbl.grid(row=0, column=5)
self.month_str_var.set(self.month)
self.month_lbl = tk.Label(self.frame1, textvariable=self.month_str_var,
width=8)
self.month_lbl.grid(row=0, column=1)
def init_buttons(self):
self.left_yr = ttk.Button(self.frame1, text="←", width=5,
command=self.prev_year)
self.left_yr.grid(row=0, column=4)
self.right_yr = ttk.Button(self.frame1, text="→", width=5,
command=self.next_year)
self.right_yr.grid(row=0, column=6)
self.left_mon = ttk.Button(self.frame1, text="←", width=5,
command=self.prev_month)
self.left_mon.grid(row=0, column=0)
self.right_mon = ttk.Button(self.frame1, text="→", width=5,
command=self.next_month)
self.right_mon.grid(row=0, column=2)
def space_between_widgets(self):
self.frame1.grid_columnconfigure(3, minsize=40)
def prev_year(self):
self.prev_yr = int(self.year_str_var.get()) - 1
self.year_str_var.set(self.prev_yr)
self.make_calendar()
def next_year(self):
self.next_yr = int(self.year_str_var.get()) + 1
self.year_str_var.set(self.next_yr)
self.make_calendar()
def prev_month(self):
index_current_month = self.month_names.index(self.month_str_var.get())
index_prev_month = index_current_month - 1
# index 0 is empty string, use index 12 instead,
# which is index of December.
if index_prev_month == 0:
self.month_str_var.set(self.month_names[12])
else:
self.month_str_var.set(self.month_names[index_current_month - 1])
self.make_calendar()
def next_month(self):
index_current_month = self.month_names.index(self.month_str_var.get())
try:
self.month_str_var.set(self.month_names[index_current_month + 1])
except IndexError:
# index 13 does not exist, use index 1 instead, which is January.
self.month_str_var.set(self.month_names[1])
self.make_calendar()
def fill_days(self):
col = 0
# Creates days label
for day in self.day_names:
self.lbl_day = tk.Label(self.frame_days, text=day)
self.lbl_day.grid(row=0, column=col)
col += 1
def make_calendar(self):
# Delete date buttons if already present.
# Each button must have its own instance attribute for this to work.
try:
for dates in self.m_cal:
for date in dates:
if date == 0:
continue
self.delete_buttons(date)
except AttributeError:
pass
year = int(self.year_str_var.get())
month = self.month_names.index(self.month_str_var.get())
self.m_cal = calendar.monthcalendar(year, month)
# build dates buttons.
for dates in self.m_cal:
row = self.m_cal.index(dates) + 1
for date in dates:
col = dates.index(date)
if date == 0:
continue
self.make_button(str(date), str(row), str(col))
def make_button(self, date, row, column):
"""
Description:
Build a date button.
:param date: date.
:type date: string
:param row: row number.
:type row: string
:param column: column number.
:type column: string
"""
exec(
"self.btn_" + date + " = ttk.Button(self.frame_days, text=" + date
+ ", width=5)\n"
"self.btn_" + date + ".grid(row=" + row + " , column=" + column
+ ")\n"
"self.btn_" + date + ".bind(\"<Button-1>\", self.get_date)"
)
def delete_buttons(self, date):
"""
Description:
Delete a date button.
:param date: date.
:type: string
"""
exec(
"self.btn_" + str(date) + ".destroy()"
)
def get_date(self, clicked=None):
"""
Description:
Get the date from the calendar on button click.
:param clicked: button clicked event.
:type clicked: tkinter event
"""
clicked_button = clicked.widget
year = self.year_str_var.get()
month = self.month_str_var.get()
date = clicked_button['text']
self.full_date = self.str_format % (date, month, year)
print(self.full_date)
sys.stderr.write(self.full_date)
# Replace with parent 'widget' of your choice.
try:
self.widget.delete(0, tk.END)
self.widget.insert(0, self.full_date)
except AttributeError:
pass
if __name__ == '__main__':
def application():
MyDatePicker(format_str='%02d-%s-%s')
root = tk.Tk()
btn = tk.Button(root, text="test", command=application)
btn.pack()
root.mainloop()
Я пытался вернуть эти данные в первое окно tkinter. что я открываю, чтобы я мог использовать его для функции поиска. Похоже, что мне нужно именно то, что мне нужно, в разделе get_date()
, где он извлекает информацию и печатает дату в консоли как переменную self.full_date
.
. Как мне заставить это работать в другомкласс? Это то, что у меня есть до сих пор (MyDatePicker
тоже есть, но я не хотел загромождать слишком много места)
class Main_Window(tk.Frame,MyDatePicker):
def __init__(self, root):
self.root=root
#self.MyDatePicker=MyDatePicker()
tk.Frame.__init__(self, root)
self.root.geometry('300x300')
b1 = tk.Button(self.root, text="Add another window", command =lambda: self.newWindow(1))
b1.grid(column=1, row=1)
self.total = 0
self.count=0
self.total_label_text = tk.IntVar()
self.total_label_text.set(self.total)
#self.total_label_text
self.lbl1=tk.Label(self.root,textvariable=self.total_label_text)
self.lbl1.grid(column=1,row=2)
b2 = tk.Button(self.root, text="Add another window", command =lambda: self.newWindow(2))
b2.grid(column=2, row=1)
self.total2 = 0
self.count2=0
self.total_label_text2 = tk.IntVar()
self.total_label_text2.set(self.total2)
#self.total_label_text
self.lbl2=tk.Label(self.root,textvariable=self.total_label_text2)
self.lbl2.grid(column=2,row=2)
b1 = tk.Button(self.root, text="Add another window", command =lambda: self.press_calendar(format_str='%02d-%s-%s',Class=MyDatePicker))
b1.grid(column=1, row=1)
def press_calendar(self,format_str,Class):
self.MyDatePicker1=Class(format_str)
self.MyDatePicker1.get_date(self)
def newWindow(self,m):
if m ==1:
self.count += 1
if m ==2:
self.count2+=1
self.window = tk.Toplevel(self)
but1=tk.Button(self.window,text="Add One",command =lambda:self.close(m))
but1.grid(row=2,column=1)
def close(self,m):
if m==1:
self.total_label_text.set(self.count)
if m==2:
self.total_label_text2.set(self.count2)
self.window.destroy()
if __name__ == "__main__":
root = tk.Tk()
Main_Window(root)
root.mainloop()
Я пытаюсь сделать это в части press_calendar
моего кода, где я вызываю другой класс, запускаю его и возвращаю дату.
Все, что я получаю, - это местоположение переменной, или мне нужно инициализировать все переменные из MyDatePicker
вMain_Window
class.
Что я могу сделать лучше, чтобы на самом деле получить дату и использовать ее в моем главном окне?
Спасибо за помощь!