C ++ Выбрать папку, Включить файлы - PullRequest
0 голосов
/ 14 февраля 2019

В настоящее время я работаю над приложением qt для Windows.Пользователь должен иметь возможность выбрать каталог для загрузки всех файлов.У меня возникла проблема, связанная с этим.Это кажется довольно глупым, но я продолжаю получать те же отзывы.Конечные пользователи смущаются диалоговым окном файлов, потому что они переходят к папке, но она не показывает никаких файлов.Даже если они выбирают папку, это сбивает их с толку, чтобы они не видели файлы в каталоге.

Так что я решил покопаться в этом и провести небольшое исследование.Из того, что я обнаружил, кажется, что есть в основном 2 варианта.IFileOpenDialog с FOS_PICKFOLDERS, который я сейчас использую через qt's QFileDialog.Или SHBrowseForFolder, который работает, но довольно ограничен.

Я что-то упустил?Кажется, что IFileOpenDialog, который показывает файлы, не позволяя пользователю выбирать их, был бы идеальным.Есть ли способ сделать это?Я нашел много более старой информации о том, что это невозможно, но нет ничего более определенного, чем более свежая.

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Основная проблема заключается в том, что, как указано в документации, диалоговое окно собственных файлов Windows не поддерживает отображение файлов и каталогов только при выборе каталогов (отметьте этот другой связанный ответ тоже).Для QFileDialog::FileMode::Directory:

Имя каталога.Оба файла и каталоги отображаются.Тем не менее, собственное диалоговое окно файлов Windows не поддерживает отображение файлов в средстве выбора каталогов.

Одним из обходных путей является использование не родного диалогового окна файлов для этого типа выбора, но, лично, это выглядит ужасноесли он должен жить вместе с другими собственными диалоговыми окнами файлов.

Здесь приведено быстрое сравнение двух способов выбора каталога с использованием QFileDialog::getExistingDirectory вручную путем создания экземпляра QFileDialog и с использованием собственного IFileDialog:

#include <qapplication.h>
#include <qfiledialog.h>
#include <qdebug.h>
#include <Windows.h>
#include <shobjidl.h>

void using_IFileDialog()
{
  IFileOpenDialog* pFileOpen;
  HRESULT hr;

  // Create the FileOpenDialog object.
  hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
                        IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

  if (SUCCEEDED(hr)) {
    // Show the Open dialog box.
    pFileOpen->SetOptions(FOS_PICKFOLDERS | FOS_PATHMUSTEXIST);
    hr = pFileOpen->Show(NULL);

    // Get the file name from the dialog box.
    if (SUCCEEDED(hr)) {
      IShellItem* pItem;
      hr = pFileOpen->GetResult(&pItem);
      if (SUCCEEDED(hr)) {
        PWSTR pszFilePath;
        hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

        // Display the file name to the user.
        if (SUCCEEDED(hr)) {
          MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
          CoTaskMemFree(pszFilePath);
        }
        pItem->Release();
      }
    }
    pFileOpen->Release();
  }
}

int main(int argc, char* argv[])
{
  QApplication a(argc, argv);

  const auto dir_1 = QFileDialog::getExistingDirectory(nullptr, "getExistingDirectory (dirs only)");
  qDebug() << dir_1;

  QFileDialog dlg(nullptr, "QFileDialog::DontUseNativeDialog");
  dlg.setFileMode(QFileDialog::Directory);
  dlg.setOption(QFileDialog::DontUseNativeDialog);
  if (dlg.exec() == QFileDialog::Accepted) {
    const auto dir_2 = dlg.directory().absolutePath();
    qDebug() << dir_2;
  }

  using_IFileDialog();

  return 0;
}
0 голосов
/ 15 февраля 2019

Несмотря на SHBrowseForFolder ошибок, я бы на 100% предпочел это, поскольку случайный пользователь наверняка запутается в IFileOpenDialog, когда он видит только пустую область.Даже сам я иногда путаюсь.Его также проще кодировать.

Я всегда использую его с BIF_EDITBOX, чтобы опытные пользователи могли быстро набирать путь, а также всегда использую его в другом диалоговом окне, в котором есть предварительно выбранный путь иКнопка «Изменить папку».

0 голосов
/ 14 февраля 2019

Вы пробовали диалог файла QML FileDialog с selectFolder: true?Поскольку документация Qt5 гласит

Реализация FileDialog будет диалоговым окном файла платформы, если это возможно.Если это невозможно, то он попытается создать экземпляр QFileDialog.

это может быть более удобным для пользователей для наборов каталогов, поскольку он использует больше собственных диалогов, чем QFileDialog.Я попробовал его на MacOS, где он отлично показывает желаемое поведение, но у меня нет машины для разработки Windows поблизости, но я нашел минимальный прикрепленный проект:

main.qml:

import QtQuick 2.2
import QtQuick.Controls 1.0
import QtQuick.Dialogs 1.2

ApplicationWindow
{
    visible: true
    width: 640
    height: 480
    title: qsTr("Minimal Qml")
    FileDialog {
        id: fileDialog
        title: "Please choose a directory"
        selectFolder: true
        folder: shortcuts.home
        onAccepted: {
            console.log("You chose: " + fileDialog.fileUrls)
            Qt.quit()
        }
        onRejected: {
            console.log("Canceled")
            Qt.quit()
        }
        Component.onCompleted: visible = true
    }
}   

main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("main.qml")));
    return app.exec();
}

qml.qrc

<RCC>
    <qresource prefix="⁄">
        <file>main.qml</file>
    </qresource>
</RCC>

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(untitled1)

set(CMAKE_CXX_STANDARD 14)

find_package(Qt5 COMPONENTS Widgets Qml Quick REQUIRED)


include_directories(${Qt5Widgets_INCLUDE_DIRS} ${QtQml_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS} ${QtQml_DEFINITIONS} ${${Qt5Quick_DEFINITIONS}})
qt5_add_resources(QT_RESOURCES qml.qrc)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(PROJECT "MinimalQml")

configure_file(main.qml main.qml COPYONLY)

add_executable(${PROJECT} main.cpp ${QT_RESOURCES})
target_link_libraries(${PROJECT}
        Qt5::Widgets
        Qt5::Qml
        Qt5::Quick
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...