Python-GUI-Toolkit auf höherer Ebene, z. pass dict für TreeView / Grid

Startete mein erstes Python-Haustierprojekt mit PyGTK. Obwohl es ein wirklich leistungsfähiges GUI-Toolkit ist und ausgezeichnet aussieht, habe ich ein paar Pet Peeves. Also habe ich darüber nachgedacht, auf etwas anderes umzusteigen, da es noch nicht zu umfangreich ist. Habe mich auf @ umgesehS undpython Dokumentation, bekam aber keinen guten Überblick.

Was ist schön an PyGTK:

Glade files self.signal_autoconnect ({...}) self.get_widget () als __getattr __

Das nervt mich aber:

manual gobject.idle_add (lambda: ... and False)keine Standardfunktionalität zum Speichern von Anwendungs- / FensterzuständenTreeView muss ein Array erstellen widget.get_selection (). get_selected (), model.get_value (iter, liststore_index)

Baumsich: Da dies das Hauptelement der Benutzeroberfläche ist, lenkt es am meisten ab. Grundsätzlich erstellt meine Anwendung eine Liste der anzuzeigenden Wörterbücher name = column + row => value. Um es mit GTK anzuzeigen, muss ein manueller Konvertierungsprozess, eine Bestellung und Typumwandlungen durchgeführt werden. Dies scheint viel Aufwand zu bedeuten, und ich wünschte mir hier etwas objektorientierteres. PyGtk hat viele Abstraktionen auf gtk +, scheint aber immer noch ziemlich niedrig zu sein. Ich würde es vorziehen, mein Diktat so wie es ist zu übergeben und die Spalten irgendwie vordefiniert zu haben. (GtkBuilder kann TreeView-Spalten vordefinieren, dies löst jedoch nicht den Overhead für die Datendarstellung.)

Wenn ich einen Mausklick auf meine TreeView-Liste bekomme, muss ich auch alles zurück in meine Anwendungsdatenstrukturen konvertieren. Und es ist auch ärgerlich, dass PyGTK gtk + -Aufrufe nicht mit gobject.idle selbst umschließt, wenn es von einem Nicht-Haupt-Thread ausgeführt wird. Im Moment gibt es eine Menge GUI-Code, von dem ich glaube, dass er nicht notwendig sein sollte oder weg rationalisiert werden könnte.

? Also, gibt es vielleicht zusätzliche Wrapper über PyGTK. Oder welches andere Toolkit unterstützt einfachere Oberflächen für die Anzeige eines Grid / TreeView. Ich habe viel darüber gelesen, dass wxPython jedermanns Favorit ist, aber unter Linux ist es weniger ausgereift. Und PyQT scheint größtenteils dieselbe Abstraktionsebene wie PyGTK zu haben. Nicht verwendet TkInter so viel, weiß nicht, ob es einfachere Schnittstellen hat, aber es sieht trotzdem unattraktiv aus. Ebenso wie PyFLTK. Schlafanzug klingt faszinierend, ist aber schon zu weit weg (Desktop-Anwendung).

.

Also, GUI-Toolkit mit Dikt -> Gitteranzeige. Welches würdest du wählen?

.

