web-dev-qa-db-fra.com

Comment faire en sorte que Gtk.Iconview réagisse en un clic au lieu d'un double clic?

J'utilise un widget Gtk.IconView dans mon application pour sélectionner différents types d'éléments. Le fonctionnement d’IconView est le suivant:

  • Faites un clic pour sélectionner l'élément
  • Faites un double-clic supplémentaire pour activer l'élément

J'ai toujours trouvé déroutant qu'un double-clic supplémentaire soit nécessaire, alors que la plupart des widgets de type bouton du bureau ne nécessitent qu'un seul clic. Maintenant, je viens de recevoir les commentaires de quelques utilisateurs qui trouvent cela déroutant (quelqu'un a pensé que c'était un bug que cliquer sur le bouton "n'a rien fait"), j'ai donc décidé de chercher comment changer ce comportement.

Idéalement, j'aimerais que l'IconView se comporte comme suit:

  • Survolez pour sélectionner un élément (facultatif)
  • Un simple clic active l'élément

Maintenant, je n'ai rien trouvé d'évident dans les propriétés du widget pour qu'il se comporte comme ça. Est-ce que quelqu'un sait comment ou si cela pourrait être réalisé?

Gtk.IconView in action

6
David Planella

Une solution (mais uniquement pour l’activation en un seul clic) permet d’utiliser le signal selection_changed de IconView (car la sélection IconView est basée sur un simple clic).

Un exemple supposant un signal on_item_activated actif serait:

def on_icon_view_selection_changed(self, widget):
        self.on_item_activated(widget, widget.get_selected_items()[0])
5
xubuntix

Un GtkIconView n'est pas un arrangement de widgets de boutons dans une table. Il s’agit d’un cas particulier de GtkTreeView, avec des éléments disposés dans une grille plutôt que dans une liste/une arborescence. Pour mettre en évidence les éléments en vol stationnaire, je pense qu'un correctif pour GTK + serait nécessaire. Un correctif serait également nécessaire pour ajouter une API permettant d'activer un clic ou un double-clic. Toutefois, cette fonctionnalité peut être implémentée au-dessus de l'API de widget existante, en écoutant le signal button_press_event sur le widget. et agissant en conséquence.

2
dobey

Vous semblez explorer les limites de Gtk récemment :-)

Tout d’abord, la réponse de Dobeys semble correcte.

Les magasins d’arbres et de listes sont un bon choix pour les collections. De plus grandes quantités de données de type identique mais de méta-contenu différent (par exemple, une collection musicale dans laquelle chaque morceau contient un artiste, un album, un titre, mais le nom de l'artiste, le nom de l'album et le nom du titre changent).

La bonne chose à propos de ces widgets est qu’ils sont faciles à trier, que de nombreux éléments peuvent être sélectionnés (par exemple, en mode "élastique") et que vous avez besoin de relativement peu de lignes de code pour ajouter des milliers d’articles similaires.

Changer la manière dont une TreeView ou une ListView se comporte de cliquer/survol, etc. à un niveau par application est une mauvaise idée, car cela dérange la façon dont les utilisateurs attendez que votre application se comporte bien. Vous l'avez découvert vous-même en vous basant sur la réaction que vous décrivez dans votre question.

Cependant, votre problème est que les utilisateurs n'ont pas compris que votre widget est une arborescence/ListView. Ils ont plutôt pensé qu'il s'agissait d'un certain nombre de boutons. Et cela semble logique, basé sur votre capture d'écran.

Les boutons sont destinés à lancer une action (par exemple, arrêter, lire, mettre en pause) ou à communiquer avec le programme (par exemple, Ok, Annuler) ou même à servir de lien vers une vue différente (voir LinkButton). Normalement, aucun objet ou élément (abstrait) n'y est associé (par exemple, "" Sammy Davis Jr "de" Movits! "De l'album" Out of my head "').

Ainsi, bien que le comportement de clic non configurable soit une lacune de gtk, il ne doit en aucun cas s’appliquer à un niveau global par utilisateur.

Ce que vous voulez est probablement un grille avec boutons . (Les boutons peuvent également contenir des icônes).

1
xubuntix

Voici comment j'ai fait en sorte qu'Iconview réponde à la position du pointeur pour obtenir un effet de survol et des actions simples avec un clic gauche et un clic droit.

Vous devez activer le pointeur-motion-notify pour le widget, puis convertir la position x, y du pointeur en chemin de la vue icône:

...
    self.iconview.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
    self.iconview.connect("item-activated", self.iv_icon_activated)
    self.iconview.connect("button-press-event", self.on_mouse_click)
    self.iconview.connect("motion-notify-event", self.on_pointer_motion)

def on_pointer_motion(self, widget, event):
    path= self.iconview.get_path_at_pos(event.x, event.y)
    if path !=None:
            self.iconview.select_path(path)
    #If we're outside of an item, deselect all items (turn off highlighting)
    if path == None:
        self.iconview.unselect_all()

def on_mouse_click(self,widget, event):
    if event.type == Gdk.EventType.BUTTON_PRESS:
        path=self.iconview.get_selected_items()[0]
       #if right click activate a pop-up menu
        if event.button == 3 and path != None:
            self.popup.popup(None, None, None, None, event.button, event.time)
       #if left click, activate the item to execute
        if event.button == 1 and path != None:
            self.iv_icon_activated(widget, path)
1
Ian B.