datepicker hilfe

Fragen zu Tkinter.
Antworten
DMD
User
Beiträge: 123
Registriert: Sonntag 17. Mai 2015, 03:34

hallo, ich habe ttkcalendar kopiert und
ein neues tkinter fenster eingefügt.
jetzt verzweifel ich langsam daran, es so hinzubekomme, dass
das kleinere fenster 'root' den kalender anzeigen soll und
das grosse unverändert bleibt.

Code: Alles auswählen

# -*- coding: cp1252 -*-

import datetime
from time import *
from Tkinter import *
import sys
import calendar
import Tkinter
import tkFont
import ttk

def datePrinter():
        ufenster = Tkinter.Tk()
        ufenster.title('Testdatum')
        ufenster.geometry('600x700+485+100')

        def get_calendar(locale, fwday):
            # instantiate proper calendar class
            if locale is None:
                return calendar.TextCalendar(fwday)
            else:
                return calendar.LocaleTextCalendar(fwday, locale)

        class Calendar(ttk.Frame):
            # XXX ToDo: cget and configure

            datetime = calendar.datetime.datetime
            timedelta = calendar.datetime.timedelta

            def __init__(self, master=None, **kw):
                """
                WIDGET-SPECIFIC OPTIONS

                    locale, firstweekday, year, month, selectbackground,
                    selectforeground
                """
                # remove custom options from kw before initializating ttk.Frame
                fwday = kw.pop('firstweekday', calendar.MONDAY)
                year = kw.pop('year', self.datetime.now().year)
                month = kw.pop('month', self.datetime.now().month)
                locale = kw.pop('locale', None)
                sel_bg = kw.pop('selectbackground', '#ecffc4')
                sel_fg = kw.pop('selectforeground', '#05640e')

                self._date = self.datetime(year, month, 1)
                self._selection = None # no date selected

                ttk.Frame.__init__(self, master, **kw)

                self._cal = get_calendar(locale, fwday)

                self.__setup_styles()       # creates custom styles
                self.__place_widgets()      # pack/grid used widgets
                self.__config_calendar()    # adjust calendar columns and setup tags
                # configure a canvas, and proper bindings, for selecting dates
                self.__setup_selection(sel_bg, sel_fg)

                # store items ids, used for insertion later
                self._items = [self._calendar.insert('', 'end', values='')
                                    for _ in range(6)]
                # insert dates in the currently empty calendar
                self._build_calendar()

                # set the minimal size for the widget
                self._calendar.bind('<Map>', self.__minsize)

            def __setitem__(self, item, value):
                if item in ('year', 'month'):
                    raise AttributeError("attribute '%s' is not writeable" % item)
                elif item == 'selectbackground':
                    self._canvas['background'] = value
                elif item == 'selectforeground':
                    self._canvas.itemconfigure(self._canvas.text, item=value)
                else:
                    ttk.Frame.__setitem__(self, item, value)

            def __getitem__(self, item):
                if item in ('year', 'month'):
                    return getattr(self._date, item)
                elif item == 'selectbackground':
                    return self._canvas['background']
                elif item == 'selectforeground':
                    return self._canvas.itemcget(self._canvas.text, 'fill')
                else:
                    r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)})
                    return r[item]

            def __setup_styles(self):
                # custom ttk styles
                style = ttk.Style(self.master)
                arrow_layout = lambda dir: (
                    [('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})]
                )
                style.layout('L.TButton', arrow_layout('left'))
                style.layout('R.TButton', arrow_layout('right'))

            def __place_widgets(self):
                # header frame and its widgets
                hframe = ttk.Frame(self)
                lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month)
                rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month)
                self._header = ttk.Label(hframe, width=15, anchor='center')
                # the calendar
                self._calendar = ttk.Treeview(show='', selectmode='none', height=7)

                # pack the widgets
                hframe.pack(in_=self, side='top', pady=4, anchor='center')
                lbtn.grid(in_=hframe)
                self._header.grid(in_=hframe, column=1, row=0, padx=12)
                rbtn.grid(in_=hframe, column=2, row=0)
                self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')

            def __config_calendar(self):
                cols = self._cal.formatweekheader(3).split()
                self._calendar['columns'] = cols
                self._calendar.tag_configure('header', background='grey90')
                self._calendar.insert('', 'end', values=cols, tag='header')
                # adjust its columns width
                font = tkFont.Font()
                maxwidth = max(font.measure(col) for col in cols)
                for col in cols:
                    self._calendar.column(col, width=maxwidth, minwidth=maxwidth,
                        anchor='e')

            def __setup_selection(self, sel_bg, sel_fg):
                self._font = tkFont.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('<ButtonPress-1>', self._pressed)

            def __minsize(self, evt):
                width, height = self._calendar.master.geometry().split('x')
                height = height[:height.index('+')]
                self._calendar.master.minsize(width, height)

            def _build_calendar(self):
                year, month = self._date.year, self._date.month

                # update header text (Month, YEAR)
                header = self._cal.formatmonthname(year, month, 0)
                self._header['text'] = header.title()

                # update calendar shown dates
                cal = self._cal.monthdayscalendar(year, month)
                for indx, item in enumerate(self._items):
                    week = cal[indx] if indx < len(cal) else []
                    fmt_week = [('%02d' % day) if day else '' for day in week]
                    self._calendar.item(item, values=fmt_week)

            def _show_selection(self, text, bbox):
                """Configure canvas for a new selection."""
                x, y, width, height = bbox

                textw = self._font.measure(text)

                canvas = self._canvas
                canvas.configure(width=width, height=height)
                canvas.coords(canvas.text, width - textw, height / 2 - 1)
                canvas.itemconfigure(canvas.text, text=text)
                canvas.place(in_=self._calendar, x=x, y=y)

            # Callbacks
            def _pressed(self, evt):
                """Clicked somewhere in the calendar."""
                x, y, widget = evt.x, evt.y, evt.widget
                item = widget.identify_row(y)
                column = widget.identify_column(x)

                if not column or not item in self._items:
                    # clicked in the weekdays row or just outside the columns
                    return

                item_values = widget.item(item)['values']
                if not len(item_values): # row is empty for this month
                    return

                text = item_values[int(column[1]) - 1]
                if not text: # date is empty
                    return

                bbox = widget.bbox(item, column)
                if not bbox: # calendar not visible yet
                    return

                # update and then show selection
                text = '%02d' % text
                self._selection = (text, item, column)
                self._show_selection(text, bbox)

            def _prev_month(self):
                """Updated calendar to show the previous month."""
                self._canvas.place_forget()

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

                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

            # Properties
            @property
            def selection(self):
                """Return a datetime representing the current selected date."""
                if not self._selection:
                    return None
                year, month = self._date.year, self._date.month
                return self.datetime(year, month, int(self._selection[0]))

        def test():
            import sys
            root = Tkinter.Toplevel(master=None)
            root.title('Ttk Calendar')
            root = Calendar(firstweekday=calendar.SUNDAY)
            root.pack(expand=1, fill='both')

            if 'win' not in sys.platform:
                style = ttk.Style()
                style.theme_use('clam')

        b_test = Button(ufenster, text = 'Datum', command=test)
        b_test.place(relx=.78, rely=.65, anchor="c")

        def datumZurueck():
            ufenster.destroy()

        b_beenden = Button(ufenster, text = 'Beenden', command=datumZurueck)
        b_beenden.place(relx=.78, rely=.75, anchor="c")

        ufenster.mainloop()


