Maximale Anzahl an Elementen in einem Grid?

Fragen zu Tkinter.
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Hallo,

ich habe folgendes Problem und bitte Euch um Hilfe:

Ich möchte mir Daten aus einer SQL DB mittelt Tkinter in einer Tabelle darstellen.
Das funktioniert auch alles relativ problemlos.
Die Tabelle besteht einfach aus Labels die in einem Grid angeordnet werden.

Wenn ich jedoch mehr als 10k Elemente in meinem Grid anordne, verhält sich Tkinter sehr merkwürdig.
Die Tabelle wird nicht mehr korrekt dargestellt, und es sieht so aus als ob Tkinter alle Labels übereinander in der oberen linken Bildschirmecke anordnen würde. Wenn die Anzahl der Elemente noch größer wird, schmiert mir alles ab.

Hat jemand eine Lösung? Wie kann ich die Anzahl der "erlaubten" Elemente erweitern? Habe in der Tkinter Dokumentation nach Limitierungen gesucht, jedoch nichts gefunden. Hat da jemand eine Quelle wo diese aufgelistet sind?

Hier noch der (vereinfachte) Code der das Problem generiert:

Code: Alles auswählen

class Table_Widget():
    def __init__(self, master):
        self.x_pos = 0
        self.y_pos = 0
        self.frame = Frame(master)
        self.frame.pack(expand=TRUE)

    def add_cell(self, text = None):
        self.cell = Label(self.frame, text = text)
        self.cell.grid(row = self.y_pos, column = self.x_pos, sticky = NSEW)
        self.x_pos = self.x_pos + 1
  
    def start_new_row(self):
        self.x_pos = 0
        self.y_pos = self.y_pos + 1

root = Tk()

tw = Table_Widget(root)
a = 101
for i in range(1,a):
    for j in range(1,a):
        tw.add_cell("Test")
    tw.start_new_row()

root.mainloop()
Gruß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ich vermute mal das ist die Limitierung deines Bildschirms,
versuch es mal mit einem Canvas und Scrollbars statt auf dem root-Widget.

Canvas sollte unbegrenzt sein, da es ein Koordinatensystem unterstützt, auch über die Bildschirmgröße hinaus.
und die Scrollbars, damit du naviieren kannst wenn es dennoch darüber geht.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:Ich vermute mal das ist die Limitierung deines Bildschirms,
versuch es mal mit einem Canvas und Scrollbars statt auf dem root-Widget.

Canvas sollte unbegrenzt sein, da es ein Koordinatensystem unterstützt, auch über die Bildschirmgröße hinaus.
und die Scrollbars, damit du naviieren kannst wenn es dennoch darüber geht.
Nein, das ist definitiv nicht die Ursache des Problems.
Meine Orginaltabelle hat ein Canvas und Scrollbars, jedoch die gleichen Probleme.

Gruß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

mh, dann musst du etwas detailierter werden.
Denn dein Beispiel oben, stellt bei mir kein Problem dar, abgesehen davon, das mein Speicher etwas voll wird.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:mh, dann musst du etwas detailierter werden.
Denn dein Beispiel oben, stellt bei mir kein Problem dar.
Hm, welche Python Version hast du?
Könntest Du bitte den Wert für a erhöhen und mir sagen wo dein maximum liegt?

Gruß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Python 2.6.5

Ein Maximum außer an der Hardware Leistung ist bisher nicht in Sicht, aber in deinem Beispiel oben sind auch keine Scrollbars, damit kann ich das nicht zu 100 % sagen.

Ich erstelle gerade noch ein Muster 1000 x 1000, das brauch aber seine Zeit.
Für solche Sachen ist Tkinter eigentlich auch nicht geeignet.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:Python 2.6.5

Ein Maximum außer an der Hardware Leistung ist bisher nicht in Sicht, aber in deinem Beispiel oben sind auch keine Scrollbars, damit kann ich das nicht zu 100 % sagen.

Ich erstelle gerade noch ein Muster 1000 x 1000, das brauch aber seine Zeit.
Für solche Sachen ist Tkinter eigentlich auch nicht geeignet.
Ich werde mal eine komplexere Version meines Table_Widgets posten. Dauert aber noch eine Stunde oder so, bin hier grade im stress :-)

Erstmal danke für deine Mühe!
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

btw. ich würde das sowieso etwas anders machen.

Wenn du tatsächlich eine solche Große Tabelle brauchst, würde ich die nicht von Beginn an erstellen.

