Tabelle mit horizontaller Scrollbar

Fragen zu Tkinter.
Antworten
snowflake
User
Beiträge: 93
Registriert: Mittwoch 9. November 2016, 15:46

Guten Morgen zusammen,

ich habe eine Klasse, mit der ich eine Tabelle erstelle. Die Klasse habe ich irgendwann mal im Internet gefunden und an meine Bedürfnisse angepasst. Kann mir jemand sagen, wie ich der Tabelle eine horizontale Scrollbar ergänzen kann? Die wäre dann notwendig, wenn die Spaltenbreite über den zur Verfügung stehende Platz hinaus gehen würde.

Code: Alles auswählen

from tkinter import *

class TkScrollTabelle:

    def __init__(self, frame, zeilen, spalten, height ,breite):

        self.frame = frame

        self.frame2 = Frame(self.frame)
        self.frame2.grid(row=0, column=0, sticky='nswe')
        self.frame2.grid_rowconfigure(0, weight=1)
        self.frame2.grid_columnconfigure(0, weight=1)

        self.zeilen = zeilen
        self.spalten = spalten
        self.breite = []
        self.breite = breite
        self.tabelle = []

        self.canvas = Canvas(self.frame2, bd=0, height=height)
        self.canvas.grid(row=0, column=0)
        self.xpos = 0
        self.ypos = 0
        for z in range(zeilen):
            self.tabelle.append([])
            for s in range(spalten):
                try:
                    spaltenbreite = self.breite[s]
                except:
                    spaltenbreite = 10
                entry = Entry(self.canvas, width=spaltenbreite, bg="white", fg="black", bd=1)
                entry.grid(row=z, column=s)
                self.canvas.create_window(self.xpos, self.ypos, window=entry,
                    anchor='nw')
                self.xpos += entry.winfo_reqwidth()
                self.tabelle[-1].append(entry)
            self.xpos = 0
            self.ypos += entry.winfo_reqheight()

        yscrollbar = Scrollbar(self.frame2)
        yscrollbar.grid(row=0, column=1, sticky='ns')
        yscrollbar.config(command=self.canvas.yview)
        xpos, ypos, width, height = self.canvas.bbox('all')
        self.canvas.config(width=width, yscrollcommand=yscrollbar.set)
        self.canvas.config(scrollregion=(xpos, ypos, width, height))

    def einfuegen(self, zeile, spalte, text):
        self.tabelle[zeile-1][spalte-1].insert('end', text)

    def loeschen(self, zeile, spalte):
        self.tabelle[zeile-1][spalte-1].delete(0,END)

    def tab_loeschen(self):
        for spalte in range(0,self.spalten):
            for zeile in range(0,self.zeilen):
                tab1.loeschen(zeile, spalte)

    def wert(self, zeile, spalte):
        return self.tabelle[zeile-1][spalte-1].get()

    def format(self, zeile, spalte, hgFarbe="white", fgFarbe="black", status="normal", ausrichtung="left", schrift=('Arial 10')):
        self.tabelle[zeile-1][spalte-1].config(bg=hgFarbe, fg=fgFarbe, state=status, justify=ausrichtung, font=schrift)

def test():
    print("Funktion test gestartet...")
    tab1.loeschen(1,1)
    tab1.einfuegen(1,1,"Zeile/Spalte")
    tab1.format(zeile=1, spalte=1, ausrichtung="center", hgFarbe="grey", schrift="Arial 10 bold")
    tab1.format(zeile=2, spalte=2, status="readonly", fgFarbe="green", ausrichtung="left")


