QFileDialog that accepts a single file or a single directory

前端 未结 4 1361
有刺的猬
有刺的猬 2021-02-13 23:46

Is it possible to show a QFileDialog where the user can select a file or a directory, either one?

QFileDialog::getOpenFileName() accepts only files, while

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-14 00:37

    QFileDialog currently does not support this. I think the main problem for you here is that the FileMode is not a Q_FLAGS and the values are not power of 2, either, and so, you cannot write this to solve this issue.

    setFileMode(QFileDialog::Directory|QFileDialog::ExistingFiles)
    

    To solve this, you would need quite a bit of fiddling, e.g.:

    • Override the open button click operation.

    • Get the "treeview" indices properly for both files and directories.

    My attempt below demonstrates the former, but I did not really go as far as solving the second because that seems to involve some more fiddling with the selection model.

    main.cpp

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    class FileDialog : public QFileDialog
    {
        Q_OBJECT
        public:
            explicit FileDialog(QWidget *parent = Q_NULLPTR)
                : QFileDialog(parent)
            {
                setOption(QFileDialog::DontUseNativeDialog);
                setFileMode(QFileDialog::Directory);
                // setFileMode(QFileDialog::ExistingFiles);
                for (auto *pushButton : findChildren()) {
                    qDebug() << pushButton->text();
                    if (pushButton->text() == "&Open" || pushButton->text() == "&Choose") {
                        openButton = pushButton;
                        break;
                    }
                }
                disconnect(openButton, SIGNAL(clicked(bool)));
                connect(openButton, &QPushButton::clicked, this, &FileDialog::openClicked);
                treeView = findChild();
            }
    
            QStringList selected() const
            {
                return selectedFilePaths;
            }
    
        public slots:
            void openClicked()
            {
                selectedFilePaths.clear();
                qDebug() << treeView->selectionModel()->selection();
                for (const auto& modelIndex : treeView->selectionModel()->selectedIndexes()) {
                    qDebug() << modelIndex.column();
                    if (modelIndex.column() == 0)
                        selectedFilePaths.append(directory().absolutePath() + modelIndex.data().toString());
                }
                emit filesSelected(selectedFilePaths);
                hide();
                qDebug() << selectedFilePaths;
           }
    
        private:
            QTreeView *treeView;
            QPushButton *openButton;
            QStringList selectedFilePaths;
    };
    
    #include "main.moc"
    
    int main(int argc, char **argv)
    {
        QApplication application(argc, argv);
        FileDialog fileDialog;
        fileDialog.show();
        return application.exec();
    }
    

    main.pro

    TEMPLATE = app
    TARGET = main
    QT += widgets
    CONFIG += c++11
    SOURCES += main.cpp
    

    Build and Run

    qmake && make && ./main
    

提交回复
热议问题