Добавить изменяющийся значок на панель Ubuntu - PullRequest
4 голосов
/ 18 ноября 2009

Какой самый простой способ добавить и изменить значок на панели Ubuntu (Gnome)? Я ищу что-то такое же простое, как сценарии оболочки, но я не ограничен этим. Напишу программу для него, если это будет лучше или проще.

Идея состоит в том, чтобы создать сценарий / программу для мониторинга некоторых условий (например, наличия точки монтирования, наличия подключения к Интернету) и изменить состояние значка, чтобы оно отражало текущее состояние.

Ответы [ 3 ]

2 голосов
/ 18 ноября 2009

Один простой способ - сделать это на Python. См., Например, сообщение в блоге .

1 голос
/ 05 декабря 2015

Я нашел ЯД (еще один диалог) , чтобы предоставить самое простое решение. См. Краткое описание webupd8 . Тем не менее, интеграция в Unity в данный момент выглядит слегка нарушенной. Ниже я упоминаю обходной путь, но если вы действительно заботитесь об Unity, вам, вероятно, стоит поискать другие ответы.

Примечание. Хотя я уверен, что YAD работает в самых разных средах, я протестировал приведенные ниже инструкции только с использованием Lubuntu 15.10 (рабочий стол LXDE) и Ubuntu 14.04 (рабочий стол Unity) .

Установка

Я получил рабочую установку с:

sudo apt-add-repository ppa:webupd8team/y-ppa-manager 
sudo apt-get update
sudo apt-get install yad

(На самом деле мне не нужны были первые две строки в Lubuntu 15.10, но это могло быть совпадением.)
В LXDE звоните

yad --notification --listen

затем вызвал иконку в трее, которую я мог бы изменить, набрав (например): icon:gtk-help. В Unity ничего не появилось, поэтому мне нужно было следующее ...

Обходной путь для Unity: Следующие инструкции снова взяты из webupd8 . Проблема в том, что «системный трей» больше официально не существует в Unity. Одним из возможных решений для запуска таких программ, как YAD, которые не догнали это изменение, является установка «эмулятора системного трея»:

sudo apt-add-repository ppa:fixnix/indicator-systemtray-unity
sudo apt-get update
sudo apt-get install indicator-systemtray-unity

Чтобы получить значки прямо на панели Unity, я использовал следующие настройки:

gsettings set net.launchpad.indicator.systemtray tray-is-static true
gsettings set net.launchpad.indicator.systemtray show-background-static false

Как только я выйду из системы и вернусь снова, yad --notification заработал как положено. (Более того, «системный трей» отображал некоторые дополнительные значки, которые я ранее искал напрасно.) Положение значков на панели можно изменить с помощью:

gsettings set net.launchpad.indicator.systemtray static-x 1500

(где 1500 может быть заменено любым разумным значением). Я не знаю, как сделать так, чтобы значки отображались вровень-вправо. Если вам когда-нибудь захочется снова удалить «эмулятор системного трея», webupd8 рекомендует:

sudo apt-get purge indicator-systemtray-unity

Демо

Вот упрощенная демонстрация, которая может помочь проиллюстрировать, как использовать YAD в реальных сценариях. Я предполагаю, что сам YAD уже установлен, как описано выше. Предположим, мы хотели бы посмотреть вывод какой-либо программы, запущенной в командной строке, и соответствующим образом обновить иконку в трее. Для целей этой демонстрации давайте просто возьмем эту «программу» в качестве следующего скрипта «dummyprogram.sh»:

#! /bin/bash
i=1
while [ $i -ne 3 ]
do
  let "i=((i+1)%2)"
echo $i
  sleep 1
done

Копирование вышеуказанных строк в файл "dummyprogram.sh", выполнение его с помощью "chmod + x dummyprogram.sh" и вызов "./dummyprogram.sh" должны привести к следующему выводу:

0
1
0
1
...

(одна строка каждую секунду). Теперь для актуальной задачи под рукой. Чтобы получить «иконизированную» версию вышеприведенного вывода в области уведомлений, мы используем следующий скрипт «demo.sh»:

#! /bin/bash
while read x
do
  if  [ $x -eq 0 ]
  then
    echo icon:gtk-home
  else
    echo icon:gtk-help
  fi