if __name__ == '__main__':
    datePrinter()
hab das vorher schon mal gepostet.
und den tip bekommen, dass i ein toplevel-tkinter fenster erstellen muss und
das als master an den datepicker übergeben muss.
nur wie?
BlackJack

@DMD: Wenn Du nicht verstehst wie man ein Argument bei einem Aufruf übergibt, das beim Aufgerufenen als `master` bekannt ist, dann fehlen Dir einfach Grundlagen die man zum Programmieren braucht. Wenn Dir jetzt jemand diese kleine, triviale Änderung vorkaut, hast Du nichts dabei gelernt. Und auf andere Kritikpunkte bist Du auch nicht eingegangen. Das ist ja jetzt mindestens das dritte Thema von Dir in dem dieser Datepicker behandelt wird.

Gehe einen Schritt zurück und lerne Funktionen, Funktionsaufrufe, wie das mit den Argumenten und Defaultwerten funktioniert, und dann OOP, also Klassen und Methoden und wie das funktioniert. Dann kannst Du auch verstehen was Du da von woanders zusammenkopiert hast und die notwendige Änderung selber vornehmen.
DMD
User
Beiträge: 123
Registriert: Sonntag 17. Mai 2015, 03:34

goil, habs jetzt hinbekommen.
hab diesen link gefunden:
http://stackoverflow.com/questions/1647 ... k-calendar
die beiden hier müssten auch geändert werden:

Code: Alles auswählen

self._calendar = ttk.Treeview(self, show=' ', selectmode='none', height=7)<-- hier fehlten self und show=' '

Code: Alles auswählen

self._calendar.bind('<Map>', self.__minsize) <-- rausnehmen
mit den beiden zusatzänderungen läufts jetzt wie es soll.
soll ich den gesamten code nocheinmal posten?
Antworten