如何使用Python向GTK的“最近使用”文件列表中添加项目?

21

我正在尝试在Ubuntu上使用Python 3将文件添加到“最近使用”的文件列表中。

我能够成功地像这样读取最近使用的文件列表:

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

这将打印出与我在Nautilus中查看“最近”或查看应用程序(如GIMP)的文件对话框中的“最近使用”位置看到的相同文件列表。

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

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

即使使用get_items()函数返回的结果,该文件也无法在Nautilus的“最近”部分或文件对话框中显示。我该如何从Python中将文件添加到GTK的最近使用文件列表中?


1
@oldtechaa Nautilus最近查看的文件列表和其他应用程序(包括GIMP,Inkscape甚至Chrome)中的文件对话框似乎是相同的。许多应用程序默认将列表过滤为自己的文件类型,但如果您将过滤器更改为“所有文件”,则会看到与Nautilus显示的完全相同的列表,并且该列表由问题中的代码显示。 - Laurence Gonsalves
add_item() 返回什么? - andlabs
也许不是这样,因为add_item()返回true会暗示它是其他问题。它可能会错误地选择了错误的历史文件吗?如果它返回true,则表明它已成功将其写入某个位置。 - OrderAndChaos
我真正关心的问题与你的代码无关,而是为什么add_item()不使用GError,而GtkRecentManager的每个其他方法都在使用。我会稍后询问这个问题;也许GTK +的开发人员能够猜出发生了什么... - andlabs
1
@andlabs 这是由于使用异步代码来避免g_content_type_guess阻塞程序流程,我认为,见下面我的回答。 - Jacques Gaudin
显示剩余5条评论
2个回答

18

为了将更新写入 C++ 类的私有属性中,Gtk.RecentManager 需要发出 changed 信号。要在应用程序中使用 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 返回布尔值是因为调用了 g_file_query_info_async 函数。回调函数 gtk_recent_manager_add_item_query_info 然后将 mimetype、应用程序名称和命令收集到一个 GtkRecentData 结构中,最后调用 gtk_recent_manager_add_full。源码在此处

如果出现任何问题,那么都会在 add_item 完成之后才会出现,所以该方法只有在被调用的对象是 RecentManager 并且 uri 不为 NULL 时返回 True,否则返回 False

文档说法不准确:

返回 TRUE 如果新项成功添加到最近使用的资源列表中

因为返回 TRUE 仅意味着异步函数被调用以处理新项的添加。

如 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()

1

这是我的解决方案(完整脚本),带有计时器退出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()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接