2010-12-14 282 views
22

tkinterアプリでユーザーが日付を選択できる標準的な方法はありますか?tkinterで日付ピッカーを作成するにはどうすればよいですか?

+0

trophinterは非常に最小限です。あなた自身でビルドせずに何かを欲しがっているのであれば、あなたの最善の策は、バッテリーを含む大きなGUIツールキット(私はQtをお勧めします)の一つです。 – delnan

+9

+1完全に合理的な質問。これは、ツールキット内で標準化されるべきUIの種類です。驚いたtkはそれを提供しません。 – Anne

答えて

14

いいえ、Tkには日付ピッカーウィジェットは含まれていません。そこには試みることができるPythonのカレンダーウィジェットのカップルは、次のとおりです。No

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

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

+0

ありがとう、私はそれを見てみましょう。私の質問は、ウィジェットがないので、ほとんどのtk/tkinter開発者は何をしましたか?ちょうど3スピンボックスを持っている?月の変動はどうですか?うるう年はどうですか? – MKaras

+2

ex-tcl/tkデベロッパーとして話していると、私は自分が必要と思った回数だけ自分自身を圧倒しました。 tcl(とPython)はあなたにデータを与えることができる日付ルーチンを持っているので、作成はかなり簡単です。あなたがする必要があるのは、ボタンのグリッドまたは同様のものを作成することだけです。 –

+1

うん、ここと同じ。 Tcl/Tk(とTkinter)は、新しいウィジェットを作成することを非常に簡単にします。 Widget Construction Kit(上記のWCKカレンダーで使用されています)をチェックしてください。 –

4

ができますが、フォーマットされた文字列からdatetime型要素として、ユーザーからそれを得ることができます。..

例:

import datetime 

userdatestring = '2013-05-10' 
thedate = datetime.datetime.strptime(userdatestring, '%Y-%m-%d') 

チェックアウトhttp://docs.python.org/2/library/datetime.html#strftime-strptime-behaviorそれは便利ですが、日付を取得する最もユーザーフレンドリーな方法ではありません。

5

私の知る限りではありません。将来的にこれを実行したい人のために:

私はCalendarDialogを作るために(this SOポストからと修正)tkSimpleDialogttkcalendar.pyを使用しました。 3つのファイルは私のgithubにあります。以下は

CalendarDialog.pyのコードです:

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、あなたがリンクしているpythonソースファイルは実際にはそれらの変更を持っていません - 実際のTkinterアプリケーションでうまくいくように修正する必要があることがわかるまで、つまずきブロックに走りました:P –

+0

そうです私はgithubのパッチ版にもリンクしていました。 – Moshe

+0

Ahh gotcha、ありがとう。私はちょうど私がそれらがすべてgithubではなかったのを見るために十分に近いそれらを読まなかったのでリンクがすべて同じ場所に行ったと仮定した:P –

0

これは、我々はTkinterではPythonの日付ピッカーをコーディングする方法です。

# !/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() 
関連する問題