我在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()
答案 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