Datepicker-Probleme

Fragen zu Tkinter.
Antworten
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

Aloa
ich beschäftige mich schon ne ganze weile mit 2 problemen:
wie bekomm ich es hin, dass
1. mit klick auf button Datum_2 das Datum_1_Toplevel geschlossen wird
und
2. sobald man sich ein datum ausgewählt hat, das toplevel, halt durch klick, wieder geschlossen wird.
beides bekomm ich net hin.
erbitte hilfe :)

Code: Alles auswählen

import Tkinter
import ttk
import calendar
import tkFont

la_fenster = Tkinter.Tk()
la_fenster.geometry('600x400+755+230')
lvar = Tkinter.StringVar()
l_infLo1 = Tkinter.Label(la_fenster,textvariable=lvar, font = "Helvetica 11 bold")
l_infLo1.place(relx=.2, rely=.45, anchor="w")


def get_calendar(locale, fwday):

    if locale is None:
        return calendar.TextCalendar(fwday)
    else:
        return calendar.LocaleTextCalendar(fwday, locale)

class Calendar(ttk.Frame):

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

    def __init__(self, master=None, **kw):

        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
        ttk.Frame.__init__(self, master, **kw)
        self._cal = get_calendar(locale, fwday)
        self.__setup_styles()
        self.__place_widgets()
        self.__config_calendar()
        self.__setup_selection(sel_bg, sel_fg)
        self._items = [self._calendar.insert('', 'end', values='')for _ in range(6)]
        self._build_calendar()

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

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

        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')
        self._calendar = ttk.Treeview(self, show='', selectmode='none', height=7)
        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')
        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
        header = self._cal.formatmonthname(year, month, 0)
        self._header['text'] = header.title()
        if len(list) == 0:
            list.extend((month, year))
        else:
            if len(list) == 2:
                list[0]=month
                list[1]=year
            else:
                list[1]=month
                list[2]=year
        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):

        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)

    def _pressed(self, evt):

        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:
            return
        item_values = widget.item(item)['values']
        if not len(item_values):
            return
        text = item_values[int(column[1]) - 1]
        if not text:
            return
        bbox = widget.bbox(item, column)
        if not bbox:
            return
        text = '%02d' % text
        self._selection = (text, item, column)
        self._show_selection(text, bbox)
        if len(list) == 2:
            list.insert(0, text)
        else:
            list[0]=text
        tag = list[0]
        monat = list[1]
        jahr = list[2]
        ausgabe_Datum(tag, monat, jahr)

    def _prev_month(self):

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

    def _next_month(self):

        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()
    @property
    def selection(self):

        if not self._selection:
            return None
        year, month = self._date.year, self._date.month
        return self.datetime(year, month, int(self._selection[0]))

def auswahl_Datum_1():

    Datum_1_Toplevel = Tkinter.Toplevel(la_fenster)
    Datum_1_Toplevel.title('Datum')
    Datum_1_Toplevel.geometry('250x200+500+130')
    ttkcal = Calendar(Datum_1_Toplevel,firstweekday=calendar.MONDAY)
    ttkcal.pack(expand=2, fill='both')

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

list = []
def ausgabe_Datum(tag, monat, jahr):
    tag = '%02s' % tag
    monat = '%02d' % monat
    datum = (str(tag)+"."+str(monat)+"."+str(jahr))
    lvar.set(datum)

b_ew1 = Tkinter.Button(la_fenster, text=('Datum_1'), width=15, relief="raised", borderwidth=3, font=('Arial', 9, 'bold'), fg='#000000000', justify='center', command=auswahl_Datum_1)
b_ew1.place(relx=.17, rely=.53, anchor="w")

#-----------------------------------------------------------------------------------------------------------------------------------------------------

def auswahl_Datum_2(Datum_1_Toplevel):
    Datum_1_Toplevel.destroy()


b_ew2 = Tkinter.Button(la_fenster, text=('Datum_2'), width=15, relief="raised", borderwidth=3, font=('Arial', 9, 'bold'), fg='#000000000', justify='center', command=lambda:auswahl_Datum_2(Datum_1_Toplevel))
b_ew2.place(relx=.5, rely=.53, anchor="w")

la_fenster.mainloop()
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@DMD-OL: in Deinem Skript sind einige Unschönheiten: außer Definitionen gehört nichts auf der obersten Ebene, dann hätte Dir auffallen müssen, dass Du globale Variablen benutzt. list für eine Variable ist zudem ein schlechter Name, weil er nicht sagt, was denn das für eine Liste ist und zweitens die Klasse list von Python überdeckt. Warum definierst Du die Klassen datetime und timedelta nochmal als Klassenvariablen? Die gehören da nicht hin. Warum benutzt Du **kw so seltsam, statt direkt die Argumente mit Defaultwerten zu versehen? Normalerweise verwendet man für solche Dialoge modale Fenster. Dann muß der Nutzer dieses erst wieder schließen, bevor er ein anderes aufmachen kann.
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

modale fenster muß man vorher eben erst schließen. ich möchte mir diesen "umstand" sparen.
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

ok. dann mit modalem fenster
Antworten