如何从 Python 向 GTK 的 "recently used" 文件列表添加一项?

How does one add an item to GTK's "recently used" file list from Python?

我正在尝试将来自 Python 3 的 Ubuntu 添加到 "recently used" 文件列表。

我能够成功读取最近使用的文件列表,如下所示:

from gi.repository import Gtk
recent_mgr = Gtk.RecentManager.get_default()
for item in recent_mgr.get_items():
    print(item.get_uri())

这打印出的文件列表与我在 Nautilus 中查看 "Recent" 或查看 GIMP 等应用程序文件对话框中的 "Recently Used" 位置时看到的相同。

但是,当我尝试添加这样的项目时(其中 /home/laurence/foo/bar.txt 是一个现有的文本文件)...

recent_mgr.add_item('file:///home/laurence/foo/bar.txt')

...该文件未显示在 Nautilus 的“最近”部分或文件对话框中。它甚至没有出现在 get_items().

返回的结果中

如何将 Python 中的文件添加到 GTK 最近使用的文件列表?

A Gtk.RecentManager 需要发出 changed 信号才能将更新写入 C++ class 的私有属性中。要在应用程序中使用 RecentManager 对象,您需要通过调用 Gtk.main:

来启动事件循环
from gi.repository import Gtk

recent_mgr = Gtk.RecentManager.get_default()
uri = r'file:/path/to/my/file'
recent_mgr.add_item(uri)
Gtk.main()

如果您不调用 Gtk.main(),则不会发出 changed 信号,也不会发生任何事情。

回答@andlabs 查询,RecentManager.add_item returns 布尔值的原因是因为调用了 g_file_query_info_async 函数。回调函数 gtk_recent_manager_add_item_query_info 然后将 mimetype、应用程序名称和命令收集到 GtkRecentData 结构中,最后调用 gtk_recent_manager_add_full。来源是 here.

如果出现任何问题,那是在 add_item 完成之后,所以如果调用它的对象是 RecentManager,则该方法只是 returns True如果 uri 不是 NULLFalse 否则。

文档中的说法不准确:

Returns TRUE if the new item was successfully added to the recently used resources list

因为返回TRUE只是说明调用了一个异步函数来处理新item的添加

正如 Laurence Gonsalves 所建议的,以下是伪同步运行的:

from gi.repository import Gtk, GObject

recent_mgr = Gtk.RecentManager.get_default()
uri = r'file:/path/to/my/file'
recent_mgr.add_item(uri)
GObject.idle_add(Gtk.main_quit)
Gtk.main()

这是我的解决方案(完整脚本),带有退出计时器 GTK.main() 循环

#!/usr/bin/env python3

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
import sys
import os
import subprocess

recent_mgr = Gtk.RecentManager.get_default()

if len(sys.argv) <= 1:
    paths = (os.getcwd(),)
else:
    paths = sys.argv[1:]

for path in paths:
    if os.path.exists(path):
        if path[0] != "/":
            path = os.getcwd() + "/" + path
        subprocess.call(["touch", "-a", path])
        uri = r"file:" + path
        recent_mgr.add_item(uri)

GLib.timeout_add(22, Gtk.main_quit, None)
Gtk.main()