![如何创建进行文件监控的统一启动器?](https://linux22.com/image/1040480/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E8%BF%9B%E8%A1%8C%E6%96%87%E4%BB%B6%E7%9B%91%E6%8E%A7%E7%9A%84%E7%BB%9F%E4%B8%80%E5%90%AF%E5%8A%A8%E5%99%A8%EF%BC%9F.png)
我想创建一个启动器,它的作用与垃圾图标相同,根据垃圾中是否有项目来显示不同的快速列表。
我想要类似的东西:如果文件夹A
存在,则显示A,B,C
在快速列表中,如果文件夹A
不存在,则显示D,E,F
在快速列表中。
答案1
以下工作:
- 创建 2 个文件:mylauncher.desktop 和 mylauncher.py,内容如下所示。
- 使 mylauncher.desktop 成为可执行文件。
- 将 mylauncher.desktop 添加到 unity 的启动器。
- 根据需要编辑 mylauncher.py 中的文件夹名称和文件夹位置。
- 在后台运行
python mylauncher.py
。您必须将其添加到您的启动脚本之一中。
来源:https://wiki.ubuntu.com/Unity/LauncherAPI
mylauncher.desktop 的内容:
[Desktop Entry]
Name=My Launcher
Comment=A,B,C if A else D,E,F
Exec=nautilus %U
Icon=nautilus
Terminal=false
StartupNotify=true
Type=Application
OnlyShowIn=GNOME;Unity;
Actions=;
mylauncher.py的内容:
updateinterval = 1 #Update interval in seconds. Set it to a +ve integer.
#In Foldernames and Folderlocations, spaces shouldn't be preceded by \.
Foldernames = ["A", "B", "C", "D", "E", "F"]
Folderlocations = ["/home/prasanth/A", "/home/prasanth/B", "/home/prasanth/C", "/home/prasanth/D", "/home/prasanth/E", "/home/prasanth/F"]
#####################################
from gi.repository import Unity, Gio, GObject, Dbusmenu
import os, subprocess
def nautilusopen(junk1, junk2, location): #Function that opens `location` in nautilus. Equivalent to `nautilus location` in bash.
subprocess.Popen(['nautilus', "%s" % location])
launcher = Unity.LauncherEntry.get_for_desktop_id("mylauncher.desktop") #You won't have to modify this, except if you rename `mylauncher.desktop`
#Code block A: This code block builds 6 quicklist entries, 3 for when A is found and 3 for when it isn't
QLentries = [Dbusmenu.Menuitem.new() for i in Foldernames]
for i in xrange(6):
QLentries[i].property_set(Dbusmenu.MENUITEM_PROP_LABEL, "Goto %s" % Foldernames[i])
QLentries[i].connect("item-activated", nautilusopen, Folderlocations[i])
QLentries[i].property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
################
#Code block B: This code block creates 2 quicklists 1 for when A is found and 1 for when it isn't. Then it adds the first 3 quicklist entries to QLifA and the next 3 to QLifnotA
QLifA = Dbusmenu.Menuitem.new() #Quicklist if A is found
QLifnotA = Dbusmenu.Menuitem.new() #Quicklist if A is not found.
for i in xrange(3):
QLifA.child_append(QLentries[i])
for i in xrange(3, 6):
QLifnotA.child_append(QLentries[i])
################
#The rest of the code simply monitors the file system for A's existence and switches appropriately between QLifA and QLifnotA
prevState = None
def updateql():
global prevState
currentState = 'A' if os.path.exists(Folderlocations[0]) else 'notA' #currentState is 'A' if Folderlocations[0] (which is /home/prasanth/A) exists, 'notA' otherwise
if currentState != prevState:
if currentState == 'A':
launcher.set_property("quicklist", QLifA)
else:
launcher.set_property("quicklist", QLifnotA)
prevState = currentState
return True
#GObject.timeout_add_seconds(updateinterval, updateql)
#mainloop = GObject.MainLoop()
#mainloop.run()
#If the 3-line commented block above worked as expected, the remainder of this script would be unnecessary. Unfortunately, it doesn't.
import signal
def alarmhandler(signum, frame):
raise Exception('Alarm has rung')
signal.signal(signal.SIGALRM, alarmhandler)
mainloop = GObject.MainLoop()
while True:
try:
updateql()
signal.alarm(updateinterval)
mainloop.run()
except KeyboardInterrupt:
continue
编辑:使用以下内容作为 mylauncher.py,用于评论中提到的目的。修改以满足您的需求应该很简单,如果评论中没有提到的话。
from gi.repository import Unity, Gio, GObject, Dbusmenu
import os, subprocess
updateinterval = 1 #Update interval in seconds. Set it to a +ve integer.
#Quicklist entries if already mounted:
ifMountedEntry1text = """Unmount A""" #Text shown in the quicklist menu for this entry.
ifMountedEntry1command = """unmount A""" #Bash command to execute when entry 1 is clicked. Doubt if `unmount A` will work. Modify appropriately.
ifMountedEntry2text = """Open A""" #Maybe you'll want to open A directly from the launcher. Included just so you get a hang of how this works.
ifMountedEntry2command = """nautilus A"""
#Extend as required.
#Quicklist entries if not already mounted:
ifnotMountedEntry1text = """Mount A"""
ifnotMountedEntry1command = """mount A""" #Again modify `mount A` appropriately.
#Extend as required.
#My old file monitoring should work. But in case you want to change the criteria for modifying quicklists, it is better to do the following:
filemonitoringcommand = """if [ -d /folder/to/monitor/ ]; then echo True; else echo False; fi;""" #<Bash command>/<location to script> which prints 'True' if A is mounted, 'False' otherwise.
#####################
def systemcall(junk1, junk2, command):
os.system(command)
launcher = Unity.LauncherEntry.get_for_desktop_id("mylauncher.desktop") #You won't have to modify this, except if you rename `mylauncher.desktop`
#Quicklist if already mounted:
QLifMounted = Dbusmenu.Menuitem.new()
ifMountedEntry1 = Dbusmenu.Menuitem.new()
ifMountedEntry1.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifMountedEntry1text) #Sets the text shown in the quicklist menu for this entry.
ifMountedEntry1.connect("item-activated", systemcall, ifMountedEntry1command) #Sets the corresponding bash command.
ifMountedEntry1.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifMounted.child_append(ifMountedEntry1) #Adds the first entry to the quicklist
ifMountedEntry2 = Dbusmenu.Menuitem.new()
ifMountedEntry2.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifMountedEntry2text)
ifMountedEntry2.connect("item-activated", systemcall, ifMountedEntry2command)
ifMountedEntry2.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifMounted.child_append(ifMountedEntry2)
#Extend as required.
#Quicklist if not already mounted:
QLifnotMounted = Dbusmenu.Menuitem.new()
ifnotMountedEntry1 = Dbusmenu.Menuitem.new()
ifnotMountedEntry1.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifnotMountedEntry1text)
ifnotMountedEntry1.connect("item-activated", systemcall, ifnotMountedEntry1command)
ifnotMountedEntry1.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifnotMounted.child_append(ifnotMountedEntry1)
#Extend as required.
#The rest of the code uses `filemonitoringcommand` to monitor the filesystem and dynamically modifies (or rather switches between) quicklists.
prevState = None
def updateql():
global prevState
currentState = 'True' in os.popen(filemonitoringcommand).read()
if currentState != prevState:
if currentState == True:
launcher.set_property("quicklist", QLifMounted) #If already mounted, sets QLifMounted as the quicklist.
else:
launcher.set_property("quicklist", QLifnotMounted) #Otherwise sets QLifnotMounted as the quicklist.
prevState = currentState
return True
#GObject.timeout_add_seconds(updateinterval, updateql)
#mainloop = GObject.MainLoop()
#mainloop.run()
#If the 3-line commented block above worked as expected, the remainder of this script would be unnecessary. Unfortunately, it doesn't.
import signal
def alarmhandler(signum, frame):
raise Exception('Alarm has rung')
signal.signal(signal.SIGALRM, alarmhandler)
mainloop = GObject.MainLoop()
while True:
try:
updateql()
signal.alarm(updateinterval)
mainloop.run()
except KeyboardInterrupt:
continue