Sondern immer wenn ein Scrollevent ausgeführt wird, entsprechende Anzahl an Feldern hinzufügen, bzw. einfach nur die Daten Matrix darauf verschieben.
Weil eine solche Applikation mit Tkinter enorm viel Prozessor Leistung und nach dem erstellen Speicher frisst.
die 1000 x 1000 Rendert immer noch und ich bin bei 412 MB :shock: RAM Auslastung und dauerhaft 50% CPU Belastung (Duo Core) <-- Das kann man einfach nicht so realisieren.

Edit: Habe es jetzt bei 550 MB abbgebrochen, die CPU Temperatur lief auf 70 Grad zu und der Lüfter hatte aussetzer. Also siehe nochmal das jetzt fettgedruckte.

Aber vieleicht sieht dein Programm ja etwas anders aus. :wink:

btw Lass den Unterstrich bei Table_Widget weg oder nenn es einfach nur Table, bei Klassennamen sind Unterstriche eigentlich nicht gewollt.
Zuletzt geändert von Xynon1 am Freitag 12. November 2010, 12:32, insgesamt 1-mal geändert.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:btw. ich würde das sowieso etwas anders machen.

Wenn du tatsächlich eine solche Große Tabelle brauchst, würde ich die nicht von Beginn an erstellen.

Sondern immer wenn ein Scrollevent ausgeführt wird, entsprechende Anzahl an Feldern hinzufügen, bzw. einfach nur die Daten Matrix darauf verschieben.
Weil eine solche Applikation mit Tkinter enorm viel Prozessor Leistung und nach dem erstellen Speicher frisst.
die 1000 x 1000 Rendert immer noch und ich bin bei 412 MB :shock: RAM Auslastung und dauerhaft 50% CPU Belastung (Duo Core) <-- Das kann man einfach nicht so realisieren.

Aber vieleicht sieht dein Programm ja etwas anders aus. :wink:

btw Lass den Unterstrich bei Table_Widget weg oder nenn es einfach nur Table, bei Klassennamen sind Unterstriche eigentlich nicht gewollt.
Also, echt komisch dass das bei dir überhaupt möglich ist. Wie gesagt, bei mir schmiert er relativ zeitnah ab wenn ich sowas versuche :-)

Gruß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Welches OS ?
Und wie groß ist die Swap Partition (ähm, im Windows glaube ich heißt das Auslagerungsdatei)?
Und wie viel RAM hat dein Rechner ?
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:Welches OS ?
Und wie groß ist die Swap Partition (ähm, im Windows glaube ich heißt das Auslagerungsdatei)?
Und wie viel RAM hat dein Rechner ?
OS: Win XP SP3
RAM: 2 GB
CPU: P4 3,6 GHz
Auslagerungsdatei: 4 GB

Gruß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Siehe nochmal in mein Post oben :mrgreen:

Oha 2GB RAM und 4 GB Auslagerung und da geht das nicht ? :shock:
Vieleicht doch noch ein Script fehler

Ich habe hier gerade mal 1 GB RAM.
Aber wie schon gesagt ich würde es lassen, das auf die Art zu realisieren.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:Siehe nochmal in mein Post oben :mrgreen:

Oha 2GB RAM und 4 GB Auslagerung und da geht das nicht ? :shock:
Vieleicht doch noch ein Script fehler

Ich habe hier gerade mal 1 GB RAM.
Aber wie schon gesagt ich würde es lassen, das so zu realisieren.
Im Normalfall hab ich aber max 1k Elemente, und das sollte Tk schon können.

Gruß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Naja bei 1000 kommst du schon stark an die Grenzen von Tkinter.

Aber musst du selbst sehen wie gut es läuft.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:Naja bei 1000 kommst du schon stark an die Grenzen von Tkinter.

Aber musst du selbst sehen wie gut es läuft.


Ja, läuft garnicht :D
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Aber noch nicht wegen dem zu hohen Rechenaufwand, oder ?
Erstell erstmal ein detailiertertes Beispiel. :D
Vieleicht kommst du dann auch schon selbst darauf.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Hm, könntest du mir vielleicht eine andere GUI empfehlen?

Gruß
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Xynon1 hat geschrieben:Aber noch nicht wegen dem zu hohen Rechenaufwand, oder ?
Erstell erstmal ein detailiertertes Beispiel. :D
Vieleicht kommst du dann auch schon selbst darauf.
Hier ein umfangreiches Beispiel, welches exakt meine Tabelle beschreibt:

Code: Alles auswählen

