Como programar um indicador de um clique (adicionar funcionalidade de clique do meio)?

1

Sou bastante fluente na criação de indicadores de aplicativos com menus. No exemplo abaixo, há um item de menu (sair). Eu não teria problemas para adicionar outro item, meu aplicativo ou linha real para execução.

No entanto, quando estou tentando fazer é o item ser executado quando o ícone do indicador é clicado. Cada vez que o ícone do indicador for clicado, ele será executado. Para remover o ícone do indicador, o usuário clicará em sair.

Alguém pode me dizer onde colocar minha linha para executar o código?

Este é o código do indicador:

#!/usr/bin/python

import os
import signal
import subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk as gtk
gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as appindicator

APPINDICATOR_ID = 'appreveallauncher'


def main():
    indicator = appindicator.Indicator.new(APPINDICATOR_ID,
                                            os.path.abspath('sample_icon.svg'),
                                            appindicator.IndicatorCategory.SYSTEM_SERVICES)
    indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
    indicator.set_menu(build_menu())
    gtk.main()

def build_menu():
    menu = gtk.Menu()

    item_quit1 = gtk.MenuItem('Quit')
    item_quit1.connect('activate', quit)

    item_reveallauncher = gtk.MenuItem('Reveal Launcher')
    item_reveallauncher.connect('activate', reveallauncher)

    # This is my attempt to add the middle click functionality

    menu_items = gtk.MenuItem("Reveal Launcher Middle Click")
    menu.append(menu_items)
    menu_items.connect("activate", menu_items)
    menu_items.set_secondary_activate_target(menu_items)    


    menu.append(item_reveallauncher)
    menu.append(item_quit1)
    menu.show_all()
    return menu

def menu_items(_):
    subprocess.call("xdotool key alt+F1", shell=True) 


def reveallauncher(_):
    subprocess.call("xdotool key alt+F1", shell=True) 

def quit1(_):
    gtk.main_quit()


if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    main()

#   last = self.get_last_menuitem(self.app_menu) 
#   self.app.set_secondary_activate_target(last)

Aqui está a linha:

subprocess.call("xdotool key alt+F1", shell=True)

Este é o erro ao executar o código acima:

Traceback (most recent call last):
  File "/home/users/l/j/ljames/workspace/pythontest/src/basic.py", line 57, in <module>
    main()
  File "/home/users/l/j/ljames/workspace/pythontest/src/basic.py", line 19, in main
    indicator.set_menu(build_menu())
  File "/home/users/l/j/ljames/workspace/pythontest/src/basic.py", line 35, in build_menu
    menu_items.connect("activate", menu_items)
TypeError: second argument must be callable

O que estou tentando alcançar é que o Ubuntu Launcher seja revelado quando o indicador for clicado.

Atualizar

Atualizei meu exemplo de código acima para incluir as linhas da ação desejada. Sergiy Kolodyazhnyy indicou em sua resposta a resolução do clique do meio. Eu comentei as linhas necessárias na parte inferior. Agora estou tentando obter a sintaxe e a posição certas para essas linhas.

    
por L. D. James 01.07.2017 / 00:37

2 respostas

0

Para remover os erros e aplicar a funcionalidade middleclick ao código em questão (embora possa haver muitos métodos alternativos), adicionei um argumento à instrução build_menu no si principal de que a definição build_menu pode levar um argumento. Eu chamei esse argumento indicator . Em seguida, adicionou o método middleclick, set_secondary_activate_target() .

O código fixo:

#!/usr/bin/python

import os
import signal
import subprocess
import gi
from middleClick import reveallauncher
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk as gtk
gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as appindicator

APPINDICATOR_ID = 'appreveallauncher'

def main():
    indicator = appindicator.Indicator.new(APPINDICATOR_ID,
                os.path.abspath('sample_icon.svg'),
                appindicator.IndicatorCategory.SYSTEM_SERVICES)
    indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
    indicator.set_menu(build_menu(indicator))
    gtk.main()

def build_menu(indicator):
    menu = gtk.Menu()

    item_reveallauncher = gtk.MenuItem('Reveal Launcher')
    item_reveallauncher.connect('activate', reveallauncher)   
    indicator.set_secondary_activate_target(item_reveallauncher)

    item_quit = gtk.MenuItem('Quit')
    item_quit.connect('activate', quit)

    menu.append(item_reveallauncher)
    menu.append(item_quit)
    menu.show_all()
    return menu

def reveallauncher(_):
    subprocess.call("xdotool key alt+F1", shell=True) 

def quit(_):
    gtk.main_quit()

if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    main()

Existem vários exemplos de uso do método set_secondary_activate_target que pode ser encontrado pelas pesquisas do Google. No entanto, o problema que experimentei é que eles estão todos incluídos em um script complexo usado de várias linhas dependentes. Este é um esforço para colocá-lo em um exemplo mais simplificado para tornar mais fácil para a próxima pessoa tentando adaptá-lo ao seu código.

    
por L. D. James 05.07.2017 / 12:22
2

Resposta curta é que você não pode. Clicar no ícone do indicador só abre o menu. O que pode ser feito é definir o clique do meio (roda de rolagem) (nos touchpads que estão à direita e clique com o botão esquerdo pressionado juntos), o que é feito definindo o alvo de ativação secundário do objeto indicador.

Aqui está um exemplo de algo que eu uso dentro do meu próprio indicador da lista de lançadores nas linhas 152 e 153:

152         last = self.get_last_menuitem(self.app_menu)
153         self.app.set_secondary_activate_target(last)

Quando o usuário pressiona o botão do meio sobre o item idicator, ele ativará o item de menu específico sem baixar o menu.

O que você também pode fazer como alternativa é usar eventos de rolagem, algo assim:

86         self.app.connect("scroll-event", self.set_next)
    
por Sergiy Kolodyazhnyy 01.07.2017 / 00:51