2010-06-28 8 views
5

Comencé mi primer proyecto de Python pet usando PyGTK. A pesar de que es un juego de herramientas de interfaz gráfica de usuario muy potente y se ve excelente, tengo algunas cosas malas. Así que pensé en la transición a otra cosa, ya que aún no es demasiado extensa. Echó un vistazo en SO y python documentation, pero no obtuvo una buena visión general.kit de herramientas de GUI de Python de nivel superior, p. pase dict para TreeView/Grid

Lo bueno de PyGTK:

  • archivos Glade
  • self.signal_autoconnect ({...})
  • self.get_widget() como __getattr__

Esto me está molestando sin embargo:

  • manual gobject.idle_add (lambda:. .. y Falso)
  • ninguna funcionalidad estándar para guardar los estados de aplicación/ventana
  • TreeView necesidades de creación de gama
  • widget.get_selection(). Get_selected(), model.get_value (iter, liststore_index)

TreeView: Debido a que este es el elemento principal de la interfaz, es el que más distrae. Básicamente, mi aplicación crea una lista de diccionarios que se mostrarán name = column + row => value. Para mostrarlo usando GTK, debe haber un proceso de conversión manual, pedidos, tipos de difusión. Esto parece mucho sobrecargado, y deseé algo más orientado a objetos aquí. PyGtk tiene muchas abstracciones en la parte superior de gtk +, pero aún parece bastante bajo nivel. Preferiría pasar mi dict tal como está y tener columnas predefinidas de alguna manera. (GtkBuilder puede predefinir las columnas TreeView, pero esto no resuelve la sobrecarga de representación de datos.)

Cuando obtengo un mousclick en mi lista TreeView, también tengo que convertir todo de nuevo en las estructuras de datos de mi aplicación. Y también es molesto que PyGTK no envuelva llamadas gtk + con gobject.idle, si se ejecuta desde un hilo no principal. En este momento hay una gran cantidad de código GUI que creo que no debería ser necesario, o podría racionalizarse.

? Entonces, ¿hay quizás envoltorios adicionales encima de PyGTK? O qué otro kit de herramientas admite interfaces más simples para mostrar un Grid/TreeView. He leído mucho sobre wxPython siendo el favorito de todos, pero es menos maduro en Linux. Y PyQT parece ser principalmente el mismo nivel de abstracción que PyGTK. No he usado TkInter tanto, así que no sé si tiene interfaces más simples, pero de todos modos parece poco atractivo. Como hace PyFLTK. Pijamas suena fascinante, pero ya está demasiado lejos (aplicación de escritorio).

.

Por lo tanto, GUI toolkit with dict -> Grid display. ¿Cuál elegirías?

.

Al igual que la exposición, esta es mi función actual de mapeo TreeView.Tipo de obras, pero preferiría tener algo estándar:

#-- 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 

Respuesta

5

Prueba Kiwi, ¿quizás? Especialmente con su ObjectList.

Actualización: Creo que el desarrollo de Kiwi se ha movido a PyGTKHelpers.

+0

Tengo que comprar algunos votos por adelantado. Y algo para golpearme a mí mismo. En realidad, había leído sobre Kiwi antes, pero de alguna manera lo pasé por alto en el momento de la implementación. Eso es realmente lo que quería. Solo tiene que verificar si puede recuperar el contenido de ObjectLists tal como está en una devolución de llamada de señal. – mario

1

I would suggest taking a look at wxPython. Me pareció muy fácil de aprender y muy poderoso también, aunque tendría que admitir que no he hecho mucho con Treeviews.

wxWidgets llama al control equivalente un wxTreeCtrl

[Editar] ElwxDataViewTreeCtrl en realidad podría ser más útil en su caso.

+0

¿Cómo es que responder a su pregunta? Si bien ha pasado un tiempo desde que utilicé estas dos bibliotecas, mi sensación era que, en todo caso, PyGTK tiene un nivel superior al de wxPython. No veo nada en los documentos de wxTreeCtrl que sugiera que puede, por ejemplo, simplemente pasar un diccionario y terminarlo. – Ken

+0

No es tan útil como lo pensé primero. Estoy seguro de que había visto un ejemplo en el sitio web de wxPython haciendo algo como esto, pero ahora no puedo encontrarlo: -/ –

+0

Investigaré esto de todos modos. WX usa GTK como back-end, por lo que al menos no puede ser una degradación visual. Pero dado que es un contenedor de compatibilidad, probablemente sea el nivel de abstracción del denominador común. Pero luego, estoy más interesado en la API TreeView. Simplemente no he visto el documento pertinente todavía ... – mario

4

No había encontrado Kiwi antes. Gracias, Johannes Sasongko.

Aquí hay algunos comentarios adicionales que guardo marcados. Algunos de estos son envolturas alrededor de otras herramientas (GTK, wxWidgets), mientras que otros están solos:

(He incluido algunos que ya fueron mencionados por el bien de otros que vienen con este post. Me hubiera publicado esto como un comentario, pero es un poco demasiado largo.)

+0

Excelentes puntos en su lista. He visto a Dabo antes, que parecía tener un nivel mucho más alto y proporciona una vista de datos sobre una vista de árbol/cuadrícula.Sin embargo, no pude encontrar una documentación API real y, por lo tanto, no estoy seguro de si los componentes de UI se pueden usar independientemente de las fuentes de la base de datos. – mario

+0

¡Y AVC suena aún mejor! "AVC es una conexión multiplataforma, completamente automática, en vivo entre widgets de interfaz gráfica y variables de aplicación para el lenguaje python". – mario

+0

+1 para Dabo, nivel muy alto. – ychaouche

Cuestiones relacionadas