GNU/Linux >> Linux Esercitazione >  >> Ubuntu

Come scrivere un'app / indicatore del pannello aggiornato dinamicamente?

Sto cercando di scrivere alcune app del pannello per Ubuntu Mate.
Conosco C/C++ e SDL abbastanza bene.
Ho visto la pagina github delle app del pannello Mate-University, ma non riesco a farlo funzionare correttamente / Sto avendo un po' di tempo con esso.

Mi chiedo solo se esiste una strada facile per scrivere app di pannelli? Non sto parlando dell'utilizzo del programma di avvio delle applicazioni personalizzato, vorrei aggiungere nuove funzionalità al pannello, ma non sono sicuro di come farlo. Un tutorial o una descrizione sulla scrittura di app del pannello potrebbero essere davvero utili.

Migliore risposta

Poiché quella che sembra essere l'occasione per porre questa domanda ha già una risposta, sto rispondendo a questa domanda come una spiegazione estesa su come è stato fatto (in python )

Base statico indicatore

Poiché Ubuntu Mate, da 15,10, supporta gli indicatori, non c'è molta differenza tra la scrittura di un indicatore e un'app di pannello per Mate. Pertanto, questo collegamento è un buon punto di partenza per un indicatore di base in python , utilizzando AppIndicator3 API. Il collegamento è un buon inizio, ma non fornisce alcuna informazione su come mostrare il testo sull'indicatore, per non parlare di come aggiornare il testo (o l'icona). Tuttavia, con alcune aggiunte, ciò porta a una "cornice" di base di un indicatore come di seguito. Mostrerà un'icona, un'etichetta di testo e 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()

Nella riga AppIndicator3.IndicatorCategory.OTHER , la categoria è definita, come spiegato in questo link (parzialmente obsoleto). Impostare la categoria giusta è importante, a.o. per posizionare l'indicatore in una posizione appropriata nel pannello.

La sfida principale; come aggiornare il testo e/o l'icona dell'indicatore

La vera sfida non è come scrivere un indicatore di base, ma come aggiornare periodicamente il testo e/o l'icona del tuo indicatore, poiché vuoi che mostri l'ora (testuale). Per far funzionare correttamente l'indicatore, non possiamo semplicemente usare il threading per avviare un secondo processo di aggiornamento periodico dell'interfaccia. Bene, in realtà possiamo, ma su un periodo più lungo, porterà a conflitti, come ho scoperto.

Ecco dove GObject entra, a, come è messo in questo (anche obsoleto) link:

Correlati:come mostrare l'arte ascii nella parte superiore del terminale quando è aperto?

chiama gobject.threads_init() all'inizializzazione dell'applicazione. Quindi avvii i thread normalmente, ma assicurati che i thread non eseguano mai direttamente attività della GUI. Invece, usi gobject.idle_add per pianificare l'esecuzione dell'attività della GUI nel thread principale

Quando sostituiamo gobject.threads_init() da GObject.threads_init() e gobject.idle_add da GObject.idle_add() , abbiamo praticamente la versione aggiornata di come eseguire i thread in un Gtk applicazione. Un esempio semplificato, che mostra un numero crescente di scimmie:

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

Questo è il principio. Nell'indicatore effettivo in questa risposta, sia il tempo di ciclo che il testo dell'indicatore sono stati determinati da un modulo secondario, importato nello script, ma l'idea principale è la stessa.


Ubuntu
  1. Come installare Indicator SysMonitor su Ubuntu e Debian

  2. Come concedere autorizzazioni di scrittura in Samba?

  3. Come elencare i nomi dei pannelli del centro di controllo di Gnome?

  4. Come aggiungere Indicator-datetime al pannello?

  5. Come eliminare il pannello di Gnome?

Come installare il pannello di controllo Ajenti su Ubuntu 14.04

Come installare il pannello di controllo Vesta su Ubuntu 14.04

Come scrivere un'app ottimizzata per dispositivi mobili utilizzando JQuery e Bootstrap

Come regolare il formato dell'indicatore dell'orologio?

Come impostare il titolo del terminale sulla barra delle applicazioni (pannello)?

Come installare il pannello di controllo di CloudPanel su Ubuntu 20.04