Como fazer um Gtk.Iconview reagir ao único clique em vez de clicar duas vezes?

6

Eu uso um widget Gtk.IconView no meu aplicativo para selecionar diferentes tipos de elementos. A maneira como o IconView funciona é a seguinte:

  • Clique para selecionar o item
  • Faça um clique duplo adicional para ativar o item

Eu sempre achei confuso que um duplo clique adicional seja necessário, quando a maioria dos widgets semelhantes a botões na área de trabalho requer apenas um único clique. Agora, acabei de receber comentários de alguns usuários que acham que é confuso (alguém achou que era um erro clicar no botão "não fez nada"), então decidi investigar como mudar esse comportamento.

Idealmente, gostaria que o IconView se comportasse da seguinte forma:

  • Passe o mouse para selecionar um item (opcional)
  • Clique único ativa o item

Agora eu não encontrei nada óbvio nas propriedades do widget para fazê-lo se comportar assim. Alguém sabe como ou se isso poderia ser alcançado?

    
por David Planella 30.05.2012 / 23:38

4 respostas

5

Uma solução (mas apenas para a ativação de um único clique) é o motivo de usar o sinal selection_changed do IconView (porque a seleção do IconView é baseada em um único clique).

Um exemplo que pressupõe um sinal de trabalho on_item_activated seria:

def on_icon_view_selection_changed(self, widget):
        self.on_item_activated(widget, widget.get_selected_items()[0])
    
por xubuntix 05.06.2012 / 19:50
2

Um GtkIconView não é um arranjo de widgets de botão em uma tabela. É basicamente um caso especial do GtkTreeView, com itens dispostos em uma grade, ao invés de uma lista / árvore. Para destacar os itens em foco, acredito que um patch para o GTK + seria necessário. Um patch também seria necessário para adicionar API para permitir clique único ou duplo clique para ativar, no entanto, esse recurso pode ser implementado no topo da API de widget existente, ouvindo o sinal button_press_event no widget e agindo de acordo.

    
por dobey 30.05.2012 / 23:43
1

Você parece explorar as limitações do Gtk ultimamente: -)

Em primeiro lugar, a resposta do dobeys parece correta.

Lojas de árvore e de listas são uma boa opção para coleções. Quantidades maiores de dados que são idênticos em tipos, mas diferentes em meta-conteúdo (por exemplo, uma coleção de músicas em que cada peça tem um artista, álbum, título, mas o nome real do artista, nome do álbum, nome do título muda).

O bom desses widgets é que eles são facilmente classificáveis, muitos itens podem ser selecionados (por exemplo, no modo 'rubber-band') e você precisa de poucas linhas de código para adicionar milhares de itens semelhantes.

Alterar a maneira como um TreeView ou ListView se comporta como cliques / passar o mouse, etc. em um nível por aplicativo é uma má ideia, pois mexe com o modo como os usuários esperam seu aplicativo comportar-se. Você descobriu isso com base na reação que descreve em sua pergunta.

Seu problema, no entanto, é que os usuários não entenderam que seu widget é um TreeView / ListView, em vez disso, eles pensaram que eles são um número de botões. E isso parece fazer sentido, com base na sua captura de tela.

Os botões destinam-se a iniciar uma ação (por exemplo, parar, reproduzir, pausar) ou comunicar-se com o programa (por exemplo, Ok, Cancelar) ou até mesmo atuar como um link para uma visualização diferente (consulte LinkButton). Eles normalmente não têm um objeto ou item (abstrato) associado a ele (por exemplo, "Sammy Davis Jr", de "Movits!", Do álbum "Out of my head").

Assim, embora o comportamento de cliques não configurável seja uma falha do gtk, ele deve, de qualquer maneira, estar apenas em um nível global por usuário.

O que você deseja é provavelmente uma grade com Botões . (Botões também podem conter ícones).

    
por xubuntix 31.05.2012 / 09:52
1

Veja como eu fiz meu Iconview responder à posição do ponteiro para obter um efeito de foco e ações de um único clique e clique com o botão direito do mouse.

Você precisa ativar pointer-motion-notify para o widget e, em seguida, converter a posição x, y do ponteiro para o caminho do iconview:

...
    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)
    
por Ian B. 23.07.2012 / 18:50