在Ubuntu Panel中添加更改图标

时间:2009-11-18 15:31:21

标签: linux ubuntu panel gnome

在Ubuntu(Gnome)面板中添加和更改图标的最简单方法是什么?我正在寻找像shell脚本一样简单的东西,但我并不局限于此。如果这是一种更好或更简单的方法,它会为它编写一个程序。

我们的想法是创建一个脚本/程序来监控某些情况(例如安装点的可用性,互联网连接的可用性),并更改图标的状态以反映当前状态。

3 个答案:

答案 0 :(得分:2)

一种简单的方法是在Python中创建它。例如,见blog post

答案 1 :(得分:1)

我发现YAD (Yet Another Dialog)提供了最简单的解决方案。见webupd8's short description。但是,目前与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来结束演示。

答案 2 :(得分:0)

对于那些关心Unity的人来说,目前可能还没有一个简单的解决方案。所以也许编写一个使用Unity的AppIndicator-API的自定义Python脚本确实是可行的方法。网上已经有很多这方面的例子了,但是我仍然需要付出相当大的努力来实现一个脚本,该脚本实现与solution using YAD described in my other answer大致相同的功能:一个将监听输出的脚本一个程序并相应地更新“托盘图标”。这是我的解决方案:

#!/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(...取自this answer。这似乎是终止shell(子)进程的唯一可靠方法。
  • 无法使用Ctrl-C终止脚本 - 请使用菜单项“Quit”代替。应该可以使用信号库为Ctrl-C添加事件处理程序,但由于Gtk中的错误,这似乎被打破了。有关可能的解决方法,请参阅this answer

演示:将上述代码粘贴到文件my-indicator.py中,并使其chmod +x my-indicator.py可执行。对my answer proposing YAD中描述的文件dummy-programm.sh执行相同操作。调用./my-indicator.py,您应该会在Unity面板中看到一个图标,该图标每秒在两个不同的图标之间来回切换。 (如果安装了Ubuntu的app-indicator-library,这个 也适用于gnome和KDE桌面。)