web-dev-qa-db-fra.com

Comment programmer un indicateur en un clic (ajouter une fonctionnalité de clic central)?

Je maîtrise assez bien la création d'indicateurs d'application avec des menus. Dans l'exemple ci-dessous, il y a un élément de menu (quitter). Je n'aurais aucun problème à ajouter un autre élément, mon application réelle ou une ligne à exécuter.

Cependant, lorsque j'essaie de faire, c'est d'exécuter l'élément lorsque vous cliquez sur l'icône d'indicateur. Chaque fois que l'icône d'indicateur est cliquée, elle s'exécute. Pour supprimer l'icône d'indicateur, l'utilisateur cliquera sur Quitter.

Quelqu'un peut-il me dire où mettre ma ligne à exécuter dans le code?

Ceci est le code indicateur:

#!/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)

Voici la ligne:

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

C'est l'erreur lors de l'exécution du code ci-dessus:

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

Ce que j'essaie de réaliser, c'est que le lanceur Ubuntu s'affiche lorsque l'utilisateur clique sur l'indicateur.

Mise à jour

J'ai mis à jour mon exemple de code ci-dessus pour inclure les lignes de l'action souhaitée. Sergiy Kolodyazhnyy a indiqué dans sa réponse la résolution du clic du milieu. J'ai commenté les lignes nécessaires en bas. Maintenant, j'essaie d'obtenir la bonne syntaxe et la bonne position pour ces lignes.

1
L. D. James

Pour supprimer les erreurs et appliquer la fonctionnalité middleclick au code en question (bien qu'il puisse y avoir de nombreuses méthodes alternatives), j'ai ajouté un argument à l'instruction build_menu Dans le si principal que la définition build_menu peut prendre un argument. J'ai appelé cet argument indicator. Puis ajouté la méthode middleclick, set_secondary_activate_target().

Le code fixe:

#!/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()

Il existe un certain nombre d'exemples d'utilisation de la méthode set_secondary_activate_target Qui peuvent être trouvés par les recherches Google. Cependant, le problème que j'ai rencontré est qu'ils sont tous inclus dans un script complexe utilisé à la manière de nombreuses lignes dépendantes. C'est un effort pour le mettre dans un exemple le plus simplifié pour le rendre plus facile pour la prochaine personne essayant de l'adapter à son code.

0
L. D. James

La réponse courte est que vous ne pouvez pas. Cliquer sur l'icône de l'indicateur fait seulement apparaître le menu. Ce qui peut être fait est de définir le clic du milieu (molette de défilement) (sur les pavés tactiles sur lesquels le clic droit et le clic gauche sont pressés ensemble), ce qui est fait en définissant la cible d'activation secondaire de l'objet indicateur.

Voici un exemple de quelque chose que j'utilise dans mon propre launcher-list-indicator aux lignes 152 et 153:

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

Lorsque l'utilisateur appuie sur le bouton du milieu sur l'élément idicator, il activera l'élément de menu spécifique sans abaisser le menu.

Ce que vous pouvez également faire comme alternative, c'est d'utiliser des événements de défilement, quelque chose comme ça:

86         self.app.connect("scroll-event", self.set_next)
2