動的に更新されるパネルアプリ/インジケーターを作成するにはどうすればよいですか?


12

私はubuntu Mate用のいくつかのパネルアプリを書こうとしています。私はC / C ++とSDLをかなりよく知っています。Mate-Universityパネルアプリのgithubページを見たことがありますが、正常に動作しません/少し時間がかかります。

パネルアプリを作成する簡単な方法があるかどうか疑問に思っています。カスタムアプリケーションランチャーの使用について話していません。新しい機能をパネルに追加したいのですが、方法がわかりません。チュートリアル、またはパネルアプリの作成に関する説明が非常に役立つ場合があります。

回答:


16

何がすでにこの質問をする機会であると考えられるので、答えた(で、私はそれが行われたかの拡張説明として、この質問に答えるのですがpython

基本的な静的インジケーター

Ubuntu Mateは15,10以降、インジケーターをサポートしているため、インジケーターの作成とMateのパネルアプリの作成に大きな違いはありません。したがって、このリンクpythonAppIndicator3API を使用するの基本的なインジケーターの出発点として適しています。リンクは良いスタートですが、インジケーターにテキストを表示する方法に関する情報は提供されません。テキスト(またはアイコン)を更新する方法は言うまでもありません。それにもかかわらず、いくつかの追加により、これは以下のようなインジケーターの基本的な「フレーム」につながります。アイコン、テキストラベル、メニューが表示されます。

ここに画像の説明を入力してください

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

AppIndicator3.IndicatorCategory.OTHERでは、この(部分的に古い)リンクで説明されているように、カテゴリが定義されています。適切なカテゴリを設定することは重要です。インジケーターをパネルの適切な位置に配置するためです。

主な課題。インジケーターのテキストやアイコンを更新する方法

本当の課題は、基本的なインジケーターをどのように書くかではなく、インジケーターのテキストやアイコンを定期的に更新する方法です。インジケーターを適切に機能させるために、threading2番目のプロセスを開始して、定期的にインターフェイスを更新するだけでは使用できません。ええと、実際には可能ですが、長い目で見ると、競合が発生することがわかりました。

これがこの(古くなった)リンクにGObject置かているので、ここに来ます:

gobject.threads_init()アプリケーションの初期化時に呼び出します。次に、通常どおりスレッドを起動しますが、スレッドがGUIタスクを直接実行しないようにしてください。代わりgobject.idle_addに、メインスレッドで実行されるようにGUIタスクをスケジュールするために使用します

gobject.threads_init() by GObject.threads_init()gobject.idle_addby を置き換えるとGObject.idle_add()、ほとんどの場合、Gtkアプリケーションでスレッドを実行する方法の更新版が作成されます。サルの数が増加していることを示す簡単な例:

ここに画像の説明を入力してください

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

それが原則です。この回答の実際のインジケーターでは、ループ時間とインジケーターテキストの両方が、スクリプトにインポートされたセカンダリモジュールによって決定されましたが、主な考え方は同じです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.