我正在测试一个gtk4小部件,它是GtkDropTarget。我计划设置一个拖动到窗口的图像作为窗口本身的图像。但是当我拖动图像文件时就会出现错误。需要明确的是,这是vala中的代码:
int main (string[] args) {
var app = new App();
return app.run(args);
}
public class App : Gtk.Application {
public App () {
Object (
application_id: "com.github.ea",
flags: ApplicationFlags.FLAGS_NONE
);
}
public override void activate () {
var window = new Window (this);
add_window (window);
}
}
public class Window : Gtk.ApplicationWindow {
public Window (Gtk.Application app) {
Object (application: app);
}
construct {
title = "Drag";
set_default_size (640, 480);
var drag_source = new DragSource ();
set_child (drag_source.self);
show ();
}
}
public class DragSource {
public Gtk.Image self;
public DragSource () {
self = new Gtk.Image ();
var drag_controller = new Gtk.DropTarget (GLib.Type.INVALID, Gdk.DragAction.COPY);
drag_controller.set_gtypes ({typeof(File)});
self.add_controller (drag_controller);
drag_controller.on_drop.connect (on_drop);
}
private bool on_drop (GLib.Value val, double x, double y) {
File filename = (File) val;
var file_path = filename.get_path ();
if (val.holds(typeof(File)) == true) {
print ("The dragged object is a file.\n");
if ("png" in file_path || "jpg" in file_path) {
print ("The dragged object is an image.\n");
self.set_from_pixbuf (pixbuf(file_path));
}
else {
print ("The dragged object is NOT an image.\n");
}
}
else {
print ("The dragged object is NOT a file.\n");
return false;
}
return true;
}
private Gdk.Pixbuf pixbuf (string file) {
try {
return new Gdk.Pixbuf.from_file (file);
} catch (Error e) {
error ("%s", e.message);
}
}
}
这将编译并运行。但是当我将图像文件拖到窗口时,就会出现错误并且图像不显示。这是所发生事情的图片。应该发生的是,当我从文件管理器中拖动一个 png 文件时,拖动的图像应该是 GtkImage 中显示的图像,它是窗口的主要小部件。
第一次从电脑中拖动图像文件时,出现此错误:
The dragged object is a file.
The dragged object is an image.
(v:3891): Gtk-CRITICAL **: 08:52:28.861: gtk_image_set_from_pixbuf: assertion 'GTK_IS_IMAGE (image)' failed
第二次拖动时,会显示:
(v:3891): Gdk-CRITICAL **: 08:53:33.388: gdk_drop_set_actions: assertion 'priv->state == GDK_DROP_STATE_NONE' failed
The dragged object is a file.
The dragged object is an image.
(v:3891): Gtk-CRITICAL **: 08:53:33.973: gtk_image_set_from_pixbuf: assertion 'GTK_IS_IMAGE (image)' failed
我真的很感激您的帮助。谢谢!
这就是我实现你的意图的方式
int main (string[] args) {
var app = new App ();
return app.run (args);
}
public class App : Gtk.Application {
public App () {
Object (
application_id: "com.github.ea",
flags : ApplicationFlags.FLAGS_NONE
);
}
public override void activate () {
var window = new Window (this);
window.present ();
}
}
public class Window : Gtk.ApplicationWindow {
public Window (Gtk.Application app) {
Object (application: app);
}
construct {
title = "Drag an Image!";
set_default_size (640, 480);
var image = new Gtk.Image ();
image.vexpand = image.hexpand = true;
var controller = new Gtk.DropTarget (typeof (GLib.File), Gdk.DragAction.COPY);
controller.on_drop.connect ((target, value, x, y) => {
var file = (GLib.File) value;
var filename = file.get_path ();
if (GLib.ContentType.guess (filename, null, null).contains ("image")) {
image.set_from_file (filename);
}
});
image.add_controller (controller);
set_child (image);
}
}
我也一直在寻找解决方案,我的结论是 GTK4 还不完整(还?)。我认为在 gtk4.0 中找到解决这个问题的机会几乎为零。甚至他们的演示应用程序(gtk4-demo-application 和 gtk4-widget-factory)也会产生相同的警告。