retireSakiの日記

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

Qt QFileDialog のサイドバー表示フォルダーをGTKのbookmarksを使って、ほぼ同じようにするサンプルコード

 QtのQFileDialogは、どうしようもなく使いづらいく、エンドユーザーも含めて不評です。
その原因も一つがサイドバーです。


 そこで、GTKを使ったデスクトップ環境限定ですが、QtのQFileDialogのサイドバーをGTK環境のオープンファイルダイアログに近い状態にするサンプルコードを作りました。
あくまでも私の環境のUbuntuでのテストコードなので、Windowsなど他のOSなどでは若干の手直しが必要になるかもしれません。
 また、このアプリの作成途中でテストしたので、ソースファイル等は公開しませんので、ご了承ください。

retiresaki.hatenablog.com
※リンク忘れで追加 (2019/03/03 13:59)

サンプルコード


sample.cpp

QString MainWindow::getOpenFilename()
{
    QFileDialog dlgfile(this);
    dlgfile.setOptions(QFileDialog::ReadOnly|QFileDialog::DontUseNativeDialog);
    dlgfile.setWindowTitle(tr("Open File"));
    dlgfile.setDirectory(init_path);
    dlgfile.setNameFilter(tr("ALL file (*.*)"));

    QSize size=dlgfile.size();
    dlgfile.resize(820,size.height());

    QList<QUrl> urls = getGTKbookmarks();
    if (urls.length() > 0){
        dlgfile.setSidebarUrls(urls);
    }

    int nrtn = dlgfile.exec();
    if (nrtn == 0){
        return "";
    }

    return dlgfile.selectedFiles()[0];
}

QList<QUrl> MainWindow::getGTKbookmarks()
{
    QList<QUrl> urls;
    urls.clear();

    QString dirPath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation)[0];

    QStringList nameFilters;
    nameFilters << "bookmarks";

    QDir::Filters filters = QDir::Files;
    QDirIterator::IteratorFlags flags = QDirIterator::Subdirectories;

    QDirIterator it(dirPath, nameFilters, filters, flags);
    QStringList files;
    while (it.hasNext())
    {
        QString file = it.next();
        if (file.indexOf("gtk") >= 0){
            files << file;
            qDebug() << file;
            break;
        }
    }

    QStringList list;

    QFile file(files[0]);
    if (file.open(QIODevice::ReadOnly)) {
        QTextStream in(&file);

        while (!in.atEnd()) {
            QString str = in.readLine().trimmed();
            //qDebug() << in.readLine();
            if (str.length() > 0)
                list << str;
        }
        file.close();
    }

    urls << QUrl("file://"+QStandardPaths::standardLocations
		(QStandardPaths::HomeLocation)[0]);
    urls << QUrl("file://"+QStandardPaths::standardLocations
		(QStandardPaths::DesktopLocation)[0]);
    for (int ni = list.length()-1;ni > list.length()-6;ni--){
        QStringList list2 = list[ni].split(" ");
        urls << QUrl(list2[0]);
    }
    for (int ni = 0;ni < list.length()-5;ni++){
        QStringList list2 = list[ni].split(" ");
        urls << QUrl(list2[0]);
    }

    return urls;
}

動作させた状態でのスクリーンショット

 以下のスクリーンショットUbuntu 18.04 LTSで動作させたものです。

GTKのオープンファイルダイアログ

Qtのオープンファイルダイアログ


解説

 nautilusなどのGTK環境のファイルマネージャーの多くは、
  Ubuntu 場合:"home/.config/gtk-3.0/bookmarks"
に保存されます。

また、booknarksの中は、
  file://〜
というように、URL形式で保存されます。
これには、初期標準で表示されるフォルダーも含まれています。

 これを解析したところで、

 ・前半部分はユーザーが追加したブックマークフォルダーが並び順
 ・後半部分は初期標準で設定されたブックマークフォルダーが逆の並び順

となっていました。
この辺りに関する処理がこのサンプルコードを不確定とする部分で、修正しなければならない箇所になると思います。

 これらの情報を元に、

(1) QDirIterator を使って、GTKbookmarksファイルを探します。

(2) QFileDialogsetSidebarUrlsQList<QUrl> で設定するため、
 (2.1) bookmarksの後半部分をファイルを降順に読み出す
 (2.2) bookmarksの前半部分をファイルを昇順に読み出す
ということをしています。

(3) 取得した QList<QUrl>QFileDialogsetSidebarUrls で設定します。

これで、ほぼ GTK のファイルダイアログに近い状態にすることができました。

Qtの QFileDialog がもっとしっかり作ってあれば、こんなことしなくても済むのですが...(^^ゞ

現場ですぐに使える!  C/C++逆引き大全 560の極意

現場ですぐに使える! C/C++逆引き大全 560の極意

Qtプログラミング入門―使いやすいフレームワークを基礎から解説 (I・O BOOKS)

Qtプログラミング入門―使いやすいフレームワークを基礎から解説 (I・O BOOKS)

24時間集中講座 Qtプログラミング

24時間集中講座 Qtプログラミング

  • 作者: ダニエルソーリン,Daniel Solin,アットコム
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2001/05
  • メディア: 単行本
  • 購入: 1人 クリック: 9回
  • この商品を含むブログ (2件) を見る
Gtk+3入門

Gtk+3入門

注目記事

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