python - 使用 freedesktop 门户使用 Python 截屏
问题描述
我一直在尝试用 python 编写一个 flatpak 应用程序,它使用 freedesktop 门户来截取屏幕截图。我正在调整 Gimp 的 freedesktop screenshot 插件,它是用 c 编写的,在获取截图并与我的应用程序共享后,我遇到了麻烦。我得到一个 '/org/freedesktop/portal/desktop/request/1_326/t' 形式的 uri,freedesktop 门户文档说 uri 指向安装在 run/user/$UID/doc/ 和我可以确认屏幕截图已保存在那里。但是,我似乎无法为它们获取有用的标识符,以便我可以使用我的应用程序将它们附加到电子邮件中。
我已经尝试了 freedesktop Documents 门户中的所有方法,但都没有成功。在调用一个 dbus 代理后,该代理返回一个保存在 opath 变量中的 uri,Gimp 实现设置另一个 dbus 代理,然后将该代理连接到此处的回调函数:我从中复制这些片段的完整文件可在此处获得 << a href="https://github.com/GNOME/gimp/blob/master/plug-ins/screenshot/screenshot-freedesktop.c" rel="nofollow noreferrer">https://github.com/GNOME/gimp /blob/master/plug-ins/screenshot/screenshot-freedesktop.c>
if (opath)
{
GDBusProxy *proxy2 = NULL;
proxy2 = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
NULL,
"org.freedesktop.portal.Desktop",
opath,
"org.freedesktop.portal.Request",
NULL, NULL);
*image_ID = 0;
g_signal_connect (proxy2, "g-signal",
G_CALLBACK (screenshot_freedesktop_dbus_signal),
image_ID);
gtk_main ();
g_object_unref (proxy2);
g_free (opath);
screenshot_freedesktop_dbus_signal 函数如下所示:
static void
screenshot_freedesktop_dbus_signal (GDBusProxy *proxy,
gchar *sender_name,
gchar *signal_name,
GVariant *parameters,
gint32 *image_ID)
{
if (g_strcmp0 (signal_name, "Response") == 0)
{
GVariant *results;
guint32 response;
g_variant_get (parameters, "(u@a{sv})",
&response,
&results);
/* Possible values:
* 0: Success, the request is carried out
* 1: The user cancelled the interaction
* 2: The user interaction was ended in some other way
* Cf. https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.Request.xml
*/
if (response == 0)
{
gchar *uri;
if (g_variant_lookup (results, "uri", "s", &uri))
{
GFile *file = g_file_new_for_uri (uri);
gchar *path = g_file_get_path (file);
*image_ID = gimp_file_load (GIMP_RUN_NONINTERACTIVE,
path, path);
gimp_image_set_filename (*image_ID, "screenshot.png");
/* Delete the actual file. */
g_file_delete (file, NULL, NULL);
g_object_unref (file);
g_free (path);
g_free (uri);
}
}
g_variant_unref (results);
gtk_main_quit ();
}
}
在回调函数之前,我的代码以相同的方式工作。我找不到 g_signal_connect 函数的 pythonic 等效项。我试过像这样将回调添加到新代理的初始化中
proxy2 = Gio.DBusProxy.new_for_bus(Gio.BusType.SESSION,
Gio.DBusProxyFlags.NONE,
None,
"org.freedesktop.portal.Desktop",
returned_uri[0],
"org.freedesktop.portal.Request",
None,
G_CALLBACK(self.receive_screenshot_signal),
None)
但是我的 receive_screenshot_signal 函数没有传递任何值,并且传入的任务对象说它们没有完成。
我不确定从这里去哪里,所以任何关于如何更有效地使用 dbusproxy 库和/或 freedesktop 门户的建议或见解将不胜感激。谢谢!
解决方案
我通过订阅请求句柄路径上来自总线的信号解决了这个问题。
args = GLib.Variant('(sa{sv})', (filename, {}))
result = self.proxy.call_sync('Screenshot',
args,
Gio.DBusCallFlags.NONE,
-1,
None)
request_handle = result.unpack()[0]
self.bus.signal_subscribe("org.freedesktop.portal.Desktop",
"org.freedesktop.portal.Request",
"Response",
request_handle,
None,
Gio.DBusSignalFlags.NO_MATCH_RULE,
self.receive_screenshot_signal)
我在 Gio.bus.signal_subscribe 上找不到任何特定文档,但这里是回调函数如何处理返回:
def receive_screenshot_signal(self,
connection,
sender,
path,
interface,
signal,
params):
if not isinstance(params, GLib.Variant):
print("It's not a variant")
return
response_code, results = params.unpack()
# Response code 0 signifies success
if response_code != 0 or 'uri' not in results:
print("Error taking screenshot")
return
parsed_uri = urlparse(results['uri'])
assert parsed_uri.scheme == "file"
self.screenshot = unquote(parsed_uri.path)
推荐阅读
- javascript - 脚本执行暂停时如何在chrome devtools中运行异步代码?
- r - 在 R 中创建新变量
- postgresql - Trigram 索引 ORDER BY 优化
- react-native - 在 Android Pay 流程 (getPaymentToken) 之后,支付令牌变得未定义
- ruby-on-rails - 如果控制器方法导致外部服务修改数据库,我应该使用 GET 还是 POST?
- javascript - documentFragment 转换为 JSON 格式
- git - 如何在从 Github 存储库安装包时包含提交哈希?
- javascript - Javascript位操作问题
- google-analytics - 有没有办法加密/解密或混淆/去混淆传递给 Google 跟踪代码管理器的数据?
- unity3d - 为什么统一 iap 在导入 google play 游戏服务后无法工作