retireSakiの日記

たぶん引退した?ソフトウエアエンジニアのブログ

GTKmm の FileChooserDialog をただ表示するアプリ

今回は、Qt のファイルダイアログつながりで、GTKmm の FileChooserDialog を使ったサンプル (g++) です。

f:id:retireSaki:20180929070934j:plain

単にサンプルなので、FileChooserDialog を単独表示させます。
部分部分でなにかと参考になるコードだと思いますので、ご自身のコードの参考にしてください。


コンパイル&実行結果(terminal)は、こんな感じです。


    $ g++ main.cc -o fileChooser `pkg-config --cflags --libs gtkmm-3.0`
    $ ./fileChooser 700 400 740 600
    action: open or save
    selected count: 1
    selected: /home/xxxxxx/なてなBLOG/yyyyyyy/main.cc
    XYWH: 700,400,735,536
    $


●コードは下
(突貫で作成したサンプルなので、細かいバグは多めにみてw)

このサンプルプログラムでは、極小サイズのメインウィンドウを作成し、そこから FileChooserDialog を呼び出しています。

実行結果で表示される"XYWH:"値を使って実行時の引数にすれば、同じ位置に表示されます。
例えば、
x=700 y=400,w=740 h=600
であれば、
./fileChooser 700 400 740 600
というように。

難しいことはしていないので。Qt や GTK+ 経験者の方であれば、少しみれは分かると思います。

正直、FileChooserDialog は Qtより細かいことができるので好きです。
その分、コードも作業時間も増えますがww。
簡単にファイルダイアログを使いたいときは、Qt のほうが楽ですね。

こんなアプリでも少し改造すれば、使いみちがあるような、ないような(笑)。

 

sorce-code & icon(PNG) を圧縮したファイル(ZIP) を以下からダウンロードできます。 (Mediafire)
www.mediafire.com


source code: main.cc

/*
This application is a sample, please modify and use it.
This GTK application displays only FileChooserDialog and outputs the result
 as standard output.

This program was compiled and tested with `pkg-config gtkmm-3.0-cflags-libs`.

Since there is no copyright, this sample can be used freely.
But I will not be held responsible for any problems.
Based on the above, please fully utilize this sample.
thankyou.

*** compile sample ***
g++ main.cc -o fileChooser `pkg-config --cflags --libs gtkmm-3.0`

*** execute ***
$ ./fileChooser arg1 arg2 arg3 arg4
    arg1: pos(x) of base window
    arg2: pos(y) of base window
    arg3: width of FileChooserDialog
    arg4: height of FileChooserDialog

ex.
    $ ./fileChooser 761 443 740 600

notes:
    The display position of FileChooserDialog of this sample is based
    on the calculation result of GTK + 3.0 from the base window.

created by 2018.09 retireSaki.

*/

#include <gtkmm.h>
#include <iostream>
#include <gtkmm/application.h>

using namespace std;


class fileChooser : public Gtk::Window
{


public:
    fileChooser(int argc, char *argv[]);
    virtual ~fileChooser(){}

protected:
    sigc::connection  d_timeout;

    bool show_filedialog();

private:
    int nPos[4];    // x, y, w, h

};