Nur als Exponat ist dies meine aktuelle TreeView-Mapping-Funktion. Art von Arbeiten, aber ich hätte lieber etwas Standard:

    #-- fill a treeview
    #
    # Adds treeviewcolumns/cellrenderers and liststore from a data dictionary.
    # Its datamap and the table contents can be supplied in one or two steps.
    # When new data gets applied, the columns aren't recreated.
    #
    # The columns are created according to the datamap, which describes cell
    # mapping and layout. Columns can have multiple cellrenderers, but usually
    # there is a direct mapping to a data source key from entries.
    #
    # datamap = [  #  title   width    dict-key    type,  renderer,  attrs  
    #               ["Name",   150,  ["titlerow",   str,    "text",    {} ]  ],
    #               [False,     0,   ["interndat",  int,     None,     {} ]  ],
    #               ["Desc",   200,  ["descriptn",  str,    "text",    {} ],  ["icon",str,"pixbuf",{}]  ],
    #
    # An according entries list then would contain a dictionary for each row:
    #   entries = [ {"titlerow":"first", "interndat":123}, {"titlerow":"..."}, ]
    # Keys not mentioned in the datamap get ignored, and defaults are applied
    # for missing cols. All values must already be in the correct type however.
    #
    @staticmethod
    def columns(widget, datamap=[], entries=[], pix_entry=False):

        # create treeviewcolumns?
        if (not widget.get_column(0)):
            # loop through titles
            datapos = 0
            for n_col,desc in enumerate(datamap):

                # check for title
                if (type(desc[0]) != str):
                    datapos += 1  # if there is none, this is just an undisplayed data column
                    continue
                # new tvcolumn
                col = gtk.TreeViewColumn(desc[0])  # title
                col.set_resizable(True)
                # width
                if (desc[1] > 0):
                    col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
                    col.set_fixed_width(desc[1])

                # loop through cells
                for var in xrange(2, len(desc)):
                    cell = desc[var]
                    # cell renderer
                    if (cell[2] == "pixbuf"):
                        rend = gtk.CellRendererPixbuf()  # img cell
                        if (cell[1] == str):
                            cell[3]["stock_id"] = datapos  # for stock icons
                            expand = False
                        else:
                            pix_entry = datapos
                            cell[3]["pixbuf"] = datapos
                    else:
                        rend = gtk.CellRendererText()    # text cell
                        cell[3]["text"] = datapos
                        col.set_sort_column_id(datapos)  # only on textual cells

                    # attach cell to column
                    col.pack_end(rend, expand=cell[3].get("expand",True))
                    # apply attributes
                    for attr,val in cell[3].iteritems():
                        col.add_attribute(rend, attr, val)
                    # next
                    datapos += 1

                # add column to treeview
                widget.append_column(col)
            # finalize widget
            widget.set_search_column(2)   #??
            widget.set_reorderable(True)

        # add data?
        if (entries):
            #- expand datamap            
            vartypes = []  #(str, str, bool, str, int, int, gtk.gdk.Pixbuf, str, int)
            rowmap = []    #["title", "desc", "bookmarked", "name", "count", "max", "img", ...]
            if (not rowmap):
                for desc in datamap:
                    for var in xrange(2, len(desc)):
                        vartypes.append(desc[var][3])  # content types
                        rowmap.append(desc[var][0])    # dict{} column keys in entries[] list
            # create gtk array storage
            ls = gtk.ListStore(*vartypes)   # could be a TreeStore, too

            # prepare for missing values, and special variable types
            defaults = {
                str: "",
                unicode: u"",
                bool: False,
                int: 0,
                gtk.gdk.Pixbuf: gtk.gdk.pixbuf_new_from_data("\0\0\0\0",gtk.gdk.COLORSPACE_RGB,True,8,1,1,4)
            }
            if gtk.gdk.Pixbuf in vartypes:
                pix_entry = vartypes.index(gtk.gdk.Pixbuf) 

            # sort data into gtk liststore array
            for row in entries:
                # generate ordered list from dictionary, using rowmap association
                row = [   row.get( skey , defaults[vartypes[i]] )   for i,skey   in enumerate(rowmap)   ]

                # autotransform string -> gtk image object
                if (pix_entry and type(row[pix_entry]) == str):
                    row[pix_entry] = gtk.gdk.pixbuf_new_from_file(row[pix_entry])

                # add
                ls.append(row)   # had to be adapted for real TreeStore (would require additional input for grouping/level/parents)

            # apply array to widget
            widget.set_model(ls)
            return ls

        pass

Antworten auf die Frage(8)

Ihre Antwort auf die Frage