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

Python中的托盘图标应用程序,图标已消失,python,wxpython,trayicon,Python,Wxpython,Trayicon,我用Python为自己设计了一个小小的壁纸更改应用程序。它在通知栏中制作了一个图标,可用于根据周围的人在“好”和“淘气”之间切换模式:P并强制更改墙纸。如果不使用,它仍然会每10分钟更改一次随机壁纸,从我不断添加到的满是图像的目录中随机选择。一切都很好,直到我从Ubuntu 14.04“Trusty”升级到Ubuntu 15.10“Wily”。现在,该应用程序仍在运行,并将像应该的那样每10分钟更换一次壁纸,但图标不见了。它在托盘中为图标留出了一个空间,但图标不再出现在其中,空白空间也不会响应任

我用Python为自己设计了一个小小的壁纸更改应用程序。它在通知栏中制作了一个图标,可用于根据周围的人在“好”和“淘气”之间切换模式:P并强制更改墙纸。如果不使用,它仍然会每10分钟更改一次随机壁纸,从我不断添加到的满是图像的目录中随机选择。一切都很好,直到我从Ubuntu 14.04“Trusty”升级到Ubuntu 15.10“Wily”。现在,该应用程序仍在运行,并将像应该的那样每10分钟更换一次壁纸,但图标不见了。它在托盘中为图标留出了一个空间,但图标不再出现在其中,空白空间也不会响应任何鼠标左键或右键单击(左键单击用于强制更改墙纸,右键单击用于为我提供两种模式的菜单)。运行应用程序时,控制台上不会出现警告或错误消息。我对Python不是很有经验,也不知道到底是什么问题。以下是小程序的(非常短)代码。很抱歉,如果代码中有任何糟糕的做法,就像我说的,我真的不是python爱好者,这似乎是做我想做的事情的最简单的方法,所以我选择了它。如果有人能帮我解决这个问题,我将不胜感激

PS.“/change\u 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()

除了检查我的评论中的内容外,请查看此代码是否正常工作,使用的图标应该存在于您的计算机上

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()

好吧,我不再继续胡闹wxPython和这个凤凰城项目,我已经改用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时从未遇到过这个问题;有没有更优雅的方法来解决这个问题


再次感谢您的帮助

因为您正在运行wx.python 3,看起来您需要更改一些调用:
IconFromBitmap
变成
图标

TaskBarIcon
变为
adv.TaskBarIcon

可能还有其他一些细微的差异,但这些似乎是显而易见的

编辑:
另一个选项是加载wxpython的早期版本。
为此,您可以在导入中使用类似的
wxversion

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

只有2个最初的想法,1您是否更改了python版本?和2您是否使用另一个图标图像进行了测试?您的代码正在Mint 17.2上运行。谢谢您的回复。我不确定我以前使用的是什么Python版本,但到目前为止,“Python-V”报告的是2.7.10。我尝试过使用另一个图标,结果也一样。Re:你的代码,我在那个地方没有那个图标,所以我把它改成了下面的,也是一个16x16 PNG,它确实存在于我的系统中:“/usr/share/icons/Adwaita/16x16/status/battery full charge.PNG”,但是当我运行代码时,什么都没有发生。我没有托盘图标,根本没有控制台输出,执行一开始就停止ps aux’告诉我,与脚本相关的任何进程都不会继续运行……真讨厌!运行python,
import wx
,然后键入
wx\uuuuuuuuuuuu版本
,这将告诉您wxpython的版本。如果是3,你必须阅读《凤凰计划》手册。我假设您是从命令行运行此命令,如果不是,请这样做。可能是您的新OS上缺少了某些内容。wx___;版本不起作用(NameError:名称“wx_________;”未定义),但“print wx.version()”报告“3.0.2.0 gtk2(经典)”。我将查看凤凰计划手册。非常感谢。您只需加载wx的早期版本,您的原始代码就可以正常工作,而不是从一个新的UI开始