GNU/Linux >> Tutoriales Linux >  >> Ubuntu

¿Cómo escribir una aplicación/indicador de panel actualizado dinámicamente?

Estoy tratando de escribir algunas aplicaciones de panel para ubuntu Mate.
Conozco C/C++ y SDL razonablemente bien.
He visto la página de github de aplicaciones de panel de Mate-University, pero no puedo hacer que funcione correctamente / Estoy teniendo un tiempo con eso.

Me pregunto si hay alguna vía fácil para escribir aplicaciones de panel. No estoy hablando de usar el iniciador de aplicaciones personalizado, me gustaría agregar una nueva funcionalidad al panel, pero no estoy seguro de cómo hacerlo. Un tutorial o una descripción sobre cómo escribir aplicaciones de panel podría ser muy útil.

Mejor respuesta

Dado que lo que parece ser la ocasión para hacer esta pregunta ya tiene una respuesta, respondo esta pregunta como una explicación extendida sobre cómo se hizo (en python )

Básico estático indicador

Dado que Ubuntu Mate, desde 15,10, admite indicadores, no hay mucha diferencia entre escribir un indicador y una aplicación de panel para Mate. Por lo tanto, este enlace es un buen punto de partida para un indicador básico en python , usando el AppIndicator3 API. El enlace es un buen comienzo, pero no proporciona ninguna información sobre cómo mostrar texto en el indicador, y mucho menos sobre cómo actualizar. el texto (o icono). Sin embargo, con algunas adiciones, esto conduce a un "marco" básico de un indicador como se muestra a continuación. Mostrará un icono, una etiqueta de texto y un 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()

En la línea AppIndicator3.IndicatorCategory.OTHER , la categoría está definida, como se explica en este enlace (parcialmente desactualizado). Establecer la categoría correcta es importante, entre otros. para colocar el indicador en una posición adecuada en el panel.

El principal desafío; cómo actualizar el texto y/o el icono del indicador

El verdadero desafío no es cómo escribir un indicador básico, sino cómo actualizar periódicamente el texto y/o icono de su indicador, ya que desea que muestre la hora (textual). Para que el indicador funcione correctamente, no podemos simplemente usar threading para iniciar un segundo proceso para actualizar periódicamente la interfaz. Bueno, en realidad podemos, pero a más largo plazo, conducirá a conflictos, como descubrí.

Aquí es donde GObject viene en, a, como se pone en este enlace (también desactualizado):

Relacionado:¿Cómo mostrar arte ascii en la parte superior de la terminal cuando está abierta?

llamar a gobject.threads_init() en la inicialización de la aplicación. Luego, inicia sus subprocesos normalmente, pero asegúrese de que los subprocesos nunca realicen ninguna tarea de GUI directamente. En su lugar, usa gobject.idle_add para programar la tarea GUI para que se ejecute en el hilo principal

Cuando reemplazamos gobject.threads_init() por GObject.threads_init() y gobject.idle_add por GObject.idle_add() , prácticamente tenemos la versión actualizada de cómo ejecutar subprocesos en un Gtk solicitud. Un ejemplo simplificado que muestra un número creciente de monos:

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

Ese es el principio. En el indicador real de esta respuesta, tanto el tiempo de ciclo como el texto del indicador fueron determinados por un módulo secundario, importado en el script, pero la idea principal es la misma.


Ubuntu
  1. Cómo instalar el indicador SysMonitor en Ubuntu y Debian

  2. ¿Cómo otorgar permisos de escritura en Samba?

  3. ¿Cómo enumerar los nombres del panel del centro de control de Gnome?

  4. ¿Cómo agregar indicador de fecha y hora al panel?

  5. ¿Cómo eliminar el panel de Gnome?

Cómo instalar el panel de control de Ajenti en Ubuntu 14.04

Cómo instalar el panel de control de Vesta en Ubuntu 14.04

Cómo escribir una aplicación compatible con dispositivos móviles usando JQuery y Bootstrap

¿Cómo ajustar el formato del indicador del reloj?

¿Cómo configurar el título del terminal en la barra de tareas (panel)?

Cómo instalar el panel de control de CloudPanel en Ubuntu 20.04