Python中如何复用用户输入而非仅打印?含tkcalendar场景
跨函数传递用户输入字符串的通用方法
作为Python新手,开发收集用户输入构建数据库的程序时,你遇到了tkcalendar选日期后无法把值传到enter_data函数的问题——点击OK只能打印日期,return返回的是None。下面是几种通用的跨函数传递输入值的方法:
方法1:使用全局变量
直接把要传递的变量声明为全局,在获取输入的函数里赋值,另一个函数就能直接读取。
修改后的示例代码:
import tkinter as tk from tkinter import ttk from tkcalendar import Calendar window = tk.Tk() window.title("Route Cards") # 定义全局变量存储选中的日期 selected_date = None def enter_data(): # 直接使用全局变量 if selected_date: print(f"要存入数据库的日期:{selected_date}") # 这里可以把selected_date转成datetime或str存入dataclass def open_calendar(): def on_ok_click(): global selected_date # 给全局变量赋值 selected_date = cal.selection_get() # 关闭日历窗口 top.destroy() top = tk.Toplevel(window) cal = Calendar(top, font="Arial 14", selectmode='day', locale='en_US', cursor="hand1", year=2024, month=1, day=26) cal.pack(fill="both", expand=True) ttk.Button(top, text="ok", command=on_ok_click).pack() # 补充原代码缺失的帧定义 customer_info_frame = ttk.Frame(window) customer_info_frame.pack(padx=10, pady=10) date_btn = ttk.Button(customer_info_frame, text='选择日期', command=open_calendar) date_btn.grid(row=7, column=1) # 测试按钮:触发enter_data查看日期 ttk.Button(customer_info_frame, text='保存数据', command=enter_data).grid(row=8, column=1) window.mainloop()
方法2:用类封装(推荐用于GUI程序)
把窗口、变量、方法都封装到类里,用实例属性存储输入值,类里的方法可以直接访问这个属性,结构更清晰,避免全局变量的混乱。
示例代码:
import tkinter as tk from tkinter import ttk from tkcalendar import Calendar class RouteCardApp: def __init__(self, root): self.root = root self.root.title("Route Cards") self.selected_date = None # 实例属性存储日期 self.create_widgets() def create_widgets(self): self.customer_info_frame = ttk.Frame(self.root) self.customer_info_frame.pack(padx=10, pady=10) self.date_btn = ttk.Button(self.customer_info_frame, text='选择日期', command=self.open_calendar) self.date_btn.grid(row=7, column=1) self.save_btn = ttk.Button(self.customer_info_frame, text='保存数据', command=self.enter_data) self.save_btn.grid(row=8, column=1) def open_calendar(self): def on_ok_click(): self.selected_date = cal.selection_get() top.destroy() top = tk.Toplevel(self.root) cal = Calendar(top, font="Arial 14", selectmode='day', locale='en_US', cursor="hand1", year=2024, month=1, day=26) cal.pack(fill="both", expand=True) ttk.Button(top, text="ok", command=on_ok_click).pack() def enter_data(self): if self.selected_date: print(f"要存入数据库的日期:{self.selected_date}") # 这里处理存入dataclass的逻辑 if __name__ == "__main__": window = tk.Tk() app = RouteCardApp(window) window.mainloop()
方法3:使用回调函数
把需要使用输入值的函数作为参数传给打开日历的函数,当获取到日期后直接调用这个回调函数,把日期传进去。
示例代码:
import tkinter as tk from tkinter import ttk from tkcalendar import Calendar window = tk.Tk() window.title("Route Cards") def enter_data(date): print(f"要存入数据库的日期:{date}") # 这里处理存入dataclass的逻辑 def open_calendar(callback): def on_ok_click(): selected_date = cal.selection_get() callback(selected_date) # 调用回调函数,把日期传进去 top.destroy() top = tk.Toplevel(window) cal = Calendar(top, font="Arial 14", selectmode='day', locale='en_US', cursor="hand1", year=2024, month=1, day=26) cal.pack(fill="both", expand=True) ttk.Button(top, text="ok", command=on_ok_click).pack() customer_info_frame = ttk.Frame(window) customer_info_frame.pack(padx=10, pady=10) # 传递enter_data作为回调函数 date_btn = ttk.Button(customer_info_frame, text='选择日期', command=lambda: open_calendar(enter_data)) date_btn.grid(row=7, column=1) window.mainloop()
内容的提问来源于stack exchange,提问作者ecc3_15
相关产品推荐
相关产品推荐