if __name__ == '__main__':

    root = Tk()
    rahmen = LabelFrame(root, text="Tabelle 123", fg="black", bd=0)
    rahmen.pack()
    spalten = 8
    breite = [5, 30, 7, 20, 30, 10, 30,5]
    zeilen = 101
    hoehe = 400
    tab1 = TkScrollTabelle(rahmen, zeilen, spalten, hoehe, breite)
    button = Button(root, text="Test", command=test)
    button.pack()
    tab1.einfuegen(2,2,"Test1234")
    tab1.format(zeile=2, spalte=2, status="disabled", fgFarbe="red")

    for z in range(2, zeilen+1):
        tab1.einfuegen(z, 1, str(z-1))
        tab1.format(zeile=z, spalte=1, ausrichtung="center", status="readonly", schrift='Arial 10 bold')

    buchstaben = ["A", "B", "C", "D", "E", "F", "G"]
    for s in range(2, spalten+1):
        tab1.einfuegen(1, s, str(buchstaben[s-2]))
        tab1.format(zeile=1, spalte=s, ausrichtung="center", status="readonly", schrift="Arial 10 bold")

    for z in range(2, zeilen+1):
        for s in range(2, spalten+1):
            tab1.format(zeile=z, spalte=s, hgFarbe="lightblue1")

    root.mainloop()
Vielen Dank und freundliche Grüße

snowflake
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@snowflake: Inzwischen nach 79 Beiträge benutzt Du immer noch *-Importe und globale Variablen.
Die Zuweisung einer leeren Liste an self.breite ist überflüssig, wenn man gleich danach das Attribut wieder überschreibt.
Nackte excepts sollte man nicht verwenden, wenn man eigentlich nur einen IndexError erwartet.
Wenn man Werte in einer for-Schleife ändert, dann ist das ein ganz sicheres Zeichen dafür, dass das keine Attribute sein sollten, wie self.xpos oder self.ypos.

Horizontale Scrollbars werden wie vertikale benutzt, nur dass halt statt yscrollcommand xscrollcommand steht.
snowflake
User
Beiträge: 93
Registriert: Mittwoch 9. November 2016, 15:46

Hallo Sirius3,

mir ist nach 79 Beiträgen die Bedeutung mit dem *-Import bewusst. Dass ich mir damit möglicherweise Probleme mit den Namensräumen einfange ist mir klar. Zu meiner Verteidigung muss ich sagen, dass dieses Skript schon etwas älter ist und von mir nicht mehr abgeändert wurde. Sobald ich hierfür (scrollen) eine Lösung habe, werde ich diesen Missstand korrigieren. Bzgl. der globalen Variablen bin ich mir im klaren, dass das keine gute Lösung ist. Unabhängig von diesem Skript weiß ich allerdings manchmal keine andere Lösung.

Am Ende der Klasse TkScrollTabelle habe ich folgenden Code eingefügt:

Code: Alles auswählen

xscrollbar = Scrollbar(self.frame2)
xscrollbar.config(command=self.canvas.xview)
self.canvas.config(width=width, xscrollcommand=xscrollbar.set)
self.canvas.config(scrollregion=(xpos, ypos, width, height))
Leider bin ich damit der Lösung keinen Schritt näher gekommen. Es erscheint kein horizontaler Balken. Was mache ich falsch?

Vielen Dank und gesund bleiben

snowflake
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Da fehlt zum einen ein orient=tk.HORIZONTAL und zum anderen, wo ist das grid?
snowflake
User
Beiträge: 93
Registriert: Mittwoch 9. November 2016, 15:46

Hallo Sirius3,

hiermit wird der horizontale Balken angezeigt, er lässt sich aber nicht nutzen.

Code: Alles auswählen

        
xscrollbar = Scrollbar(self.frame2)
xscrollbar.grid(row=1, column=0, sticky='we')
xscrollbar.config(command=self.canvas.xview, orient=HORIZONTAL)
self.canvas.config(width=width, xscrollcommand=xscrollbar.set)
self.canvas.config(scrollregion=(xpos, ypos, width, height))
Ich weiß wirklich nicht mehr was ich noch ändern könnte.

Vielen Dank und viele Grüße

snowflake
Antworten