done

Снова скопируйте строки в файл "demo.sh" и сделайте его исполняемым. Вызов

./dummyprogram.sh | ./demo.sh | yad --notification --listen

теперь должно привести к желаемому результату: значок в области уведомлений, который каждую секунду меняет изображение между двумя различными значками.

Вы можете завершить демонстрацию, набрав Ctrl-C в терминале.

0 голосов
/ 12 декабря 2015

Для тех, кому небезразлична Unity, простого решения в настоящее время может не существовать. Так что, возможно, написание нестандартного скрипта Python, использующего API-интерфейс Unity AppIndicator-API, - действительно правильный путь. В Интернете уже есть множество примеров этого, но мне все еще потребовалось немало усилий, чтобы найти скрипт, который реализует примерно ту же функциональность, что и решение , используя YAD, описанный в моем другом ответе : скрипт, который будет прослушивать вывод программы и соответственно обновлять «иконку в трее». Вот мое решение:

#!/usr/bin/python
import os, threading, signal
from subprocess import Popen, PIPE, STDOUT
from gi.repository import Gtk
from gi.repository import AppIndicator3 as AppIndicator

class my_indicator:
    ICON_0 = "gtk-home" 
    ICON_1 = "gtk-help"       

    def __init__(self, wrapper):
        self.ind = AppIndicator.Indicator.new("my-app-indicator", Gtk.STOCK_INFO, AppIndicator.IndicatorCategory.SYSTEM_SERVICES)
        self.ind.set_status(AppIndicator.IndicatorStatus.ACTIVE)
        self.wrapper = wrapper
        self.build_menu()

    def build_menu(self):
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.wrapper.quit)
        menu = Gtk.Menu()
        self.ind.set_menu(menu)
        menu.append(item_quit)
        menu.show_all()

    def update_icon(self,icon):
        self.ind.set_icon(icon)

class dummy_wrapper:
    PROGRAM = "./dummyprogram.sh"

    def __init__(self):
        self.indicator = my_indicator(self)

    def main(self):
        self.process = Popen(self.PROGRAM, stdout=PIPE, stderr=STDOUT, close_fds=True, shell=True, preexec_fn=os.setsid)
        self.thread = threading.Thread(target=self.watch_pipe, args=(self.process.stdout,self.indicator))
        self.thread.daemon = True
        self.thread.start() 
        Gtk.main()

    def quit(self, source):
        if self.process:
            os.killpg(self.process.pid, signal.SIGTERM)               
        if self.thread:
            self.thread.join() 
        Gtk.main_quit()

    @staticmethod
    def watch_pipe(pipe, indicator): 
        while 1:  
            line = pipe.readline().strip() 
            # The thread waits here until a line appears in the pipe.
            if not line: 
                # This happens exactly once, namely when the process ends.
                break
            else:
                print line
                if line=="0": 
                    indicator.update_icon(my_indicator.ICON_0)
                else:
                    indicator.update_icon(my_indicator.ICON_1)  

dummy_wrapper().main()

Несколько кратких замечаний по коду:

  • Синтаксис строк, вызывающих и закрывающих программу, которую я хочу прослушать (./dummyprogram.sh), т.е. строки self.process = Popen(... и os.killpg(... взяты из этого ответа . Похоже, что это единственный надежный способ завершить процесс оболочки (под).
  • Сценарий не может быть завершен с помощью Ctrl-C - используйте пункт меню «Выход»). Должна быть возможность добавить обработчик событий для Ctrl-C, используя библиотеку сигналов, но это, похоже, не работает из-за ошибки в Gtk. См. этот ответ для возможного обходного пути.

Демонстрация : вставьте приведенный выше код в файл my-indicator.py и сделайте его исполняемым с помощью chmod +x my-indicator.py. Сделайте то же самое для файла dummy-programm.sh, описанного в моего ответа с предложением YAD . Позвоните по номеру ./my-indicator.py, и вы увидите значок на панели Unity, который каждую секунду переключается между двумя различными значками. (Этот должен также работать на рабочих столах gnome и KDE при условии, что установлена ​​библиотека-индикатор-приложение Ubuntu.)

...