2010-12-14 24 views
22

Kullanıcıların bir tarih seçmesine izin veren herhangi bir standart uygulama var mı?Tiner'de tarih seçiciyi nasıl oluştururum?

+0

Bozulma, kireç çözücü olarak çok azdır. Kendiniz inşa etmeden bir şey fantezi istiyorsanız, en iyi bahsiniz daha büyük, piller dahil GUI araç takımlarından biridir (Qt'yi öneririm). – delnan

+9

+1 tamamen makul bir soru. Bu, bir araç kitinde standartlaştırılması gereken kullanıcı arayüzü şeyidir. Sürpriz tk teklif etmiyor. – Anne

cevap

14

Hayır, Tk bir tarih seçici widget'ını içermez. Orada Python takvim widget birkaç deneyebilirsin şunlardır: Hayır

http://svn.python.org/projects/sandbox/trunk/ttk-gsoc/samples/ttkcalendar.py

http://effbot.org/zone/wcklib-calendar.htm

+0

Teşekkürler bir göz atacağım. Benim sorum - bir widget'ları olmadığı için - çoğu tk/tkinter geliştiricisi ne yaptı? Sadece üç spin kutusu var mı? Değişen aylara ne dersin? Kaç sene? Bir ex-tcl/tk geliştiricisi olarak konuşan – MKaras

+2

, sadece ihtiyacım olan birkaç kez kendi kendime yuvarlandı. Tcl (ve python) verileri size besleyebilecek tarih rutinlerine sahip olduklarından, yaratmaları oldukça önemsizdir. Tek yapmanız gereken, bir düğme ızgarası veya benzer bir şey yaratmak. –

+1

Yup, burada aynı; Tcl/Tk (ve Tkinter) yeni widget'lar yaratmayı çok kolaylaştırıyor. Eğer bazı yapıları istiyorsanız Widget Construction Kit'e (yukarıda bağlantılı WCK takvimi tarafından kullanılır) göz atın. –

5

Bulabildiğim kadarıyla değil. Gelecekte bu yapmak isteyen herkes için:

Bir CalendarDialog yapmak için (this SO yayının ait olan modifikasyonları) tkSimpleDialog ve ttkcalendar.py kullandı. Üç dosya benim github'umda kullanılabilir. Bu, Tkinter bir piton datepicker kodu nasıl

import Tkinter 
import ttkcalendar 

import tkSimpleDialog 

class CalendarDialog(tkSimpleDialog.Dialog): 
    """Dialog box that displays a calendar and returns the selected date""" 
    def body(self, master): 
     self.calendar = ttkcalendar.Calendar(master) 
     self.calendar.pack() 

    def apply(self): 
     self.result = self.calendar.selection 

# Demo code: 
def main(): 
    root = Tkinter.Tk() 
    root.wm_title("CalendarDialog Demo") 

    def onclick(): 
     cd = CalendarDialog(root) 
     print cd.result 

    button = Tkinter.Button(root, text="Click me to see a calendar!", command=onclick) 
    button.pack() 
    root.update() 

    root.mainloop() 


if __name__ == "__main__": 
    main() 
+2

Heh, bağladığınız python kaynak dosyası aslında bu değişiklikler var mı - gerçek bir Tkinter uygulaması ile güzel oynamak için değiştirilmek zorunda olduğunu fark edene kadar tökezleyen bir blok koştu: P –

+0

Evet, işte bu yüzden Github'umdaki yamalı sürümlere de bağlandım. – Moshe

+0

Ahh gotcha, teşekkürler. Sadece bağlantıların hepsinin aynı yere gittiğini varsaydım çünkü hepsini github olmadıklarını görecek kadar yakın okumamıştım: P –

0

:

Aşağıda benim CalendarDialog.py yılında kodudur.

# !/usr/bin/env python 
# -*- coding: utf-8 -*- 
# Author: Rambarun Komaljeet 
# License: Freeware 
# --------------------------------------------------------------------------- 
import calendar 
import tkinter as tk 
import time 
from tkinter import ttk 


class MyDatePicker(tk.Toplevel): 
    """ 
    Description: 
     A tkinter GUI date picker. 
    """ 

    def __init__(self, widget=None, format_str=None): 
     """ 
     :param widget: widget of parent instance. 

     :param format_str: print format in which to display date. 
     :type format_str: string 

     Example:: 
      a = MyDatePicker(self, widget=self.parent widget, 
          format_str='%02d-%s-%s') 
     """ 

     super().__init__() 
     self.widget = widget 
     self.str_format = format_str 

     self.title("Date Picker") 
     self.resizable(0, 0) 
     self.geometry("+630+390") 

     self.init_frames() 
     self.init_needed_vars() 
     self.init_month_year_labels() 
     self.init_buttons() 
     self.space_between_widgets() 
     self.fill_days() 
     self.make_calendar() 

    def init_frames(self): 
     self.frame1 = tk.Frame(self) 
     self.frame1.pack() 

     self.frame_days = tk.Frame(self) 
     self.frame_days.pack() 

    def init_needed_vars(self): 
     self.month_names = tuple(calendar.month_name) 
     self.day_names = tuple(calendar.day_abbr) 
     self.year = time.strftime("%Y") 
     self.month = time.strftime("%B") 

    def init_month_year_labels(self): 
     self.year_str_var = tk.StringVar() 
     self.month_str_var = tk.StringVar() 

     self.year_str_var.set(self.year) 
     self.year_lbl = tk.Label(self.frame1, textvariable=self.year_str_var, 
           width=3) 
     self.year_lbl.grid(row=0, column=5) 

     self.month_str_var.set(self.month) 
     self.month_lbl = tk.Label(self.frame1, textvariable=self.month_str_var, 
            width=8) 
     self.month_lbl.grid(row=0, column=1) 

    def init_buttons(self): 
     self.left_yr = ttk.Button(self.frame1, text="←", width=5, 
            command=self.prev_year) 
     self.left_yr.grid(row=0, column=4) 

     self.right_yr = ttk.Button(self.frame1, text="→", width=5, 
            command=self.next_year) 
     self.right_yr.grid(row=0, column=6) 

     self.left_mon = ttk.Button(self.frame1, text="←", width=5, 
            command=self.prev_month) 
     self.left_mon.grid(row=0, column=0) 

     self.right_mon = ttk.Button(self.frame1, text="→", width=5, 
            command=self.next_month) 
     self.right_mon.grid(row=0, column=2) 

    def space_between_widgets(self): 
     self.frame1.grid_columnconfigure(3, minsize=40) 

    def prev_year(self): 
     self.prev_yr = int(self.year_str_var.get()) - 1 
     self.year_str_var.set(self.prev_yr) 

     self.make_calendar() 

    def next_year(self): 
     self.next_yr = int(self.year_str_var.get()) + 1 
     self.year_str_var.set(self.next_yr) 

     self.make_calendar() 

    def prev_month(self): 
     index_current_month = self.month_names.index(self.month_str_var.get()) 
     index_prev_month = index_current_month - 1 

     # index 0 is empty string, use index 12 instead, 
     # which is index of December. 
     if index_prev_month == 0: 
      self.month_str_var.set(self.month_names[12]) 
     else: 
      self.month_str_var.set(self.month_names[index_current_month - 1]) 

     self.make_calendar() 

    def next_month(self): 
     index_current_month = self.month_names.index(self.month_str_var.get()) 

     try: 
      self.month_str_var.set(self.month_names[index_current_month + 1]) 
     except IndexError: 
      # index 13 does not exist, use index 1 instead, which is January. 
      self.month_str_var.set(self.month_names[1]) 

     self.make_calendar() 

    def fill_days(self): 
     col = 0 
     # Creates days label 
     for day in self.day_names: 
      self.lbl_day = tk.Label(self.frame_days, text=day) 
      self.lbl_day.grid(row=0, column=col) 
      col += 1 

    def make_calendar(self): 
     # Delete date buttons if already present. 
     # Each button must have its own instance attribute for this to work. 
     try: 
      for dates in self.m_cal: 
       for date in dates: 
        if date == 0: 
         continue 

        self.delete_buttons(date) 

     except AttributeError: 
      pass 

     year = int(self.year_str_var.get()) 
     month = self.month_names.index(self.month_str_var.get()) 
     self.m_cal = calendar.monthcalendar(year, month) 

     # build dates buttons. 
     for dates in self.m_cal: 
      row = self.m_cal.index(dates) + 1 
      for date in dates: 
       col = dates.index(date) 

       if date == 0: 
        continue 

       self.make_button(str(date), str(row), str(col)) 

    def make_button(self, date, row, column): 
     """ 
     Description: 
      Build a date button. 

     :param date: date. 
     :type date: string 

     :param row: row number. 
     :type row: string 

     :param column: column number. 
     :type column: string 
     """ 
     exec(
      "self.btn_" + date + " = ttk.Button(self.frame_days, text=" + date 
      + ", width=5)\n" 
      "self.btn_" + date + ".grid(row=" + row + " , column=" + column 
      + ")\n" 
      "self.btn_" + date + ".bind(\"<Button-1>\", self.get_date)" 
     ) 

    def delete_buttons(self, date): 
     """ 
     Description: 
      Delete a date button. 

     :param date: date. 
     :type: string 
     """ 
     exec(
      "self.btn_" + str(date) + ".destroy()" 
     ) 

    def get_date(self, clicked=None): 
     """ 
     Description: 
      Get the date from the calendar on button click. 

     :param clicked: button clicked event. 
     :type clicked: tkinter event 
     """ 

     clicked_button = clicked.widget 
     year = self.year_str_var.get() 
     month = self.month_str_var.get() 
     date = clicked_button['text'] 

     self.full_date = self.str_format % (date, month, year) 
     print(self.full_date) 
     # Replace with parent 'widget' of your choice. 
     try: 
      self.widget.delete(0, tk.END) 
      self.widget.insert(0, self.full_date) 
     except AttributeError: 
      pass 


if __name__ == '__main__': 
    def application(): 
     MyDatePicker(format_str='%02d-%s-%s') 

    root = tk.Tk() 
    btn = tk.Button(root, text="test", command=application) 
    btn.pack() 
    root.mainloop() 
İlgili konular