Wie programmiere ich ein Statussymbol, das sowohl in Ubuntu als auch in anderen Distributionen angezeigt wird?

23

Die betreffende Anwendung führt eine Aktion aus (hier Verbinden von Audio mit Netzwerkströmen) und wird minimiert ausgeführt, wenn diese Aktionen erfolgreich waren. Daher wird ein Statussymbol benötigt, um den Status der Verbindung anzuzeigen (z. B. VERBUNDEN / NICHT VERBUNDEN). Erst wenn Sie auf das Symbol klicken, wird das Anwendungsfenster geöffnet, in dem Sie auf weitere Optionen zugreifen können.

Mit Python 2.6 und pyGtk habe ich dies bequem mit gtk_status_icon realisiert . Ich habe die Anwendung absichtlich so geschrieben, dass sie auf möglichst vielen Distributionen läuft, einschließlich der verschiedenen Ubuntu-Versionen. Ich habe darauf geachtet, mögliche Abhängigkeiten erst zu verwenden, nachdem der Benutzer sie installiert hat.

Jetzt höre ich jedoch, dass gtk_status_icon in zukünftigen Ubuntu-Versionen nicht mehr unterstützt wird. Entwickler werden gebeten, stattdessen Anwendungsindikatoren zu verwenden. Was ist dann die beste Vorgehensweise, um sicherzustellen, dass:

  1. Die lokalen Symbole der Anwendung werden ordnungsgemäß angezeigt
  2. Die Anwendung wird weiterhin ausgeführt und zeigt ihre Symbole in zukünftigen Ubuntu-Versionen an.
  3. Die Anwendung wird auch ausgeführt und zeigt ihre Symbole in anderen Umgebungen an, in denen Indikator-Applet , Libappindicator und Python-Appindicator nicht bereitgestellt werden.

Anwendungsindikator-Fallback-Mechanismen für gtk_status_icon funktionieren nicht, wenn das Indikator-Applet nicht ausgeführt wird. Python-Interpreter werden nicht ausgeführt, wenn kein Appindicator- Modul zum Import vorhanden ist. Muss ich verschiedene Versionen für verschiedene Distributionen entwickeln oder gibt es einen besseren Weg, dies zu umgehen?

Wo finde ich eine andere Dokumentation zur Verwendung von ApplicationIndicator als im Beispiel im Ubuntu-Wiki ? Welche Befehle werden bereitgestellt, um zu überprüfen, ob das Anzeige-Applet ausgeführt wird, um zu vermeiden, dass unterschiedliche Quellcodes für Ubuntu-Distributionen im Vergleich zu Nicht-Ubuntu-Distributionen programmiert werden?

Takkat
quelle

Antworten:

16

Ich denke, dass das Bedürfnis hier eigentlich eher die Bestimmung der Python-Appindicator-Bibliothek ist. Wenn es vorhanden ist, werden alle von Ihnen benötigten Fallback-Fälle unterstützt. Es wird XFCE, KDE und älteres GNOME angemessen behandeln. Gutes Beispiel dafür, wie es in dieser Antwort gemacht wird .

Die Anwendungsindikatorbibliothek verwendet DBus, um zu überprüfen, ob der Anwendungsindikator-Rendervorgang verfügbar ist. Dies ist bei Unity der Fall oder wenn das Indikator-Applet ausgeführt wird. Wenn es verfügbar ist, wird es das verwenden, wenn nicht, wird es auf die Verwendung eines GtkStatusIcon mit demselben Menü zurückgreifen.

Leider glaube ich, dass Sie beide Codepfade beibehalten müssen, wenn Sie den Fall behandeln möchten, dass die Bibliothek nicht verfügbar ist. Wir würden uns freuen, die Bibliothek in anderen Distributionen zu finden :)

Ted Gould
quelle
Vielen Dank für diese sehr klare Antwort. Dies zeigt auf den Pfad, den ich gehen muss, wenn meine App in 11.04 ausgeführt werden soll. Ich habe einen Arbeitspfad für GtkStatusIcon, muss aber das Ganze für das Indikator-Applet neu entwickeln. Wenn ich Ihren Kommentar zum Fehler # 668375 verstanden habe, kann ich möglicherweise meine lokalen Symbole verwenden, ohne ein vollständiges Symbol-Design erstellen zu müssen.
Takkat
Nachdem ich die Zeit hatte, mich mit der AppIndicator-Programmierung zu beschäftigen, stellte ich fest, dass die Verwendung des Vorschlags von jgoguen zur Überprüfung des Appindicator-Moduls nicht wirklich hilfreich ist, da benutzerdefinierte Symbole in 10.04 LTS nicht gerendert werden. Siehe meine Kommentare zu Fehler # 668375.
Takkat
Meine Antwort beinhaltet einen sehr einfachen Weg, um dieses Problem zu lösen. Es hat sehr gut für meine App funktioniert und es ist sogar schmerzlos geworden, eine App, die AppIndicators verwendet, auf Windows zu portieren!
Nathan Osman
10

