Python中的托盘图标应用程序,图标消失了

时间:2015-12-09 06:21:20

标签: python wxpython trayicon

我在Python中为自己掀起了一个改变壁纸的应用程序。它在通知托盘中生成一个图标,可用于在" nice"之间切换模式。和顽皮的"取决于周围的人:P并强制更换壁纸。如果单独留下,它仍会每10分钟更改一次随机壁纸,从我不断添加的图像中随机选择。一切都很好,直到我升级到Ubuntu 14.04" Trusty"到Ubuntu 15.10" Wily。"现在,应用程序仍然运行,并且每隔10分钟就会更换一次壁纸,但是图标消失了。它在图标的托盘中显示空间,但图标中不再显示图标,空白空间也不会响应任何鼠标左键或右键(左键单击用于强制更换壁纸,右键单击用于给我一个菜单的两种模式)。运行应用程序时,控制台上不显示警告或错误消息。我对Python不太熟悉,也无法弄清楚问题到底是什么。以下是applet的(非常短的)代码。对不起,如果代码中有任何可怕的做法,就像我说我真的不是一个蟒蛇人,它似乎是做我想做的最容易的方式,所以我去了。如果有人能帮我解决问题,我会很感激!

PS" ./ change_wall"只是一个bash脚本除了更改壁纸之外还可以做其他一些事情。我知道问题不在那里,因为自动壁纸更改仍然有效,它只是托盘图标/控制界面的FUBAR。

#!/usr/bin/python

import os
import wx

import time
import thread

class TaskBarIcon(wx.TaskBarIcon):
    def __init__(self):
        super(TaskBarIcon, self).__init__()
        os.chdir("/home/caleb/walls")
        self.SetIcon(wx.Icon('walls.xpm', wx.BITMAP_TYPE_XPM), "Wallpaper switcher")
        self.set_nice(None)
        self.Bind(wx.EVT_TASKBAR_LEFT_UP, self.set_new_wall_x)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        nice_item    = menu.AppendRadioItem(-1, "Nice")
        naughty_item = menu.AppendRadioItem(-1, "Naughty")
        if self.type == 'nice':
            nice_item.Check()
        elif self.type == 'naughty':
            naughty_item.Check()
        menu.Bind(wx.EVT_MENU, self.set_nice, nice_item)
        menu.Bind(wx.EVT_MENU, self.set_naughty, naughty_item)
        return menu

    def set_nice(self, event):
        self.type = 'nice'
        self.set_new_wall()

    def set_naughty(self, event):
        self.type = 'naughty'
        self.set_new_wall()

    def set_new_wall(self):
        os.system("./change_wall " + self.type)
        self.last_changed_time = time.time()

    def set_new_wall_x(self, event):
        self.set_new_wall()

def main():
    app = wx.App(False)
    the_icon = TaskBarIcon()
    thread.start_new_thread(app.MainLoop, ())
    while 1:
        if (time.time() > the_icon.last_changed_time + 600):
            the_icon.set_new_wall()

if __name__ == '__main__':
    main()

3 个答案:

答案 0 :(得分:0)

除了检查评论中的内容之外,看看此代码是否有效,您的机器上应该存在使用的图标。

import wx

TRAY_TOOLTIP = 'System Tray Demo'
TRAY_ICON = '/usr/share/icons/gnome/16x16/emotes/face-cool.png'

def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.AppendItem(item)
    return item

class TaskBarIcon(wx.TaskBarIcon):
    def __init__(self):
        wx.TaskBarIcon.__init__(self)
        self.set_icon(TRAY_ICON)
        self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)
        self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.on_right_down)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Say Hello', self.on_hello)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu

    def set_icon(self, path):
        icon = wx.IconFromBitmap(wx.Bitmap(path))
        self.SetIcon(icon, TRAY_TOOLTIP)

    def on_left_down(self, event):
        print 'Tray icon was left-clicked.'

    def on_right_down(self, event):
        print 'Tray icon was right-clicked.'
        event.Skip()

    def on_hello(self, event):
        print 'Hello, world!'

    def on_exit(self, event):
        wx.CallAfter(self.Destroy)

def main():
    app = wx.App()
    TaskBarIcon()
    app.MainLoop()

if __name__ == '__main__':
    main()

答案 1 :(得分:0)

好吧,我没有继续使用wxPython和这个Project Phoenix胡说八道,而是转而使用PyGTK,我不得不说,总的来说我更喜欢这个。我的代码现在的行为完全符合我的要求,如下所示:

#!/usr/bin/python

import gobject
import gtk
import os
import thread
import time 

last_changed_time = 0
mode = "nice"

def set_mode (new_mode):
  global mode
  mode = new_mode
  change_wall()

def make_menu(event_button, event_time, data=None):
  menu = gtk.Menu()
  nice_item = gtk.CheckMenuItem("Nice")
  naughty_item = gtk.CheckMenuItem("Naughty")
  kill_item = gtk.MenuItem("Quit")
  if mode == "nice":
    nice_item.set_active(True)
  if mode == "naughty":
    naughty_item.set_active(True)
  menu.append(nice_item)
  menu.append(naughty_item)
  menu.append(kill_item)
  nice_item.connect_object("activate", set_mode, ("nice"))
  naughty_item.connect_object("activate", set_mode, ("naughty"))
  kill_item.connect_object("activate", gtk.main_quit, ())
  nice_item.show()
  naughty_item.show()
  kill_item.show()
  menu.popup(None, None, None, event_button, event_time)

def change_wall():
  global last_changed_time
  os.system("./change_wall " + mode)
  last_changed_time = time.time()

def on_right_click(data, event_button, event_time):
  make_menu(event_button, event_time)

def on_left_click(event):
  change_wall()

def auto_update():
  while 1:
    time.sleep(1)
    if time.time() > last_changed_time + 600:
      change_wall()

if __name__ == '__main__':
  gobject.threads_init()
  os.chdir("/home/caleb/walls")
  icon = gtk.status_icon_new_from_file("walls.xpm")
  icon.connect('popup-menu', on_right_click)
  icon.connect('activate', on_left_click)
  change_wall()
  thread.start_new_thread(auto_update, ())
  gtk.main()

我必须在每次检查之前插入time.sleep(1)调用,以查看是否需要自动更新,以防止图标/菜单本身变得相当滞后。当我使用wx时,我从未遇到过这个问题;有没有更优雅的方法来解决这个问题?

再次感谢您的帮助!

答案 2 :(得分:0)

因为您正在运行wx.python 3,看起来您需要更改一些呼叫:
IconFromBitmap成为Icon
TaskBarIcon成为adv.TaskBarIcon
可能存在一些其他微小差异,但这些差异似乎是显而易见的。

编辑:
另一种选择是加载以前版本的wxpython 为此,您可以在导入中使用wxversion,如此:

import wxversion
wxversion.select("2.8-gtk2-unicode")
import wx