2016-05-11 39 views
6

Używam w mojej aplikacji this ttk calendar.Jak programowo ustawić kalendarz ttk?

Chcę ustawić kalendarz przy użyciu instancji datetime.date, aby po wyświetleniu kalendarza podświetlona była określona data.

Pomyślałem, że mogę przejść przez metodę _show_selection z instrukcją text i bbox args. Aby przetestować ten pomysł, umieściłem tę linię na końcu metody __init__:

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

Miałam nadzieję, że to podkreślić 16. tego miesiąca (maj), ale tak się nie stało.

Mam argumenty z uruchamiania print text, bbox w metodzie _pressed.

Jeśli ktoś może rzucić trochę światła na ten temat, byłbym bardzo wdzięczny.

+1

Jestem również zaintrygowany. Umieszczam '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'))) 'na końcu _show_selection i wszystko jest takie samo. Dodałem także 'self._selection = ('16', 'I004', '# 2')' przed dodanym wywołaniem w '__init__', aby dopasować linię do' _pressed'. Dodałem nawet 'self._canvas.place_forget(), szukając w _setup_selection. –

+1

Próbuję również 'self._canvas.event_generate ('', x = 50, y = 73) self._calendar.event_generate ('', x = 50, y = 73) '. Umieszczam 'print (evt.x, evt.y, evt.widget)' u góry '_pressed', aby sprawdzić, czy jest on wywoływany podczas uruchamiania z zasadniczo tym samym wydarzeniem. Nadal nie działa. –

Odpowiedz

0

W __setup_selection() występuje powiązanie ze zdarzeniem Configure. Prawdopodobnie istnieje możliwość usunięcia "płótna wyboru" po zmianie rozmiaru kalendarza . Jednak zdarzenie Configure jest również uruchamiane, gdy kalendarz jest najpierw odwzorowany na ekranie, a więc wstępnie wybrana data zniknie, zanim pojawi się jego numer.

set_day (poniżej) pozwala programowo wybrać dzień. Odsuwa problem pierwszego zdarzenia Configure od ponownego planowania, jeśli widget nie jest jeszcze widoczny.

zmiany Kalendarz:

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() 
0

W przeważającej części @Oblivion jest poprawny, jednak chcę, aby móc korzystać z Datetime.date obiekt i być w stanie przechodzić przez miesiące i lata w razie potrzeby. Kiedy zmieniłem metodę set_day, wszystko działało idealnie.

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"