Ich habe eine hervorragende Lösung, die in StackApplet gut funktioniert hat : Ich habe eine funktionsäquivalente Version des appindicatorModuls erstellt, die gtk.StatusIconintern identische Funktionen bereitstellt, wenn das eigentliche Modul nicht vorhanden ist.

Die Benutzung ist so einfach wie:

  1. Laden Sie die folgende Datei herunter und rufen Sie sie aufappindicator_replacement.py
  2. Fügen Sie Ihrer Bewerbung Folgendes hinzu:

    try:
        import appindicator
    except ImportError:
        import appindicator_replacement as appindicator
    

Das ist es! Jetzt läuft Ihre Anwendung perfekt mit oder ohne Unterstützung für AppIndicators. Es läuft sogar unter Windows, vorausgesetzt, Sie haben keinen anderen plattformspezifischen Code.


Hinweis: Die Datei ist unter der MIT-Lizenz veröffentlicht - Sie können sie also für so ziemlich alles verwenden.

Nathan Osman
quelle
9

Sie müssen Code für beide schreiben. Sie können das Vorhandensein von appindicator in Ihrem Python-Code mit etwas ähnlichem feststellen:

have_appindicator = True
try:
    import appindicator
except:
    have_appindicator = False

Verwenden Sie von dort aus have_appindicator, um zu entscheiden, ob Sie den appindicator-Code oder den gtk_status_icon-Code verwenden möchten.

Leider bedeutet dies auch, dass Sie sowohl Ubuntu als auch eine andere Umgebung zum Testen benötigen.

jgoguen
quelle
1
Es kann jedoch Umgebungen geben, in denen Python-Appindicator installiert ist, das Indikator-Applet jedoch nicht ausgeführt wird. Die Anwendung müsste auch damit umgehen.
Takkat
Für diesen Fall siehe wiki.ubuntu.com/DesktopExperienceTeam/ApplicationIndicators > Custom Fallbacks. Standardmäßig erhalten Sie ein gtk.StatusIcon für den Anwendungsindikator, wenn kein Indikator-Applet vorhanden ist.
htorque
Mir ist die Fallback-Option bekannt. Was ich nicht verstehe ist, wenn das Indikator-Applet nicht ausgeführt wird, wie kann das Indikator-Applet einen Fallback bereitstellen?
Takkat
Ich stelle mir vor, dass es einfach nach Indikator-Applets sucht und hinter den Kulissen die Funktionalität von gtk_status_icon bietet.
JGOGUEN
1
@jgoguen: was ist "es"? Ich verstehe , dass von 11.04 Ubuntu / Einheit wird nicht mehr unterstützt gtk_status_icon. Andere Distributionen haben möglicherweise nicht "es". Ich mache mir wirklich Sorgen.
Takkat
3
for line in os.popen("ps xa"): 
fields = line.split() 
pid = fields[0] 
process = fields[4]

applet_is_running = ( process.find('indicator-applet') > 0 )

Auf diese Weise können Sie feststellen, ob das Indikator-Applet ausgeführt wird. Sie müssen sich keine Sorgen um Ubuntu 11.04 machen, da dies nicht der Fall sein wird. Es gibt kein Fallback-Szenario, da das Indikator-Applet eine obligatorische Komponente ist, die standardmäßig ausgeführt wird.

OpenNingia
quelle
Vielen Dank, dass Sie darauf hingewiesen haben, die PID des Indikator-Applets zu erhalten (ich tue dies bereits für andere mögliche Abhängigkeiten, indem ich pidof verwende). Dies wäre zugegebenermaßen ein weniger eleganter Weg, wenn nichts Besseres verfügbar wäre. Soweit ich sehe, läuft Indicator-Applet nur dann zuverlässig mit Unity, wenn die Hardwareanforderungen erfüllt sind. Benutzer können in 2D GNOME booten und entscheiden, Indikator-Applet nicht auszuführen. Allerdings kann dies dann nicht an meinem Problem liegen.
Takkat
Ich stimme Ihnen zu, dass es vielleicht nicht "elegant" ist (aber Sie können jedes gewünschte Kosmetikum hinzufügen: D), aber es sollte funktionieren. Persönlich bevorzuge ich Lösungen, die gut funktionieren, und Eleganz steht an zweiter Stelle :)
OpenNingia
Diese Aufgabe scheint auf meinem 14.04-System nicht zu laufen. Wurde der Ansatz abgelöst? /usr/lib/x86_64-linux-gnu/indicator-messages/indicator-messages-serviceStattdessen gibt es viele Aufgaben.
halfer