GTK FileChooserDialog select 个文件和文件夹 (Vala)

GTK FileChooserDialog select files AND folders (Vala)

有什么方法可以使 FileChooserDialog select 既是文件又是文件夹?

我知道有 FileChooserAction OPEN 和 SELECT_FOLDER 但它们是排他性的。

PD:我不想要两个按钮,我已经知道怎么做了。我想要的是使用同一个按钮获取所有 selected 元素(包括文件和文件夹)的路径。

文件选择器操作与您想要的不同。我认为你是在 set_select_multiple () method or the select_multiple 属性 之后(都继承自 Gtk.FileChooser 接口)。

然后就可以根据需要使用方法get_filenames () or get_uris ()了。

默认的 GtkFileChooserDialog 只允许您 select 文件夹和文件,如果您在最近 "tab" 上,但是一旦您使用普通文件夹,它就不允许您这样做。

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

我已经创建了一个简单的示例,它可以按您的需要运行,并且您可以轻松地进行更改以满足您的需要。

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

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\n", 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

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

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

 file:///.../Whosebug/3305/1
 file:///.../Whosebug/3305/2
 file:///.../Whosebug/3305/3
 file:///.../Whosebug/3305/Gtk.FileChooserDialog
 file:///.../Whosebug/3305/Gtk.FileChooserDialog.vala
 file:///.../Whosebug/3305/Gtk.FileChooserWidget
 file:///.../Whosebug/3305/Gtk.FileChooserWidget.vala
 file:///.../Whosebug/3305/img1.jpg
 file:///.../Whosebug/3305/img2.jpg
 file:///.../Whosebug/3305/img3.jpg
 file:///.../Whosebug/3305/Makefile