Ttk.Treeview – Änderungsreihenfolge kann nicht geändert werden

Ich benutze ttkcalendar.py die in diesem Link gefunden werden können.

Ich habe es für den Einsatz in Python 3.3 angepasst

Im Grunde, was ich versuche zu tun ist, geben Sie diese Kalender-Widget in meine Tkinter-Anwendung, die funktioniert gut und es gibt keine Probleme gibt.

Die Probleme, die ich überwinden möchte, sind:

  1. Wie ändere ich die Schriftgröße des Kalenders (Monat, Tage & Termine) – Abgeschlossen
  2. Wie ändere ich das ausgewählte Datum so, dass es bold . – Abgeschlossen
  3. Wie kann ich die Höhe der Zeilen in der Baumansicht ändern, wie in Prevoius Versuche Schriftgröße kann erhöht werden, aber die Zeilenhöhe erhöht sich nicht mit Schriftgröße. – HELFEN SIE HILFE

Danke im Voraus.

BEARBEITUNG 1:

Finde unter dem Code für das ganze Programm:

 import calendar import tkinter as Tkinter import tkinter.font as tkFont from tkinter import ttk #Imports ttk Module 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): 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', '#EEEEEE') sel_fg = kw.pop('selectforeground', '#B6333B') 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 & Setup Tags #Configure a Canvas & Proper Bindings for Selecting Dates self.__setup_selection(sel_bg, sel_fg) #Store Item ids - Used for Insertion Later On self._items = [self._calendar.insert('', 'end', values='') for _ in range(6)] #Insert Dates in the Currently Empty Calendar self._build_calendar() #Set Minimal Size for 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 & 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', font='Arial 20') #Main Calendar self._calendar = ttk.Treeview(show='', selectmode='none', height='6') #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', font='Arial 20') self._calendar.insert('', 'end', values=cols, tag=('header', 'dayFont')) #Change Font of dayFont TAG self._calendar.tag_configure('dayFont', font='Arial 20') #Adjust Column Widths font = tkFont.Font(size=20) maxwidth = max(font.measure(col) for col in cols) for col in cols: self._calendar.column(col, width=maxwidth, minwidth=maxwidth, anchor='c') def __setup_selection(self, sel_bg, sel_fg): self._font = tkFont.Font() canvas = Tkinter.Canvas(self._calendar, background=sel_bg, borderwidth=0, highlightthickness=0) self._canvas = canvas canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='c') 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 Showing 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, tag='bodyFont') self._calendar.tag_configure('bodyFont', font='Arial 10') def _show_selection(self, text, bbox): #SELECTION FONT """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, font='Arial 15 bold') 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 is not Visible Yet return #Update & 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) #Reconstruct Calendar self._build_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() #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])) #---------------------------------- 

EDIT 2:

Wie kann ich die relief der Treeview ?

3 Solutions collect form web for “Ttk.Treeview – Änderungsreihenfolge kann nicht geändert werden”

Vielleicht wie du, ich erwartete, dass die Strecke nach Bedarf erweitert wurde. Aber ich bestätigte das Problem mit dem unten stehenden Code, mit der Lösung (die beiden Style Linien) weggelassen. Als ich die Lösung hier und die entsprechende Style-Seite nicht finden konnte, habe ich gegoogelt und das gefunden. Scrollen Sie nach unten zu Emilianos Antwort, und einige der folgenden (es gibt auch eine Einrückungsoption).

 import tkinter as tk from tkinter import ttk root = tk.Tk() root.geometry('500x200') style = ttk.Style(root) style.configure('Treeview', rowheight=40) #SOLUTION tree = ttk.Treeview(root) tree.insert('', 0, text='Line 1 of many XXX', tags='T') tree.insert('', 1, text='Line 2 of many XXX', tags='T') tree.insert('', 2, text='Line 3 of many XXX', tags='T') tree.column('#0', stretch=True) tree.tag_configure('T', font='Arial 20') tree.pack(fill='x') 

Das obige, mit der Antwort weggelassen, ist ein Beispiel für minimalen Code, der das Problem zeigt. Dies ist die Art der Sache zu posten!

BEARBEITUNG 1:

Um das Kalender-Widget ordnungsgemäß importierbar und in einer anderen Anwendung verwendbar zu machen, sollte es einen benutzerdefinierten Stil verwenden, also hat sein Stil keine anderen Baumansichten in der App.

 style.configure('Calendar.Treeview', rowheight=40) tree = ttk.Treeview(root, style='Calendar.Treeview') 

