GNU/Linux >> LINUX-Kenntnisse >  >> Ubuntu

Wie schreibe ich eine dynamisch aktualisierte Panel-App / einen Indikator?

Ich versuche, einige Panel-Apps für Ubuntu Mate zu schreiben.
Ich kenne C/C++ und SDL ziemlich gut.
Ich habe die Github-Seite für Panel-Apps der Mate-University gesehen, aber ich bekomme sie nicht zum Laufen richtig / Ich habe eine schöne Zeit damit.

Ich frage mich nur, ob es einen einfachen Weg gibt, Panel-Apps zu schreiben? Ich spreche nicht von der Verwendung des benutzerdefinierten Anwendungsstarters, ich möchte dem Bedienfeld neue Funktionen hinzufügen, bin mir aber nicht sicher, wie. Ein Tutorial oder eine Beschreibung zum Schreiben von Panel-Apps könnte sehr hilfreich sein.

Beste Antwort

Da die Gelegenheit, diese Frage zu stellen, bereits eine Antwort zu sein scheint, beantworte ich diese Frage als erweiterte Erklärung, wie es gemacht wurde (in python )

Basis statisch Indikator

Da Ubuntu Mate ab 15,10 Indikatoren unterstützt, gibt es keinen großen Unterschied zwischen dem Schreiben eines Indikators und einer Panel-App für Mate. Daher ist dieser Link ein guter Ausgangspunkt für einen einfachen Indikator in python , mit dem AppIndicator3 API. Der Link ist ein netter Anfang, liefert aber keine Informationen darüber, wie Text auf dem Indikator angezeigt wird, geschweige denn, wie er aktualisiert wird der Text (oder das Symbol). Mit einigen Ergänzungen führt dies jedoch zu einem grundlegenden „Rahmen“ eines Indikators wie unten. Es zeigt ein Symbol, eine Textbezeichnung und ein Menü:

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

In der Zeile AppIndicator3.IndicatorCategory.OTHER , die Kategorie ist definiert, wie in diesem (teilweise veralteten) Link erklärt. Das Setzen der richtigen Kategorie ist wichtig, u.a. um den Indikator an einer geeigneten Position im Panel zu platzieren.

Die größte Herausforderung; wie man den Indikatortext und/oder das Symbol aktualisiert

Die eigentliche Herausforderung besteht nicht darin, einen einfachen Indikator zu schreiben, sondern wie er regelmäßig aktualisiert wird den Text und/oder das Symbol Ihres Indikators, da Sie möchten, dass er die (Text-) Zeit anzeigt. Damit der Indikator richtig funktioniert, können wir nicht einfach threading verwenden um einen zweiten Prozess zu starten, um die Schnittstelle regelmäßig zu aktualisieren. Nun, eigentlich können wir das, aber auf längere Sicht führt das zu Konflikten, wie ich herausgefunden habe.

Hier ist GObject reinkommt, wie es in diesem (ebenfalls veralteten) Link steht:

Verwandte:Wie kann man ASCII-Kunst oben im Terminal anzeigen, wenn es geöffnet ist?

Rufen Sie gobject.threads_init() auf bei der Anwendungsinitialisierung. Dann starten Sie Ihre Threads normal, aber stellen Sie sicher, dass die Threads niemals GUI-Aufgaben direkt ausführen. Stattdessen verwenden Sie gobject.idle_add GUI-Task zur Ausführung im Haupt-Thread zu planen

Wenn wir gobject.threads_init() ersetzen von GObject.threads_init() und gobject.idle_add durch GObject.idle_add() , haben wir so ziemlich die aktualisierte Version, wie Threads in einem Gtk ausgeführt werden Anwendung. Ein vereinfachtes Beispiel, das eine zunehmende Anzahl von Affen zeigt:

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

Das ist das Prinzip. Im eigentlichen Indikator in dieser Antwort wurden sowohl die Schleifenzeit als auch der Indikatortext von einem sekundären Modul bestimmt, das in das Skript importiert wurde, aber die Hauptidee ist dieselbe.


Ubuntu
  1. So installieren Sie Indicator SysMonitor unter Ubuntu und Debian

  2. Wie erteile ich Schreibberechtigungen in Samba?

  3. Wie listet man Gnome-Control-Center-Panel-Namen auf?

  4. Wie füge ich Indikator-datetime zum Panel hinzu?

  5. Wie lösche ich das Gnome-Panel?

So installieren Sie das Ajenti Control Panel unter Ubuntu 14.04

So installieren Sie das Vesta Control Panel unter Ubuntu 14.04

So schreiben Sie eine für Mobilgeräte optimierte App mit JQuery und Bootstrap

Wie wird das Uhranzeigeformat angepasst?

Wie lege ich den Titel des Terminals in der Taskleiste (Panel) fest?

So installieren Sie die CloudPanel-Systemsteuerung unter Ubuntu 20.04