Maximale Anzahl an Elementen in einem Grid?

Fragen zu Tkinter.
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ß
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Piotr hat geschrieben: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?
Sry, fällt mir auf anhieb nichst ein, da ich das noch nie brauchte, aber ich kann mal nachsehen.
Bei meinem OS geht das automatisch :D.

Bin gerade am umschreiben deines Scripts, irgendwie habe ich gerade Probleme mit den Scrollbars.
Aber egal wollte mir sowieso schon immer mal eine Tabelle bauen :mrgreen:

Aber egal wie es nachher aussieht, die Peformance wird sich nicht Grundlegend ändern.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ok, hier mein erster Stand, vieleicht reicht dir das schon, aber heute muss ich noch was anderes machen.
Geht mit 70x70 noch Flüssig danach fängt es an zu ruckeln,
prüf mal ob der Fehler immer noch kommt.

Code: Alles auswählen

from Tkconstants import *
import Tkinter as tkinter

class AutoScrollbar(tkinter.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()
        tkinter.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 TableWidget(tkinter.LabelFrame):
    """Eine Tabelle."""
    
    def __init__(self, master, text, rows, columns, cnf={}):
        """Initialisiert eine neue Instanz von TableWidget

        @type master: tkinter.Widget
        @param master: Das Master Widget.

        @type text: str
        @param text: Der Text auf dem LabelFrame.

        @type rows: int
        @param rows: Die Anzahl der Zeilen.

        @type columns: int
        @param columns: Die Anzahl der Spalten.

        @type cnf: dict
        @param cnf: Optionen f\xfcr den Canvas.
        """  
        tkinter.LabelFrame.__init__(self, master, text=text)
        
        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 = tkinter.Canvas(self, cnf)
        self.canvas.config(yscrollcommand = vscrollbar.set)
        self.canvas.config(xscrollcommand = hscrollbar.set)
        self.canvas.grid(row=0, column=0)

        vscrollbar.config(command=self.canvas.yview)
        hscrollbar.config(command=self.canvas.xview)
        
        self.cells = {}
        self.rows = rows
        self.columns = columns

    def show_table(self, widget, options={}):
        """Legt fest aus welchen Widgets die Tabelle besteht.

        @type widget: classobj 
        @param widget: Ein tkinter.Widget aus dem jedes Feld der Tabelle
                       bestehen soll.

        @type options: dict
        @param options: Die Optionen f\xfcr das \xdcbergebene KlassenObjekt.
        """
        frame = tkinter.Frame(self.canvas)
        for row in xrange(self.rows):
            for column in xrange(self.columns):
                lb = widget(frame, options)
                lb.grid(row=row, column=column)
                self.cells[(row, column)] = lb

        self.canvas.create_window(0, 0, window=frame)
        self.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox("all"))
        
    def set_(self, xy, text=""):
        """Setzt einen Text auf eine Zelle der Tabelle.

        @type xy: tuple(x,y)
        @param xy: Die Koordinaten der Zelle.

        @type text: str
        @param text: Der Text, welcher der Zelle \xfcbergeben werden soll.

        @warning: Nur m\xf6glich wenn das Zellen Widget eine Textoption hat.
        """
        cell = self.cells[xy]
        cell.config(text=text)

        
if __name__ == "__main__":
    root = tkinter.Tk()
    root.title("Tabellen Test")

    options = dict(width=600, height=600)
    tw = TableWidget(root, "Tabelle 1", 50, 50, options)
    tw.grid(row=0, column=0)

    options = dict(bd=3, relief=RIDGE, width=3)
    tw.show_table(tkinter.Label, options)
    
    tw.set_((0,0), "100")
    tw.set_((1,1), "99")

    root.mainloop()
Zuletzt geändert von Xynon1 am Dienstag 7. Dezember 2010, 14:00, insgesamt 1-mal geändert.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ah, hier --> http://sourceforge.net/projects/tktable ... z/download

Bei dem ist die Performance um einiges höher, da hier die Tabelle direkt in tcl erstellt 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

Sorry, dass ich erst jetzt antworte. War eine Woche krank...

Ich werde deinen Code mal ausprobieren.
Aufjedenfall danke ich dir erstmal!

bye
Antworten