EDIT 2:

Ich lerne nur über ttk Styles. Um Ihre Erleichterung Frage zu beantworten, ging ich zu diesem Stil doc und versuchte in Idle's Shell nach dem Ausführen der oben, mit den beiden Änderungen in Edit 1.

 >>> style.layout('Calendar.Treeview') [('Treeview.field', {'sticky': 'nswe', 'children': [('Treeview.padding', {'sticky': 'nswe', 'children': [('Treeview.treearea', {'sticky': 'nswe'})]})], 'border': '1'})] >>> style.element_options('Calendar.Treeview.border') ('-relief',) >>> style.lookup('Calendar.Treeview.border', 'relief') '' >>> style.configure('Calendar.Treeview.border', relief='raised') {} 

Ich sehe keine Grenze und sehe keinen Effekt von der Einstellung. Vielleicht gilt die Entlastung für die Grenzen zwischen den Säulen. Ich weiß es nicht. (Beachten Sie, dass die Änderung der Zeilenhöhe sofort verfügbar ist, so dass die Konfiguration "live" ist.)

Ich habe festgestellt, dass das Tkinter Font-Objekt eine metrics () -Methode hat, die seine Höhe als "linespace" gibt. Damit kann die Zeilenhöhe dynamisch skaliert werden:

 try: from tkinter.font import Font from tkinter.ttk import Style, Treeview from tkinter import * except: from tkFont import Font font ttk import Style, Treeview from Tkinter import * font=Font(family='Arial', size=20) font.metrics() #output: {'ascent': 31, 'descent': 7, 'linespace': 38, 'fixed': 0} 

Mit diesem können Sie die Schrifthöhe mit:

 font.metrics()['linespace'] #output: 38 

Dann benutze es, um die rowheight in deinem Treeview-Widget zu setzen:

 fontheight=font.metrics()['linespace'] style=Style() style.configure('Calendar.Treeview', font=font, rowheight=fontheight) tree=Treeview(style='Calendar.Treeview') 

Das Ändern der Schriftartobjektparameter aktualisiert das Treeview-Widget bequem, aber die Zeilenhöhe wird nicht aktualisiert und muss erneuert werden. So kann zum Beispiel die Skalierung der Schriftgröße mit einer Tastenkombination so aussehen:

 def scaleup(): font['size']+=1 style.configure('Calendar.Treeview', rowheight=font.metrics()['linespace']) def scaledown(): font['size']-=1 style.configure('Calendar.Treeview', rowheight=font.metrics()['linespace']) tree.bind('<Control-equal>', scaleup) tree.bind('<Control-minus>', scaledown) 

Ich wollte das Gleiche mit Control-MouseWheel machen, aber ich habe das Verhalten noch nicht herausgefunden (wäre froh zu hören, wie das funktioniert).

Hoffe, das ist praktisch

Wie kann ich die Höhe der Zeilen in der Baumansicht ändern, wie in Prevoius Versuche Schriftgröße kann erhöht werden, aber die Zeilenhöhe erhöht sich nicht mit Schriftgröße. – HELFEN SIE HILFE

Falls Sie noch auf diese Hilfe warten, gibt es einen Weg , um die Zeilenhöhe zu ändern, obwohl das Google Gruppen-Thread sagt, dass es nicht offiziell von Tk unterstützt wird:

 #apply any configuration options ttk.Style().configure('Treeview',rowheight=30) 
  • Python Tkinter Eintrag zeigt den aktuellen Wert von textvariable nicht an
  • So ändern Sie die Farbe der ttk-Taste
  • Python 2.7 - ttk-Modul scheinbar nicht in Windows 8.1 funktioniert
  • Python tkinter mit ttk Kalender
  • Warum werden die `tkinter.ttk.Notebook` Tabs dünner und dünner?
  • Python / ttk / tKinter - Übergeben eines Arguments mit einem Button Klick func?
  • Python: Wie bekomme ich progressbar start () info von einem fenster (klasse) zu anderen
  • Rückruf und n Entry-Box-Widgets funktionieren nicht Tkinter
  • Standardtext sowie Liste textvariable Eintrags-Widget Tkinter
  • Warum ttk Progressbar erscheint nach dem Prozess in Tkinter
  • Wie erstelle ich den Fortschrittsbalken in ttk?
  • Python ist die beste Programmiersprache der Welt.