代码之家  ›  专栏  ›  技术社区  ›  mario

更高级别的python gui工具包,如pass dict for treeview/grid

  •  5
  • mario  · 技术社区  · 15 年前

    使用pygtk启动了我的第一个python宠物项目。虽然它是一个非常强大的图形用户界面工具包,看起来非常棒,但我有一些小毛病。所以我想换个别的东西,因为它还不太广泛。看看周围 SO python documentation 但没有得到一个好的概述。

    Pygtk的优点是:

    • 格莱德档案
    • self.signal_autoconnect(…)
    • self.get_widget()作为\u getattr__

    然而,这让我心烦意乱:

    • 手动gobject.idle添加(lambda:…和假)
    • 没有保存应用程序/窗口状态的标准功能
    • TreeView需要阵列构建
    • widget.get_selection().get_selected(),model.get_value(iter,liststore_index)

    树视图 :因为这是主界面元素,所以最容易分散注意力。基本上,我的应用程序会构建一个要显示的字典列表:name=column+row=>value。要使用GTK显示它,需要有一个手动转换过程、排序、打字。这似乎有很多开销,我希望在这里有更面向对象的东西。Pygtk在gtk+上有很多抽象的内容,但仍然显得相当低级。我更喜欢按原样传递我的听写,并且以某种方式预先定义列。(GTKbuilder可以预先定义TreeView列,但这并不能解决数据表示开销。)

    当我在TreeView列表上单击鼠标时,我还必须将所有内容转换回我的应用程序数据结构。而且,如果从非主线程运行,Pygtk不会用gobject.idle本身包装gtk+调用,这也让人感到厌烦。现在有很多GUI代码,我认为它们不应该是必需的,或者可以合理化。

    ? 那么,Pygtk上面是否还有其他的包装纸呢?或者其他哪个工具包支持更简单的界面来显示网格/树视图。我读过很多关于wxpython是每个人最喜欢的,但是它在Linux上不太成熟。和 PYQT 似乎与Pygtk基本上是相同的抽象级别。没有用过 特金特 很多人都不知道它是否有更简单的界面,但它看起来并不吸引人。一样 PyFLTK . 睡衣听起来很吸引人,但已经太远了(桌面应用程序)。

    .

    因此,带有dict->网格显示的GUI工具包。你会选哪个?

    .

    正如图表所示,这是我当前的TreeView映射函数。有点像,但我更希望有一个标准:

        #-- 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
    
    4 回复  |  直到 14 年前
        1
  •  5
  •   Johannes Sasongko    14 年前

    尝试 Kiwi 也许吧?尤其是它 ObjectList .

    更新:我认为猕猴桃发展已经转移到 PyGTKHelpers .

        2
  •  4
  •   ʇsәɹoɈ    15 年前

    我以前没有遇到过猕猴桃。谢谢,佐松子。

    这里还有一些我保留书签的玩具。其中一些是其他工具包(GTK、WXWidgets)的包装器,而另一些则是独立的:

    (我已经包括了一些已经提到的,是为了其他人看到这篇文章。我本可以将此作为评论发布,但有点太长了。)

        3
  •  3
  •   ychaouche    14 年前
        4
  •  1
  •   Community CDub    8 年前

    I would suggest taking a look at wxPython . 我发现它真的很容易接受和非常强大的,虽然我不得不承认,我没有做很多与树视图自己。

    wxwidgets调用等效的控件a wxTreeCtrl

    [编辑] 这个 wxDataViewTreeCtrl 在你的情况下可能更有用。