Я пытаюсь записать некоторые приложения панели для ubuntu Mate. Я знаю C/C++ и SDL обоснованно хорошо. Я видел приложения панели Mate-University страница GitHub, но я не могу заставить ее работать правильно / я имею хотя время с нею.
Я просто задаюсь вопросом, если существует некоторая легкая авеню для записи приложений панели? Я не говорю об использовании средства запуска пользовательского приложения, я хотел бы добавить новую функциональность к панели, но я не уверен как. Учебное руководство или описание о записи приложений панели могло быть действительно полезным.
Начиная с какого, кажется, случай для задавания этого вопроса, уже имеет ответ, я отвечаю на этот вопрос как на расширенное объяснение о том, как это было сделано (в python
)
Так как Помощник Ubuntu, от 15,10, поддерживает индикаторы, нет большого различия между записью индикатора и приложением панели для Помощника. Поэтому эта ссылка является хорошей начальной точкой для основного индикатора в python
, использование AppIndicator3
API. Ссылка является хорошим запуском, но не предоставляет информации о том, как показать текст на индикаторе, уже не говоря о том, как обновить текст (или значок). Тем не менее, с несколькими дополнениями, это приводит к основному "кадру" индикатора как ниже. Это покажет значок, текстовую метку и меню:
#!/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
, категория определяется, как экс-наструганная в этом (частично устаревший) ссылка. Установка правильной категории важна, a.o. для помещения индикатора в соответствующее положение в панели.
Реальная проблема не состоит в том, как записать основной индикатор, а как периодически обновлять текст и/или значок Вашего индикатора, так как Вы хотите иметь его, показывают (текстовое) время. Чтобы заставить индикатор работать правильно, мы не можем просто использовать threading
запустить второй процесс для периодического обновления интерфейса. Ну, на самом деле мы можем, но на долгосрочной перспективе, это приведет к конфликтам, как я узнал.
Вот то, где GObject
входит, к, поскольку это помещается в это (также устаревший) ссылка:
звонить gobject.threads_init()
при applicaiton инициализации. Затем Вы обычно запускаете свои потоки, но удостоверяетесь, что потоки никогда не делают задач GUI непосредственно. Вместо этого Вы используете gobject.idle_add
запланировать задачу GUI к выполняемому в основном потоке
Когда мы заменяем gobject.threads_init()
GObject.threads_init()
и gobject.idle_add
GObject.idle_add()
, у нас в значительной степени есть обновленная версия того, как выполнить потоки в a 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()
Это - принцип. В фактическом индикаторе в этом ответе и время цикла и текст индикатора были определены вторичным модулем, импортированным в сценарии, но основная идея является тем же.