关于 gtk3:GTK FileChooserDialog 选择文件和文件夹 (Vala)

GTK FileChooserDialog select files AND folders (Vala)

有什么方法可以让 FileChooserDialog 同时选择文件和文件夹?

我知道有 FileChooserAction OPEN 和 SELECT_FOLDER 但它们是独占的。

PD:我不想要两个按钮,我已经知道怎么做。我想要的是使用相同的按钮获取所有选定元素(文件和文件夹)的路由。


文件选择器操作与您想要的不同。我认为您在使用 set_select_multiple () 方法或 select_multiple 属性(均继承自 Gtk.FileChooser 接口)。

然后你可以使用 get_filenames ()get_uris () 方法,这取决于你的需要。

默认的 GtkFileChooserDialog 仅允许您在"最近""选项卡"上选择文件夹和文件,但只要您使用普通文件夹,它就不会让您这样做。

为了实现这一点,您必须通过组合解决方案或创建新小部件(例如,子类化 Gtk.FileChooserWidget 或 Gtk.Dialog)来使用 Gtk.FileChooserWidget。

我创建了一个简单的示例,它可以根据您的需要工作,并且您可以轻松更改以适应您的需要。

以下代码基于 Valadoc.org Gtk.FileChooserWidget 页面,可以满足您的要求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
public class Application : Gtk.Window {
    public Application () {
        // Prepare Gtk.Window:
        this.window_position = Gtk.WindowPosition.CENTER;
        this.destroy.connect (Gtk.main_quit);

        // VBox:
        Gtk.Box vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
        this.add (vbox);

        // HeaderBar:
        Gtk.HeaderBar hbar = new Gtk.HeaderBar ();
        hbar.set_title ("MyFileChooser");
        hbar.set_subtitle ("Select Files and Folders");

        // HeaderBar Buttons
        Gtk.Button cancel = new Gtk.Button.with_label ("Cancel");
        Gtk.Button select = new Gtk.Button.with_label ("Select");

        hbar.pack_start (cancel);
        hbar.pack_end (select);

        this.set_titlebar (hbar);

        // Add a chooser:
        Gtk.FileChooserWidget chooser = new Gtk.FileChooserWidget (Gtk.FileChooserAction.OPEN);
        vbox.pack_start (chooser, true, true, 0);

        // Multiple files can be selected:
        chooser.select_multiple = true;

        // Add a preview widget:
        Gtk.Image preview_area = new Gtk.Image ();
        chooser.set_preview_widget (preview_area);
        chooser.update_preview.connect (() => {
            string uri = chooser.get_preview_uri ();
            // We only display local files:
            if (uri.has_prefix ("file://") == true) {
                try {
                    Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file (uri.substring (7));
                    Gdk.Pixbuf scaled = pixbuf.scale_simple (150, 150, Gdk.InterpType.BILINEAR);
                    preview_area.set_from_pixbuf (scaled);
                    preview_area.show ();
                } catch (Error e) {
                    preview_area.hide ();
                }
            } else {
                    preview_area.hide ();
            }
        });

        // HBox:
        Gtk.Box hbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
        vbox.pack_start(hbox, false, false, 0);

        // Setup buttons callbacks
        cancel.clicked.connect (() => {
            this.destroy ();
        });

        select.clicked.connect (() => {
            SList<string> uris = chooser.get_uris ();
            foreach (unowned string uri in uris) {
                stdout.printf (" %s\
", uri);
            }
            this.destroy ();
        });
    }

    public static int main (string[] args) {
        Gtk.init (ref args);

        Application app = new Application ();
        app.show_all ();
        Gtk.main ();
        return 0;
    }
}

编译:

valac --pkg gtk+-3.0 Gtk.FileChooserDialog.vala

选择选择后,应用程序会将您的选择打印到控制台:

widget

转储(路径部分替换为 ...):

1
2
3
4
5
6
7
8
9
10
11
 file:///.../stackoverflow/3305/1
 file:///.../stackoverflow/3305/2
 file:///.../stackoverflow/3305/3
 file:///.../stackoverflow/3305/Gtk.FileChooserDialog
 file:///.../stackoverflow/3305/Gtk.FileChooserDialog.vala
 file:///.../stackoverflow/3305/Gtk.FileChooserWidget
 file:///.../stackoverflow/3305/Gtk.FileChooserWidget.vala
 file:///.../stackoverflow/3305/img1.jpg
 file:///.../stackoverflow/3305/img2.jpg
 file:///.../stackoverflow/3305/img3.jpg
 file:///.../stackoverflow/3305/Makefile