GtkIconView no llena automáticamente el espacio con el icono cuando el usuario cambia el tamaño de la ventana

9

En el proyecto de Logros de Ubuntu, tenemos algunos errores inusuales:

Es decir, tenemos una ventana con un GtkNotebook y un GtkIconView en una página y otro en otra página.

Cuando el usuario cambia el tamaño de la ventana, la vista de iconos no llena automáticamente el espacio con iconos (permanecen en su diseño de columna original) pero si el usuario cambia las páginas de GtkNotebook y, por lo tanto, actualiza la vista de iconos, el espacio se ocupa como se esperaba. ¿Cómo podemos usar automáticamente el espacio al cambiar el tamaño de la ventana?

Sin embargo, lo que es más preocupante es que cuando aparece la ventana, podemos cambiar su tamaño más pequeño, parece que la vista de icono nos impide cambiar el tamaño y luego tener una región desplazable para los iconos.

El código se ve así. Los ListStores que manejan IconViews:

    self.trophystore = Gtk.ListStore(str, GdkPixbuf.Pixbuf, bool, bool, str, str) # title, icon accomplished, locked, app, accomplishment
    self.trophystore.set_sort_column_id(COL_TITLE, Gtk.SortType.ASCENDING)
    self.trophy_icon.set_model(self.trophystore)

    self.oppstore = Gtk.ListStore(str, GdkPixbuf.Pixbuf, bool, bool, str, str) # title, icon, accomplished, locked, app, accomplishment
    self.oppstore.set_sort_column_id(COL_TITLE, Gtk.SortType.ASCENDING)
    self.opp_icon.set_model(self.oppstore)

    self.trophy_icon.set_text_column(COL_TITLE)
    self.trophy_icon.set_pixbuf_column(COL_PIXBUF)

    self.opp_icon.set_text_column(COL_TITLE)
    self.opp_icon.set_pixbuf_column(COL_PIXBUF)

Aparte de esto, en realidad no hurgamos con IconViews, solo agregamos contenido a ListStores para actualizar las vistas.

El código para el proyecto está aquí . ¿Alguien puede recomendar cómo podemos solucionar estos dos problemas?

jonobacon
fuente
Solo una explicación: cuando el usuario cambia las páginas de Notebook, el código de la aplicación borra el modelo subyacente y agrega todos los elementos nuevamente, lo que parece ser la razón por la que GtkIconView actualiza y usa el espacio vacío.
Rafał Cieślak

Respuestas:

3

Bien, ya que hemos descubierto cómo solucionar esto, describiré la solución aquí, en caso de que alguien más tenga este problema.

El truco consiste en colocar el GtkIconView en un GtkScrolledWindow y establecer su hscrollbar_policy en "siempre". Luego, se debe usar una señal de verificación de cambio de tamaño, para reaccionar cuando el usuario cambia el tamaño de la ventana (tenga en cuenta que debe verificarse si el tamaño ha cambiado, ya que la señal se emite también, por ejemplo, cuando la ventana se arrastra).

Cuando el tamaño cambia, el modelo utilizado por GtkIconView tiene que borrarse y recrearse, ya que esto desencadena GtkIconView correctamente reasignando el espacio recién ganado (o reduciéndose). Además, como resultado, la barra de desplazamiento horizontal nunca se verá, ya que GtkIconView usa exactamente tanto espacio como GtkScrolledWindow.

Rafał Cieślak
fuente
Esto ha sido extremadamente útil, ¡gracias por la respuesta! Me afectó en lp: qreator y con su corrección, el número de columnas de iconos en la vista de iconos principal es dinámico al cambiar el tamaño nuevamente.
David Planella
1

Mi solución preferida para este problema es una subclase muy pequeña de Gtk.IconView:

class FluidIconView (Gtk.IconView):
    def __init__ (self):
        Gtk.IconView.__init__ (self)
        self.connect ("size-allocate", FluidIconView.on_size_allocate)

    def do_get_preferred_width (self):
        return (0,0)

    def on_size_allocate (self, allocation):
        [self.set_columns (m) for m in [1,self.get_columns ()]]

La anulación get_preferred_width permite que la vista sea arbitrariamente estrecha. La devolución de llamada de asignación de tamaño fuerza una retransmisión configurando el número de columnas a 1 y viceversa.

cscarney
fuente
1

También puede establecer las columnas en 0 y volver a -1 cuando cambia el tamaño. De esta manera, los íconos no serán deseleccionados:

iconview.set_columns(0)
iconview.set_columns(-1)

(Esto debe hacerse además de la respuesta de @ rafalcieslak ).

usuario82378
fuente
¿Por qué es esto además de la respuesta de rafalcieslak? Si cambia el número de columnas, obtendrá un relevo; reconstruir el modelo de todos modos sería inútil.
cscarney