python - Tkinter 窗口中 DateEntry 的行为
问题描述
我有一个将 DateEntry 小部件添加到可滚动框架的按钮。不幸的是,框架位于窗口底部,因此添加几行后,下拉日历隐藏在任务栏后面。有什么办法可以改变它,所以日历在字段上方打开,而不是在下方?
这是一些测试代码
from tkinter import *
from tkinter import ttk
from tkcalendar import Calendar, DateEntry
master = Tk()
global rowNumForShiftReport
rowNumForShiftReport=0
shiftDateWidgetList=[]
def myfunction(event):
canvas2.configure(scrollregion=canvas2.bbox("all"), width=100, height=100)
def addEntry2():
global rowNumForShiftReport
rowNumForShiftReport = rowNumForShiftReport + 1
shiftDateWidgetList.append(DateEntry(frame2, state='readonly', width=15))
shiftDateWidgetList[-1].grid(row=rowNumForShiftReport, column=0)
rowNumForShiftReport+1
master.geometry('400x400')
btn_addField2 = ttk.Button(master, text="Add Entry",command=addEntry2)
btn_addField2.grid(row=0, column=1)
#lotFrame2 = Frame(master)
actualLabelFrame=ttk.LabelFrame(master, text="Shift Report", height=300, width=300)
actualLabelFrame.grid(row=0, column=0)
canvas2 = Canvas(actualLabelFrame,width=160)
frame2 = Frame(canvas2,width=160)
frame2.bind("<Configure>", myfunction)
canvas2.create_window((0, 0), window=frame2, anchor='nw')
scrollBar2 = ttk.Scrollbar(actualLabelFrame, orient="vertical", command=canvas2.yview)
canvas2.configure(yscrollcommand=scrollBar2.set)
scrollBar2.grid(row=0, column=2, sticky=N + S)
canvas2.grid(row=0, column=1)
mainloop()
解决方案
您可以通过扩展DateEntry
和覆盖其drop_down()
功能来实现目标,如下所示:
class MyDateEntry(DateEntry):
def drop_down(self):
"""Display or withdraw the drop-down calendar depending on its current state."""
if self._calendar.winfo_ismapped():
self._top_cal.withdraw()
else:
self._validate_date()
date = self.parse_date(self.get())
x = self.winfo_rootx()
y = self.winfo_rooty() + self.winfo_height()
if self.winfo_toplevel().attributes('-topmost'):
self._top_cal.attributes('-topmost', True)
else:
self._top_cal.attributes('-topmost', False)
# - patch begin: make sure the drop-down calendar is visible
if x+self._top_cal.winfo_width() > self.winfo_screenwidth():
x = self.winfo_screenwidth() - self._top_cal.winfo_width()
if y+self._top_cal.winfo_height() > self.winfo_screenheight()-30:
y = self.winfo_rooty() - self._top_cal.winfo_height()
# - patch end
self._top_cal.geometry('+%i+%i' % (x, y))
self._top_cal.deiconify()
self._calendar.focus_set()
self._calendar.selection_set(date)
然后在您的代码中全部替换DateEntry(...)
为。MyDateEntry(...)
请注意,它基于tkcalendar
v1.6.1。
推荐阅读
- dialogflow-es - 用户标识如何在 Dialogflow Fulfillment Webhook 中工作?
- ehcache-3 - 内存中的 Ehcache 3 大小
- .net - 如果任何行上不存在另一个值,则匹配一个值
- r - 使用 ggplot,使用刻度中的 unit_format 和 Dollar_format 来标记文本
- javascript - Google 地方信息自动填充功能有时不工作
- excel - 我可以将 Excel 的自动填充与自定义模式一起使用吗?
- spring-boot - 使用spring数据jpa在存储过程中读取ref游标作为输出参数返回null
- python - 如何获取字典元组的最大值
- mysql - 加密已经散列的 BCrypt 密码是否过大?
- sql-server - 如何将多列中的多个值合并为一行?