【问题标题】:How to set ttk calendar programmatically如何以编程方式设置 ttk 日历
【发布时间】:2016-05-11 15:36:25
【问题描述】:

我在我的应用程序中使用this ttk calendar

我想要做的是使用datetime.date 实例设置日历,以便在日历出现时突出显示指定的日期。

我想我可以通过手动 textbbox args 的 _show_selection 方法。为了验证这个想法,我将这一行放在__init__ 方法的末尾:

self._show_selection('%02d'%16,(42,61,41,20))

我希望它会突出显示本月 16 日(5 月),但它没有。

我在 _pressed 方法中运行 print text, bbox 得到了参数。

如果有人能对此有所了解,我将不胜感激。

【问题讨论】:

  • 我也很疑惑。我把` print((text, textw, bbox, canvas['background'], x, y, canvas['width'], canvas['height'], canvas.text), '\n', (self. _calendar, canvas.coords(canvas.text), canvas.itemcget(canvas.text, 'text'))) ` 在 _show_selection 的末尾,一切都是一样的。我还在__init__ 中添加的调用之前添加了`self._selection = ('16', 'I004', '#2')`,以匹配_pressed 中的行。我什至从 _setup_selection 中添加了 `self._canvas.place_forget()。
  • 我也尝试了`self._canvas.event_generate('', x=50, y=73) self._calendar.event_generate('', x= 50, y=73) . I put print(evt.x, evt.y, evt.widget)` 在_pressed 的顶部,以验证它是否在启动时使用基本相同的事件调用。还是不行。

标签: python tkinter ttk


【解决方案1】:

在大多数情况下@Oblivion 是正确的,但是我希望能够使用Datetime.date 对象并能够在需要时遍历月份和年份。一旦我更改了下面的 set_day 方法,一切都运行良好。

def set_day(self, dt_object):
    day = dt_object.day
    w = self._calendar

    if not w.winfo_viewable():
        w.after(200, self.set_day, dt_object)
        return
    while dt_object.year < self._date.year:
        self._prev_month()
    while dt_object.year > self._date.year:
        self._next_month()
    while dt_object.month < self._date.month:
        self._prev_month()
    while dt_object.month > self._date.month:
        self._next_month()
    text = '%02d' % day
    column = None
    for iid in self._items:
        rowvals = w.item(iid, 'values')
        try:
            column = rowvals.index(text)
        except ValueError as err:
            pass
        else:
            item = iid
            bbox = w.bbox(iid, column)
            break

    if column is not None:
        self._selection = (text, item, column)
        self._show_selection(text, bbox)
    else:
        print "Column is None" 

【讨论】:

    【解决方案2】:

    在 __setup_selection() 中有一个配置事件的绑定。 据推测,它是在日历时删除“选择画布”的 被调整大小。但是,Configure 事件也会在日历被触发时触发 首先映射到屏幕,因此您预先选择的日期会在您之前消失 去看看吧。

    set_day(下)允许您以编程方式选择一天。它通过重新调度自身来回避第一个配置事件的问题,如果小部件 还不可见。

    对日历的更改:

    def __setup_selection(self, sel_bg, sel_fg):
        self._font = font.Font()
        self._canvas = canvas = tkinter.Canvas(self._calendar,
            background=sel_bg, borderwidth=0, highlightthickness=0)
        canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w')
    
        canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget())
        #self._calendar.bind('<Configure>', lambda evt: canvas.place_forget())
        self._calendar.bind('<Configure>', self.on_configure)        
        self._calendar.bind('<ButtonPress-1>', self._pressed)
    
    def on_configure(self, event):
        self._canvas.place_forget()
        if self._selection is not None:
            text, iid, column = self._selection
            bbox = self._calendar.bbox(iid, column)
            self._show_selection(text, bbox)
    
    def _prev_month(self):
        """Updated calendar to show the previous month."""
        self._canvas.place_forget()
        self._selection = None #
        self._date = self._date - self.timedelta(days=1)
        self._date = self.datetime(self._date.year, self._date.month, 1)
        self._build_calendar() # reconstuct calendar
    
    def _next_month(self):
        """Update calendar to show the next month."""
        self._canvas.place_forget()
        self._selection = None #
        year, month = self._date.year, self._date.month
        self._date = self._date + self.timedelta(
            days=calendar.monthrange(year, month)[1] + 1)
        self._date = self.datetime(self._date.year, self._date.month, 1)
        self._build_calendar() # reconstruct calendar
    
    def set_day(self, day):
        w = self._calendar
        if not w.winfo_viewable():
            w.after(200, self.set_day, day)
            return
    
        text = '%02d' % day
        column = None
        for iid in self._items:
            rowvals = w.item(iid, 'values')
            try:
                column = rowvals.index(text)
            except ValueError as err:
                pass
            else:
                item = iid
                bbox = w.bbox(iid, column)
                break
    
        if column is not None:
            self._selection = (text, item, column)
            self._show_selection(text, bbox) 
    
    #test
    def test():
        import sys
        root = tkinter.Tk()
        root.title('Ttk Calendar')
        ttkcal = Calendar(firstweekday=calendar.SUNDAY)
        ttkcal.pack(expand=1, fill='both')
    
        if 'win' not in sys.platform:
            style = ttk.Style()
            style.theme_use('clam')
    
        ttkcal.set_day(16) #
        root.mainloop()
    

    【讨论】:

      猜你喜欢
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      • 2011-12-24
      相关资源
      最近更新 更多