bool fileChooser::show_filedialog()
{
    d_timeout.disconnect();


//    Gtk::FileChooserDialog *dialog;
    
    // *** Fix it necessary ***
    // open files(s)        =FILE_CHOOSER_ACTION_OPEN
    // save file            =FILE_CHOOSER_ACTION_SAVE
    // open or save folder    =FILE_CHOOSER_ACTION_SELECT_FOLDER
    Gtk::FileChooserDialog dialog("Please choose a file",
                                  Gtk::FILE_CHOOSER_ACTION_OPEN);

    dialog.set_transient_for(*this);
    dialog.move(nPos[0], nPos[1]);
    dialog.resize(nPos[2], nPos[3]);
    dialog.set_has_resize_grip(true);

    // add shurtcut folder
    dialog.add_shortcut_folder("/usr/share/icons");

    // single(false) or multiple(true)
    dialog.set_select_multiple(false);


    // *** Fix it necessary ***
    // add response buttons
    dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
    //dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);

    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);

    // *** Fix it necessary ***
    // only save
    //  do overwrite confirmation=true
    dialog.set_do_overwrite_confirmation(true);

    dialog.set_create_folders(true);


    // *** Fix it necessary ***
    // add response buttons
    //dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
    // open="_Open" , save="_Save"
    //dialog.add_button("_Open", Gtk::RESPONSE_OK);

    // add filters
    // *** Fix it necessary ***
    // select folder = use pattern("*")
    auto filter_text = Gtk::FileFilter::create();
    filter_text->set_name("text files");
    filter_text->add_mime_type("text/plain");
    dialog.add_filter(filter_text);

    auto filter_any = Gtk::FileFilter::create();
    filter_any->set_name("any files");
    filter_any->add_pattern("*");
    dialog.add_filter(filter_any);

    // show dialog
    int result = dialog.run();

    // handle the response:
    switch(result)
    {
        case(Gtk::RESPONSE_OK):
        {
            cout << "action: open or save" << std::endl;

            // *** Fix it necessary ***

            // only single select
            //std::string filename = dialog.get_filename();
            //std::cout << "selected: " <<  filename << std::endl;

            // single or multiple select
            std::vector<string> filenames=dialog.get_filenames();
            printf("selected count: %d", (int)filenames.size());
            cout << std::endl;
            cout << "selected: ";
            int ncnt=0;
            for (string& filename : filenames) {
                if (ncnt>0)
                    cout << " , ";
                cout << filename;
                ncnt++;
            }
            cout << std::endl;
            break;
        }
        case(Gtk::RESPONSE_CANCEL):
        {
            cout << "action: cancel" << std::endl;
            break;
        }
        default:
        {
            cout << "action: unexpected button" << std::endl;
            break;
        }

    }

    cout << "XYWH: ";
    int pos_x, pos_y;
    int size_w, size_h;
    get_position(pos_x, pos_y);
    dialog.get_size(size_w, size_h);
    printf("%d,%d,%d,%d\n", pos_x, pos_y, size_w, size_h);

    // aplication end
    close();

    return true;
}

// base window
fileChooser::fileChooser(int argc, char *argv[])
{
    // decorate of window
    set_decorated(false);

    // did not use this codes
    // opacity = 0.0
    GdkScreen *screen = gtk_widget_get_screen(Gtk::Widget::gobj());
    GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
    gtk_widget_set_visual(Gtk::Widget::gobj(),visual);

    Gdk::RGBA gdkrgba;
    gdkrgba.set_rgba(0.0,0,0,0.0);
    override_background_color(gdkrgba);

    // init pos & size
    nPos[0] = 0;    // base window pos(x)
    nPos[1] = 0;    // base window pos(y)
    nPos[2] = 800;  // FileChooserDialog width
    nPos[3] = 600;  // FileChooserDialog height

    for (int ni=1;ni < argc;ni++){
        if (strlen(argv[ni]) > 0)
            nPos[ni-1]=atoi(argv[ni]);
    }

    // move and resize
    move(nPos[0], nPos[1]);
    resize(1, 1);

    // call function of FileChooserDialog
    d_timeout = Glib::signal_timeout().connect(
        sigc::mem_fun(*this, &fileChooser::show_filedialog),
        100);

}

int main(int argc, char *argv[])
{
    Gtk::Main kit(argc, argv);

    // *** Fix it necessary ***
    // this application icon
    // comment out when icon is not used.
    Gtk::Window::set_default_icon_from_file( "./fileChooser.png" );

    fileChooser fcw(argc, argv);
    Gtk::Main::run(fcw);

    return 0;
}

GTK3, GTKmm はちょくちょく更新更新されていて、機能の追加や統合されています。
ネット上の情報やサンプルも古くなっていることが多く、海外だけでなく日本語のサイトも同様です。アプリを作成する際は、Developer help を確認するようにしましょう。

GTK3 , GTKmm でなにか良い本がないかと探しましたがありませんでした。

注目記事

「Amazon.co.jpアソシエイト」または「[乙の名称を挿入]は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。