晚上好!
我正在为Linux编写一个简单的系统托盘应用程序,它使用Python和GTK检查系统更新。到目前为止,我有基本的功能,应用程序运行,显示一个图标,右键单击有一个菜单,其中包含更多选项。当我尝试将gtk.StatusIcon更改为其他图像而不是“交换”“alert”图标的原始图标时,会出现问题,它会在托盘中创建第二个图标(现在标准图标和警报图标是并排的)当退出应用程序的警报图标实例时,关闭它们。
这个特定的应用程序分为两部分(下面的代码),在每小时cron作业中运行的后端脚本,以及可以作为自动启动和/或通过应用程序运行的GUI(系统托盘图标)菜单。
我已经阅读了PyGTK文档,但我看到的任何内容都没有解释如何“就地”切换(交换)图标。我确信我错过了一些东西,并会欣赏来自第二双眼睛的任何建设性意见。
这是“后端”代码:
import time
import subprocess
import logging
import lupdater
# Create the log, set level to DEBUG so that all messages are available
logging.basicConfig(filename='/tmp/lupdater.log', level=logging.DEBUG)
# Global package list
paclist = []
class Pacman():
'''Provides functions to call pacman and update the repos, as well as
return a list with number of updates. '''
def pac_update(self):
'''Updates the repositories, notifies the user.'''
subprocess.call(['/usr/bin/notify-send', 'Updating repositories for update check...'], shell=False)
upd = subprocess.Popen('sudo pacman -Syy', shell=True, stdout=subprocess.PIPE)
stdout, stderr = upd.communicate()
def pac_list(self):
'''Creates a list of packages needing to be updated and counts them,
displays the count in a notification for user action.'''
subprocess.call(['/usr/bin/notify-send', 'Checking for updates...'], shell=False)
# Clean up the list from previous checks so that we keep an accurate count.
if len(paclist) > 0:
for i in paclist:
paclist.remove(i)
lst = subprocess.Popen('pacman -Qu', shell=True, stdout=subprocess.PIPE)
for line in lst.stdout:
line.rstrip('\r\n')
paclist.append(line)
numupdates = len(paclist)
if numupdates >= 1:
subprocess.call(['/usr/bin/notify-send', '%s %s %s' % ('You have', numupdates, 'updates available!')], shell=False)
# Here we set the status icon to change and start blinking
lupblinker = lupdater.SystrayApp()
lupblinker.blinker()
logging.info(time.ctime() + ': lupdater had %s updates available.\n' % (numupdates))
else:
subprocess.call(['/usr/bin/notify-send', 'Your system is already up to date! :)'], shell=False)
logging.info(time.ctime() + ': No updates available, system is up to date.')
# "Future-proofing"
return numupdates, paclist
def pac_check_list(self, paclist):
# For now only checks for kernel updates, packages named "linux".
# TODO: Check for kernel modules such as video drivers that require
# a system restart or manual initialization.
critical = []
if len(paclist) > 0:
for i in paclist:
if i.startswith('linux'):
critical.append(i)
if len(critical) >= 1:
for i in critical:
subprocess.call(['/usr/bin/notify-send',
'%s %s' % (i, 'is a critical update, it requires a system restart to take effect.')], shell=False)
logging.info(time.ctime() + ': Critical update detected, user notified via notify-send.')
return critical, paclist
def run_me(x):
logging.info(time.ctime() + ': lupdater now running with sleep enabled process.')
# Meat and Potatoes
p = Pacman()
p.pac_update()
p.pac_list()
p.pac_check_list(paclist)
if __name__ == '__main__':
x = 0
run_me(x)enter code here
这是systray应用程序的“GUI”代码:
import gtk
import subprocess
import lupdaterapi
class SystrayApp():
def __init__(self):
self.tray = gtk.StatusIcon()
self.tray.set_from_file('/usr/share/icons/lupdater.png')
self.tray.connect('popup-menu', self.on_right_click)
self.tray.set_tooltip('Lemur Updater')
self.lapi = lupdaterapi
def blinker(self):
self.tray.set_from_file('/usr/share/icons/lupdater-alert.png')
self.tray.set_blinking(True)
def on_right_click(self, icon, event_button, event_time):
self.make_menu(event_button, event_time)
if self.tray.set_blinking() == True:
self.tray.set_blinking(False)
self.tray.set_from_file('/usr/share/icons/lupdater.png')
def make_menu(self, event_button, event_time):
menu = gtk.Menu()
# show about dialog
about = gtk.MenuItem('About')
about.show()
menu.append(about)
about.connect('activate', self.show_about_dialog)
# add run item for manual updates
run = gtk.MenuItem('Check Updates')
run.show()
menu.append(run)
run.connect('activate', self.lapi.run_me)
#add log checker, open in leafpad for now
chklog = gtk.MenuItem('View Log')
chklog.show()
menu.append(chklog)
chklog.connect('activate', self.show_log)
# add quit item
quit = gtk.MenuItem('Quit')
quit.show()
menu.append(quit)
quit.connect('activate', gtk.main_quit)
menu.popup(None, None, gtk.status_icon_position_menu,
event_button, event_time, self.tray)
def show_about_dialog(self, widget):
about_dialog = gtk.AboutDialog()
about_dialog.set_destroy_with_parent (True)
about_dialog.set_icon_name ('Lemur Updater')
about_dialog.set_name('Lemur Updater')
about_dialog.set_version('1.3b')
about_dialog.set_comments((u'System Tray interface to the Lemur Updater'))
about_dialog.set_authors([u'Brian Tomlinson <darthlukan@gmail.com>'])
about_dialog.run()
about_dialog.destroy()
def show_log(self, widget):
subprocess.Popen('/usr/bin/leafpad /tmp/lupdater.log', shell=True)
# Let's roll!
if __name__ == '__main__':
SystrayApp()
gtk.main()
提前再次感谢!
答案 0 :(得分:0)
您是否尝试过设置图标的名称和标题?