#python #gtk #pygtk #gtk3
#python #gtk #pygtk #gtk3
Вопрос:
Я пытаюсь добавить в список «недавно использованных» файлов из Python 3 в Ubuntu.
Я могу успешно прочитать список недавно использованных файлов следующим образом:
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')
… файл не отображается в разделе «Последние» Nautilus или в диалоговых окнах файлов. Он даже не отображается в результатах, возвращаемых get_items()
.
Как я могу добавить файл в список недавно использованных файлов GTK из Python?
Комментарии:
1. @oldtechaa Список последних файлов, которые видит Nautilus, и диалоговое окно файла в других приложениях (включая GIMP, Inkscape и даже Chrome) кажутся идентичными. Многие приложения по умолчанию фильтруют список по своему типу файлов, но если вы измените фильтр на «Все файлы», вы увидите точно такой же список, который показывает Nautilus, и который отображается кодом в вопросе.
2. Что
add_item()
возвращает?3. Возвращает вызов @andlabs
add_item()
True
. (На самом деле, is, кажется, всегда возвращаетсяTrue
, даже если URI, который я передаю ему, не существует или полная бессмыслица. Единственное исключение — если я передаю его не-str
. Затем он возникаетTypeError
.)4. Возможно, нет, хотя, увидев, что
add_item()
возвращает true, можно предположить, что это что-то другое. Может ли это каким-то образом получить неправильный файл истории? Если он возвращает true, это говорит о том, что ему удалось его где-то записать.5. @andlabs Это связано с использованием асинхронного кода, чтобы избежать
g_content_type_guess
блокирования потока программы, я думаю, см. Мой ответ ниже.
Ответ №1:
A Gtk.RecentManager
должен выдать changed
сигнал для записи обновления в закрытый атрибут класса C . Чтобы использовать 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
завершения, поэтому метод просто возвращает True
, если объект, из которого он вызывается, является a RecentManager
, и если uri не NULL
является; и False
в противном случае.
В документации неточно указано:
Возвращает
TRUE
, если новый элемент был успешно добавлен в список недавно использованных ресурсов
поскольку возврат TRUE
означает только то, что была вызвана асинхронная функция для обработки добавления нового элемента.
Как было предложено Лоуренсом Гонсалвесом, следующее выполняется псевдосинхронно:
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()
Ответ №2:
Это мое решение (сценарий завершения) с таймером для завершения 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()