将文件从我的 GTK 应用程序拖到另一个应用程序(而不是相反)

Drag a file from my GTK app to another app (not the other way around)

我搜索了示例,但所有示例都是相反的方向(我的应用程序正在从另一个应用程序中拖放文件)。但这一定是可能的,因为我可以将文件从文件 (Nautilus) 拖到另一个应用程序文本编辑器 (gedit)。

你能给我看一个非常简单的 GTK 示例 Window 上面有一个小部件,当我从小部件拖动到文本编辑器时,它会在系统上传递一个文本文件(例如 /home/user/.profile) 到文本编辑器,以便它打开文本文件?

为了使您的应用程序可以接收 文件,您需要使用 uri。在您绑定到 drag-data-received 的函数中,您可以使用 data.get_uris() 来获取已删除文件的列表。确保调用 drag_dest_add_uri_targets(),以便小部件可以接收 URI。

此代码示例有一个按钮可以拖动文件,另一个按钮可以接收文件。您还可以将文件拖放到任何 file-receiving 应用程序中,例如 gedit(文本编辑器)或 VSCode.

import gi
gi.require_version("Gdk", "3.0")
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk

window = Gtk.Window()
window.connect("delete-event", Gtk.main_quit)

box = Gtk.HBox()
window.add(box)

# Called when the Drag button is dragged on
def on_drag_data_get(widget, drag_context, data, info, time):
    data.set_uris(["file:///home/user/test.html"])

# Called when the Drop button is dropped on
def on_drag_data_received(widget, drag_context, x, y, data, info, time):
    print("Received uris: %s" % data.get_uris())

# The button from which the file is dragged
drag_button = Gtk.Button(label="Drag")
drag_button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.LINK)
drag_button.drag_source_add_uri_targets() # This makes sure that the buttons are using URIs, not text
drag_button.connect("drag-data-get", on_drag_data_get)
box.add(drag_button)

# The button into which the file can be dropped
drop_button = Gtk.Button(label="Drop")
drop_button.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.LINK)
drop_button.drag_dest_add_uri_targets() # This makes sure that the buttons are using URIs, not text
drop_button.connect("drag-data-received", on_drag_data_received)
box.add(drop_button)

window.show_all()
Gtk.main()

Kruin 先生的回答是针对 Python 的 GTK。我真正想要的语言是 C#。使用他的代码作为提示,我像这样修改了默认的 GtkApplication 项目,并且它在 Linux.

上工作
private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow"))
{
    builder.Autoconnect(this);

    DeleteEvent += Window_DeleteEvent;

    _button1.DragDataGet += (o, args) =>
    {
        args.SelectionData.SetUris(new string[]{fullFilePath});
    };

    Gtk.Drag.SourceSet(_button1, Gdk.ModifierType.Button1Mask,
        new TargetEntry[0],
        Gdk.DragAction.Link);

    Gtk.Drag.SourceAddUriTargets(_button1);
}

在 Windows 上,但是,它不起作用。我已经尝试了 string fullFilePath = "file:///c:/windows/win.ini"string fullFilePath = "c:\windows\win.ini",其中 none 似乎有效。