如何在 python 中的动态快速列表(dbusMenuItems)中创建子菜单?
官方文档非常少: https://wiki.ubuntu.com/Unity/LauncherAPI
这是我的最小编码示例:dbus_snippet.py
#!/usr/bin/env python
from gi.repository import Unity, Gio, GObject, Dbusmenu
import os
import subprocess
launchers = []
qlList = []
#(not all references are links due to askubuntu's reputation-system)
#askubuntu "how-to-add-checkbox-or-radio-buttons-to-a-unity-quicklist"
#https://lazka.github.io/pgi-docs/Dbusmenu-0.4/classes/Menuitem.html#Dbusmenu.Menuitem
#(project that this research may go into)
#(github thirschbuechler/ubuntu-recentquicklists)
def check_item_activated_callback (menuitem, a, b):#for the submenu
if menuitem.property_get_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE) == Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED:
menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_UNCHECKED)
else:
menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED)
def check_item_activated(menuitem, a, arg):#main menu item
process = subprocess.Popen("gedit ",shell=True)
def createItem(name, arg, qlnummer):
item = Dbusmenu.Menuitem.new()
item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, name)
item.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, True)
item.connect("item-activated", check_item_activated,arg)
check1 = Dbusmenu.Menuitem.new ()
check1.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Checkbox")
check1.property_set (Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE, Dbusmenu.MENUITEM_TOGGLE_CHECK)
check1.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED)
check1.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, True)
check1.property_set (Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY, Dbusmenu.MENUITEM_CHILD_DISPLAY_SUBMENU)
#check1.property_set (Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY, 'children-display')
#https://lazka.github.io/pgi-docs/Dbusmenu-0.4/constants.html#Dbusmenu.MENUITEM_CHILD_DISPLAY_SUBMENU
check1.connect (Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED, check_item_activated_callback, None)
item.child_append(check1)
qlList[qlnummer].child_append(item)
def update(a=None):
#delete old ones
for i in range(len(qlList)):
for c in qlList[i].get_children():
qlList[i].child_delete(c)
def main():
launchers.append(Unity.LauncherEntry.get_for_desktop_id ("nautilus.desktop"))
launchers.append(Unity.LauncherEntry.get_for_desktop_id ("nemo.desktop"))
for i in range(len(launchers)):
qli = Dbusmenu.Menuitem.new()
qlList.append(qli)
update()
for i in range(len(launchers)):
createItem("item1","arg1",i)
launchers[i].set_property("quicklist", qlList[i])
loop = GObject.MainLoop()
loop.run()
main()
我为什么认为这是可能的?一个名为 的选项Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY
,内容是“将子项显示为子菜单”,听起来非常接近我想要做的事情,但我没能实现。上面的代码片段将一个 dbus-item 添加到另一个 dbus-item,并设置子菜单属性(在 Nemo/Nautilus 启动器上)
(补充:我还没有找到任何可以check_item_activated
区分右键单击、左键单击和鼠标中键的东西,但证明我错了)
答案1
我不知道如何使用 dbus 来做到这一点但是......
您只需编辑 .desktop 文件即可完成此操作,更改会自动生效。编写一个类来在 ~/.local/share/applications/ 中写入或编辑 .desktop 文件应该很简单
启动器需要一个 Action 行,其中定义了快速列表名称,对于每个名称,您需要一个包含 Name 和 Exec 行的 [桌面操作名称] 块。它记录在您的链接中。
据我所知,您只能深入一级,并且除了启动器之外,我还没有设法将任何其他内容添加到快速列表中。
这样做的好处是确保程序退出并重新启动后菜单可用。
这是一个将各种主机作为 gnome-terminal 图标的子菜单项列出的示例。
[Desktop Entry]
Name=Terminal
Comment=Use the command line
Keywords=shell;prompt;command;commandline;
TryExec=gnome-terminal
Exec=gnome-terminal
Icon=utilities-terminal
Type=Application
X-GNOME-DocPath=gnome-terminal/index.html
X-GNOME-Bugzilla-Version=3.16.2
Categories=GNOME;GTK;System;TerminalEmulator;
StartupNotify=true
X-GNOME-SingleWindow=false
OnlyShowIn=GNOME;Unity;
Actions=New;host1;host2
X-Ubuntu-Gettext-Domain=gnome-terminal
[Desktop Action New]
Name=New Terminal
Exec=gnome-terminal
OnlyShowIn=Unity
[Desktop Action host1]
Name=SSH to HOST1
Exec=gnome-terminal -e 'ssh host1' -t 'SSH to host1'
OnlyShowIn=Unity
[Desktop Action host2]
Name=SSH to HOST2
Exec=gnome-terminal -e 'ssh host2' -t 'SSH to host2'
OnlyShowIn=Unity