GtkIconView non riempie automaticamente lo spazio con l'icona quando l'utente ridimensiona la finestra


9

Nel progetto Ubuntu Accomplishments stiamo riscontrando alcuni bug insoliti:

Vale a dire che abbiamo una finestra con un GtkNotebook e un GtkIconView su una pagina e un'altra su un'altra pagina.

Quando l'utente ridimensiona la finestra iconview non riempie automaticamente lo spazio di icone (rimangono nel loro layout di colonna originale) ma se l'utente cambia le pagine di GtkNotebook e quindi aggiorna la visualizzazione dell'icona lo spazio viene occupato come previsto. Come possiamo usare automaticamente lo spazio quando ridimensioniamo la finestra?

La cosa più preoccupante è che quando appare la finestra, possiamo ridimensionarla più piccola - sembra che la vista icona ci blocchi dal ridimensionamento e quindi abbia un'area scorrevole per le icone.

Il codice è simile al seguente. I ListStore che guidano IconView:

    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)

Oltre a questo, non curiamo davvero con IconViews, ma aggiungiamo semplicemente contenuto a ListStores per aggiornare le visualizzazioni.

Il codice per il progetto è qui : qualcuno può consigliarci come possiamo risolvere questi due problemi?


Solo una spiegazione: quando l'utente cambia le pagine del Notebook, il codice dell'applicazione cancella il modello sottostante e aggiunge di nuovo tutti gli elementi, il che sembra essere il motivo per cui GtkIconView aggiorna e usa lo spazio vuoto.
Rafał Cieślak,

Risposte:


3

Ok, come abbiamo capito come risolvere questo, descriverò la soluzione qui, nel caso in cui qualcun altro abbia questo problema.

Il trucco è posizionare GtkIconView in una finestra GtkScrolled , e impostare la sua hscrollbar_policy su "sempre". Quindi, è necessario utilizzare un segnale di controllo del ridimensionamento, per reagire quando l'utente ridimensiona la finestra (si noti che deve essere controllato se la dimensione è cambiata, poiché il segnale viene emesso anche quando, ad esempio, la finestra viene trascinata).

Quando le dimensioni cambiano, il modello utilizzato da GtkIconView deve essere cancellato e ricreato, in quanto ciò innesca GtkIconView riallocando correttamente lo spazio appena guadagnato (o restringendolo). Inoltre, come risultato, la barra di scorrimento orizzontale non sarà mai vista, poiché GtkIconView utilizza esattamente lo stesso spazio utilizzato da GtkScrolledWindow.


Questo è stato estremamente utile, grazie per la risposta! Ne sono stato colpito su lp: qreator e con la tua correzione il numero di colonne dell'icona nella vista dell'icona principale è dinamico al ridimensionamento.
David Planella,

1

La mia soluzione preferita a questo problema è una sottoclasse molto piccola di 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 sostituzione get_preferred_width consente di restringere arbitrariamente la vista. Il callback con allocazione delle dimensioni forza un relayout impostando il numero di colonne su 1 e viceversa.


1

Puoi anche impostare le colonne su 0 e di nuovo su -1 quando le dimensioni cambiano. In questo modo le icone non verranno deselezionate:

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

(Questo dovrebbe essere fatto in aggiunta alla risposta di @ rafalcieslak .)


Perché questo oltre alla risposta di rafalcieslak? Se cambi il numero di colonne, otterrai un relayout; ricostruire il modello sarebbe comunque inutile.
cscarney,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.