Mar*_*cel 3 linux gtk clipboard uri vala
我目前正在尝试为我的应用程序实现复制和粘贴,问题是我只能根据以下文档将纯文本或图像写入剪贴板Gtk.Clipboard:https ://valadoc.org/gtk+-3.0/Gtk.Clipboard.htmlset_text/set_image.
但是还有这个方法https://valadoc.org/gtk+-3.0/Gtk.Clipboard.set_with_data.html set_with_data,我想我可以用来添加uri或uris数组.但我无法弄清楚如何也没有找到任何好的例子.
UPDATE
使用给定的答案我可以用一个uris数组填充剪贴板,但我可以阅读它们,当我尝试它只是get_func再次调用并重新填充它.
CTRL C pressed
clipboard get_func called
Received: file:///home/marcel/Downloads/.gitignore
CTRL V pressd
clipboard get_func called
Received: file:///home/marcel/Downloads
Try Pasting: file:///home/marcel/Downloads
Run Code Online (Sandbox Code Playgroud)
这是我用于测试的代码CTRL + V:
print ("\nCTRL V pressd\n");
clipboard.request_uris ((clipboard, uris) => {
foreach ( string content in uris ) {
print ("Try Pasting: ");
print (content);
print ("\n");
}
});
Run Code Online (Sandbox Code Playgroud)
这是get_funcfor 的相关部分CTRL + C:
clipboard.set_with_owner (
clipboard_targets,
(clipboard, selection_data, info, user_data_or_owner) => {
print ("clipboard get_func called\n");
var w = user_data_or_owner as Window;
File[] files = { w.get_selected_file () };
switch ( info ) {
case ClipboardProtocol.TEXT_URI_LIST:
print ("Received: ");
string[] uris = {};
foreach ( var file in files ) {
print (file.get_uri ());
print ("\n");
uris += file.get_uri ();
}
selection_data.set_uris (uris);
break;
Run Code Online (Sandbox Code Playgroud)
正如您在上面的终端输出中所看到的,它只是重新填充剪贴板,丢弃其先前的值.
小智 6
根据要求,我提供了一个将URI写入剪贴板并从剪贴板获取URI的示例.这些示例基本上是命令行程序,可以立即获取/设置剪贴板.在实际的GUI应用程序中,您可能会对按下按钮做出反应,或者在处理信号时捕获CtrlC/ CtrlV事件,使用Gtk.Widget.add_events()和获取/设置剪贴板Gtk.Widget.event.
您可以使用X11剪贴板请求URI Gtk.Clipboard.request_uris ().此函数采用一旦URI可用就会调用的回调.
例:
public void main (string[] args) {
Gtk.init (ref args);
Gdk.Display display = Gdk.Display.get_default ();
Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);
clipboard.request_uris (recieved_func);
Gtk.main ();
}
/* Gtk.ClipboardURIRecievedFunc */
private void recieved_func (Gtk.Clipboard clipboard, string[] uris) {
foreach (var uri in uris) {
print (uri + "\n");
}
Gtk.main_quit ();
}
Run Code Online (Sandbox Code Playgroud)
要编译 valac clipget.vala --pkg=gtk+-3.0
从Qt4文档:
由于在X11上的应用程序之间没有标准的复制和粘贴文件的方法,因此目前正在使用各种MIME类型和约定.例如,Nautilus希望文件提供x-special/gnome-copied-files MIME类型,其数据以剪切/复制操作,换行符和文件的URL开头.
Gtk.Clipboard没有预先设置剪贴板来复制/剪切文件.正如你所说,没有这样的Gtk.Clipboard.set_uris().
相反,您应该通过提供X11从一次请求获取剪贴板内容的回调来设置剪贴板.
这些是所需的步骤:
创建一堆Gtk.TargetEntrys,指定应用程序可以处理的剪贴板协议.你会想要处理协议text/uri-list,x-special/gnome-copied-files和UTF8_STRING.每个TargetEntry都由其info字段标识,因此该数字应该是唯一的(请参阅enum ClipboardProtocol下面的示例)
实现该类型的方法Gtk.ClipboardGetFunc.此方法应填充Gtk.SelectionData与文件路径一起传递的对象以进行复制/剪切.检查info参数以根据指定的协议设置SelectionData参数.
使用Gtk.Clipboard.set_with_owner或注册回调和为X11实现的协议Gtk.Clipboard.set_with_data
enum ClipboardProtocol {
TEXT_URI_LIST,
GNOME_COPIED_FILES,
UTF8_STRING
}
public void main (string[] args) {
Gtk.init (ref args);
Gdk.Display display = Gdk.Display.get_default ();
Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);
var clipboard_targets = new Gtk.TargetEntry[3];
Gtk.TargetEntry target_entry = { "text/uri-list", 0, ClipboardProtocol.TEXT_URI_LIST };
clipboard_targets[0] = target_entry;
target_entry = { "x-special/gnome-copied-files", 0, ClipboardProtocol.GNOME_COPIED_FILES };
clipboard_targets[1] = target_entry;
target_entry = { "UTF8_STRING", 0, ClipboardProtocol.UTF8_STRING };
clipboard_targets[2] = target_entry;
var owner = new Object ();
var rc = clipboard.set_with_owner (
clipboard_targets,
get_func,
clear_func,
owner
);
assert (rc);
clipboard.store ();
Gtk.main ();
}
/* Gtk.ClipboardGetFunc */
private void get_func (
Gtk.Clipboard clipboard,
Gtk.SelectionData selection_data,
uint info,
void* user_data_or_owner
) {
print ("GET FUNC!\n");
File my_file = File.new_for_path ("/home/lukas/tmp/test.txt");
File my_2nd_file = File.new_for_path ("/home/lukas/tmp/test2.txt");
File[] files = { my_file, my_2nd_file };
switch (info) {
case ClipboardProtocol.TEXT_URI_LIST:
string[] uris = {};
foreach (var file in files) {
uris += file.get_uri ();
}
selection_data.set_uris (uris);
break;
case ClipboardProtocol.GNOME_COPIED_FILES:
var prefix = "copy\n";
//var prefix = "cut\n";
/* use one of the above */
var builder = new StringBuilder (prefix);
for (int i = 0; i < files.length; i++) {
builder.append (files[i].get_uri ());
/* dont put the newline if this is the last file */
if (i != files.length - 1)
builder.append_c ('\n');
}
selection_data.set (
selection_data.get_target (),
8,
builder.data
);
break;
case ClipboardProtocol.UTF8_STRING:
var builder = new StringBuilder ();
foreach (var file in files) {
builder.append (file.get_parse_name ());
}
builder.append_c ('\n');
selection_data.set_text (builder.str, -1);
break;
default:
assert_not_reached ();
}
Gtk.main_quit ();
}
/* Gtk.ClipboardClearFunc */
private void clear_func (Gtk.Clipboard clipboard, void* data) {
;
}
Run Code Online (Sandbox Code Playgroud)
要编译 valac clipset.vala --pkg=gtk+-3.0
几个笔记:
在我的例子中,我只能测试,x-special/gnome-copied-files因为我现在只安装了Nautilus.我修改了Thunar源代码中的所有协议(参见下面的来源),但它们可能仍需要排除故障*
如果你不想自己解决这个问题,你也可以使用xclip命令行工具:https://askubuntu.com/a/210428/345569 但是,恕我直言,你自己实现这个更优雅.
| 归档时间: |
|
| 查看次数: |
307 次 |
| 最近记录: |