Tkinter 中 DateEntry 的行为 Window
Behaviour of DateEntry in Tkinter Window
我有一个按钮可以将 DateEntry 小部件添加到可滚动框架。不幸的是,框架位于 window 的底部,因此添加几行后,下拉日历隐藏在任务栏后面。有什么方法可以更改它,使日历在字段上方而不是下方打开?
这是一些测试代码
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.
我有一个按钮可以将 DateEntry 小部件添加到可滚动框架。不幸的是,框架位于 window 的底部,因此添加几行后,下拉日历隐藏在任务栏后面。有什么方法可以更改它,使日历在字段上方而不是下方打开?
这是一些测试代码
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.