GNU/Linux >> Znalost Linux >  >> Ubuntu

Jak napsat dynamicky aktualizovanou panelovou aplikaci / indikátor?

Snažím se napsat nějaké panelové aplikace pro ubuntu Mate.
Znám C/C++ a SDL poměrně dobře.
Viděl jsem stránku panelových aplikací Mate-University github, ale nemohu ji zprovoznit správně / Mám s tím čas.

Jen by mě zajímalo, jestli existuje nějaká snadná cesta k psaní panelových aplikací? Nemluvím o použití vlastního spouštěče aplikací, rád bych do panelu přidal novou funkcionalitu, ale nejsem si jistý, jak na to. Výukový program nebo popis psaní panelových aplikací může být opravdu užitečný.

Nejlepší odpověď

Vzhledem k tomu, že to, co se zdá být příležitostí položit tuto otázku, již má odpověď, odpovídám na tuto otázku jako rozšířené vysvětlení toho, jak to bylo provedeno (v python )

Základní statické indikátor

Vzhledem k tomu, že Ubuntu Mate od 15,10 podporuje indikátory, není velký rozdíl mezi psaním indikátoru a panelovou aplikací pro Mate. Proto je tento odkaz dobrým výchozím bodem pro základní indikátor v python pomocí AppIndicator3 API. Odkaz je pěkný začátek, ale neposkytuje žádné informace o tom, jak zobrazit text na indikátoru, natož jak jej aktualizovat text (nebo ikonu). Nicméně s několika dodatky to vede k základnímu „rámci“ indikátoru, jak je uvedeno níže. Zobrazí se ikona, textový štítek a nabídka:

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

V řádku AppIndicator3.IndicatorCategory.OTHER , je kategorie definována, jak je vysvětleno v tomto (částečně zastaralém) odkazu. Nastavení správné kategorie je důležité, a.o. umístěte indikátor na vhodné místo na panelu.

Hlavní výzva; jak aktualizovat text indikátoru a/nebo ikonu

Skutečnou výzvou není, jak napsat základní indikátor, ale jak jej pravidelně aktualizovat text a/nebo ikona vašeho indikátoru, protože chcete, aby zobrazoval (textový) čas. Aby indikátor fungoval správně, nemůžeme jednoduše použít threading spustit druhý proces pro pravidelnou aktualizaci rozhraní. No, vlastně můžeme, ale z dlouhodobého hlediska to povede ke konfliktům, jak jsem zjistil.

Zde je GObject přichází, do, jak je uvedeno v tomto (také zastaralém) odkazu:

Související:Jak zobrazit ascii art v horní části terminálu, když je otevřen?

volání gobject.threads_init() při inicializaci aplikace. Poté svá vlákna spustíte normálně, ale ujistěte se, že vlákna nikdy neprovádějí přímo žádné úlohy GUI. Místo toho použijete gobject.idle_add naplánovat provedení úlohy GUI v hlavním vláknu

Když nahradíme gobject.threads_init() pomocí GObject.threads_init() a gobject.idle_add pomocí GObject.idle_add() , v podstatě máme aktualizovanou verzi, jak spouštět vlákna v Gtk aplikace. Zjednodušený příklad ukazující rostoucí počet opic:

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

To je princip. Ve skutečném indikátoru v této odpovědi byly jak doba smyčky, tak text indikátoru určeny sekundárním modulem importovaným do skriptu, ale hlavní myšlenka je stejná.


Ubuntu
  1. Jak udělit oprávnění k zápisu v Sambě?

  2. Jak přidat indikátor-datetime na panel?

  3. Jak odstranit panel Gnome?

  1. Jak používat aplety indikátorů v prostředí GNOME

  2. Jak nainstalovat Indicator SysMonitor na Ubuntu a Debian

  3. Jak vypsat názvy panelů Gnome-control-center?

  1. Jak nainstalovat WSL 2 na Windows 10 (aktualizováno)

  2. Jak nainstalovat ReactJS na Ubuntu 20.04

  3. Jak nainstalovat aplikaci Signal Messaging na Ubuntu 20.04