class AutoScrollbar(Scrollbar):
    # a scrollbar that hides itself if it's not needed.  only
    # works if you use the grid geometry manager.
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        Scrollbar.set(self, lo, hi)
    def pack(self, **kw):
        raise TclError, "cannot use pack with this widget"
    def place(self, **kw):
        raise TclError, "cannot use place with this widget"

class Table_Widget(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master)
        self.active_main_cell = self
        self.x_sub_pos = 0
        self.x_pos = 0
        self.y_pos = 0

        self.create_scollbars()

        self.frame = Frame(self.canvas)
        self.frame.rowconfigure(1, weight=1)
        self.frame.columnconfigure(1, weight=1)
        self.frame.pack(expand=TRUE)

    def create_scollbars(self):
        vscrollbar = AutoScrollbar(self)
        vscrollbar.grid(row=0, column=1, sticky=N+S)
        hscrollbar = AutoScrollbar(self, orient=HORIZONTAL)
        hscrollbar.grid(row=1, column=0, sticky=E+W)

        self.canvas = Canvas(self,
                        yscrollcommand=vscrollbar.set,
                        xscrollcommand=hscrollbar.set)
        self.canvas.grid(row=0, column=0, sticky=N+S+E+W)

        vscrollbar.config(command=self.canvas.yview)
        hscrollbar.config(command=self.canvas.xview)

        # make the canvas expandable
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

    def add_x_main_cell(self, color = None):
        self.x_sub_pos = 0
        self.active_main_cell = Frame(self.frame, bd=3, relief = RIDGE, bg = color )
        self.active_main_cell.grid(row = self.y_pos, column = self.x_pos, sticky = NSEW)
        self.x_pos = self.x_pos + 1

    def add_x_cell(self, value):
        self.x_sub_pos = self.x_sub_pos + 1
        cell = Label( self.active_main_cell, text = '%s' % (value))
        cell.pack(side=LEFT, expand=TRUE, fill="x" )
    def start_new_row(self):
        self.x_pos = 0
        self.y_pos = self.y_pos + 1

    def show_table(self):
        self.canvas.create_window(0, 0, anchor=NW, window=self.frame)
        self.frame.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox("all"))
        self.lift()
        self.mainloop()

root = Tk()

tw = Table_Widget(root)

a = 70

for i in range(1,a):
    for j in range(1,a):
        tw.add_x_main_cell()
        tw.add_x_cell("AA")
        tw.add_x_cell("BB")
    tw.start_new_row()

tw.show_table()
Wie hoch kannst du nun mit dem a-Wert gehen? Bei mir läuft es noch bis ca. 50.
Manchmal bekomme ich sogar eine Fehlermeldung:
Unable to register TkTopLevel class

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Piotr hat geschrieben:Hm, könntest du mir vielleicht eine andere GUI empfehlen?
So ziemlich jede anderere :D - dort gibt es Tabellen als Standard

Qt - ist die Größte und eignet dich für Tabelle Geschichten eigentlich sehr gut.
Gtk - ähnelt Tk sehr, und hat Tabellen auch als Standard enthalten
wx - kann ich dir leider nicht sagen

Achja setz deinen Quellcode bitte in die richtigen Code-Tags, also am besten bei code=python schreiben.
Piotr hat geschrieben:Wie hoch kannst du nun mit dem a-Wert gehen? Bei mir läuft es noch bis ca. 50.
Manchmal bekomme ich sogar eine Fehlermeldung:
bis 200 habe ich es jetzt mal schnell - bin jezt zu Hause, also ist mein Rechner etwas schneller -
Rendern lassen, geht....
Aber es dauert und die Scrollperformace ist nicht sehr hoch im Gegenteil die Aktualisierung dauern mit unter mehrere Sekunden, ich seh mir den Code gleich mal genauer an.
Aber ich vermute beim Scrollen Aktuallisierst du den gesamten Canvas.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Piotr
User
Beiträge: 16
Registriert: Freitag 12. November 2010, 10:23

Übrigens habe ich Py Script auch mal auf einem anderen Rechnern laufen lassen und dort besteht das gleiche Problem.
Es handelte sich aber in beiden Fällen um Win XP Rechner. Evtl. läuft es nur unter Linux stabil? :)

Wenn du schon dabei bist dir mein Script anzusehen, hätte ich noch eine weitere Frage.
Ich möchte dass sich die Canvas größe automatisch an den Inhalt anpasst (max. Bildschirmauflösung) und erst ab da an die Scrollbars eingeblendet werden. Hast du eine Idee wie man das relativ einfach realisieren könnte?

Gruß
Antworten