GNU/Linux >> Tutoriels Linux >  >> Ubuntu

Comment écrire une application / un indicateur de panneau mis à jour dynamiquement ?

J'essaie d'écrire des applications de panneau pour ubuntu Mate.
Je connais assez bien C/C++ et SDL.
J'ai vu la page github des applications de panneau Mate-University, mais je n'arrive pas à la faire fonctionner correctement / J'ai du mal avec ça.

Je me demande simplement s'il existe un moyen simple d'écrire des applications de panneau ? Je ne parle pas d'utiliser le lanceur d'applications personnalisé, j'aimerais ajouter de nouvelles fonctionnalités au panneau, mais je ne sais pas comment le faire. Un didacticiel ou une description de l'écriture d'applications de panneau pourrait être très utile.

Meilleure réponse

Puisque ce qui semble être l'occasion de poser cette question a déjà une réponse, je réponds à cette question comme une explication détaillée sur la façon dont cela a été fait (en python )

Basique statique indicateur

Étant donné qu'Ubuntu Mate, à partir de 15,10, prend en charge les indicateurs, il n'y a pas beaucoup de différence entre écrire un indicateur et une application de panneau pour Mate. Par conséquent, ce lien est un bon point de départ pour un indicateur de base en python , en utilisant AppIndicator3 API. Le lien est un bon début, mais ne fournit aucune information sur la façon d'afficher le texte sur l'indicateur, et encore moins sur la façon de mettre à jour le texte (ou l'icône). Néanmoins, avec quelques ajouts, cela conduit à un "cadre" de base d'un indicateur comme ci-dessous. Il affichera une icône, une étiquette de texte et un menu :

#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3

class Indicator():
    def __init__(self):
        self.app = 'test123'
        iconpath = "//eadn-wc01-5196795.nxedge.io/opt/abouttime/icon/indicator_icon.png"
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)       
        self.indicator.set_menu(self.create_menu())
        self.indicator.set_label("1 Monkey", self.app)

    def create_menu(self):
        menu = Gtk.Menu()
        # menu item 1
        item_1 = Gtk.MenuItem('Menu item')
        # item_about.connect('activate', self.about)
        menu.append(item_1)
        # separator
        menu_sep = Gtk.SeparatorMenuItem()
        menu.append(menu_sep)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        menu.append(item_quit)

        menu.show_all()
        return menu

    def stop(self, source):
        Gtk.main_quit()

Indicator()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()

Dans la ligne AppIndicator3.IndicatorCategory.OTHER , la catégorie est définie, comme expliqué dans ce lien (partiellement obsolète). Définir la bonne catégorie est important, a.o. pour placer l'indicateur dans une position appropriée dans le panneau.

Le principal défi ; comment mettre à jour le texte et/ou l'icône de l'indicateur

Le véritable défi n'est pas de savoir comment écrire un indicateur de base, mais comment le mettre à jour périodiquement le texte et/ou l'icône de votre indicateur, car vous souhaitez qu'il affiche l'heure (textuelle). Pour que l'indicateur fonctionne correctement, nous ne pouvons pas simplement utiliser le threading pour démarrer un second processus de mise à jour périodique de l'interface. Eh bien, en fait, nous le pouvons, mais à plus long terme, cela conduira à des conflits, comme je l'ai découvert.

Voici où GObject arrive, à, comme il est mis dans ce lien (également obsolète):

En relation:Comment afficher l'art ascii en haut du terminal lorsqu'il est ouvert?

appeler gobject.threads_init() à l'initialisation de l'application. Ensuite, vous lancez vos threads normalement, mais assurez-vous que les threads n'effectuent jamais de tâches d'interface graphique directement. Au lieu de cela, vous utilisez gobject.idle_add pour programmer la tâche de l'interface graphique à exécuter dans le thread principal

Lorsque nous remplaçons gobject.threads_init() par GObject.threads_init() et gobject.idle_add par GObject.idle_add() , nous avons à peu près la version mise à jour de la façon d'exécuter les threads dans un Gtk application. Un exemple simplifié, montrant un nombre croissant de singes :

#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread

class Indicator():
    def __init__(self):
        self.app = 'test123'
        iconpath = "//eadn-wc01-5196795.nxedge.io/opt/abouttime/icon/indicator_icon.png"
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)       
        self.indicator.set_menu(self.create_menu())
        self.indicator.set_label("1 Monkey", self.app)
        # the thread:
        self.update = Thread(target=self.show_seconds)
        # daemonize the thread to make the indicator stopable
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        menu = Gtk.Menu()
        # menu item 1
        item_1 = Gtk.MenuItem('Menu item')
        # item_about.connect('activate', self.about)
        menu.append(item_1)
        # separator
        menu_sep = Gtk.SeparatorMenuItem()
        menu.append(menu_sep)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        menu.append(item_quit)

        menu.show_all()
        return menu

    def show_seconds(self):
        t = 2
        while True:
            time.sleep(1)
            mention = str(t)+" Monkeys"
            # apply the interface update using  GObject.idle_add()
            GObject.idle_add(
                self.indicator.set_label,
                mention, self.app,
                priority=GObject.PRIORITY_DEFAULT
                )
            t += 1

    def stop(self, source):
        Gtk.main_quit()

Indicator()
# this is where we call GObject.threads_init()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()

C'est le principe. Dans l'indicateur réel de cette réponse, le temps de boucle et le texte de l'indicateur ont été déterminés par un module secondaire, importé dans le script, mais l'idée principale est la même.


Ubuntu
  1. Comment installer Indicator SysMonitor sur Ubuntu et Debian

  2. Comment accorder des autorisations d'écriture dans Samba ?

  3. Comment répertorier les noms des panneaux Gnome-control-center ?

  4. Comment ajouter un indicateur-datetime au panneau ?

  5. Comment supprimer le panneau Gnome ?

Comment installer le panneau de configuration Ajenti sur Ubuntu 14.04

Comment installer le panneau de configuration Vesta sur Ubuntu 14.04

Comment écrire une application adaptée aux mobiles à l'aide de JQuery et Bootstrap

Comment régler le format de l'indicateur d'horloge ?

Comment définir le titre du terminal sur la barre des tâches (panneau) ?

Comment installer le panneau de configuration CloudPanel sur Ubuntu 20.04