Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 限制用户可以在QFileDialog中选择的文件数量_C++_Qt_Qfiledialog - Fatal编程技术网

C++ 限制用户可以在QFileDialog中选择的文件数量

C++ 限制用户可以在QFileDialog中选择的文件数量,c++,qt,qfiledialog,C++,Qt,Qfiledialog,代码如下: dialog = new QFileDialog(this); dialog->setFileMode(QFileDialog::ExistingFiles); connect(dialog, SIGNAL(currentChanged(const QString&)), this, SLOT(dialogSelectionChanged(const QString&))); void MainWindow::dialogSelectionChange

代码如下:

dialog = new QFileDialog(this);
dialog->setFileMode(QFileDialog::ExistingFiles);
connect(dialog, SIGNAL(currentChanged(const QString&)),
    this, SLOT(dialogSelectionChanged(const QString&)));

void MainWindow::dialogSelectionChanged(const QString& file)
{
    QStringList selected = dialog->selectedFiles();
}
问题是

  • fileSelected(const-QString&)
    fileSelected(const-QStringList&)
    仅在我按下“打开”按钮后发出
  • currentChanged(const QString&)
    只传递新选择的文件
  • 在这种情况下,
    selectedFiles()
    返回在上一步中选择的文件。对话框可能会在发出
    currentChanged(const QString&)
    后更新文件
这就是为什么我不知道如何跟踪当前选定的文件。 另一个问题是,到目前为止,我不知道如果用户超出允许选择的限制,如何取消最后选择的文件的选择


我见过几个例子,其中人们使用
QProxyModel
或使用
QFileDialog
的自定义实现来实现自定义功能,但我不确定什么最适合我的需要。

没有方法,但只要客户完成选择,您就可以通过调用方法

如果QStringList的大小大于约束,则可以中止操作并显示一些错误消息


如果您愿意接受无耻的黑客攻击,则可以这样做:-)

假设以下代码

QFileDialog fd;
使用
fd.findChildren()
检查
fd
会发现它有两个子项,它们要么是从
QListView
继承的,要么是从
QListView
继承的

  • 名为listView的QListView
  • QSidebar命名为sidebar
  • (其中QSidebar是Qt专有的)

    假设名为
    listView
    QListView
    是您感兴趣的小部件,您可以将回调连接到其选择模型

    QFileDialog fd;
    for (const auto &i: fd.findChildren<QListView *>("listView")) {
      auto *sm = i->selectionModel();
      QObject::connect(sm, &QItemSelectionModel::selectionChanged,
                       [sm](const QItemSelection &selected, const QItemSelection &deselected)
                         {
    
                           /*
                            * Here we pass a hard-coded max selected items
                            * value of 5 to the real callback/slot.
                            */
                           handle_selection_updated(5, sm, selected, deselected);
                         });
    }
    

    我只是简单地测试了上面的代码,但它的行为似乎符合要求。

    您是否尝试覆盖
    selectFile(const QString&filename)
    ?可能就是你要找的那个。从文档中看,它看起来不像是一个虚拟函数。不是,我已经检查了源代码。此外,这个方法并没有在实现中使用,它只是用户API的一部分,如果找不到更好的解决方案,我将使用它。谢谢除非您自己编写对话框,否则没有其他对话框“\_(ツ)_/¯
    QFileDialog fd;
    for (const auto &i: fd.findChildren<QListView *>("listView")) {
      auto *sm = i->selectionModel();
      QObject::connect(sm, &QItemSelectionModel::selectionChanged,
                       [sm](const QItemSelection &selected, const QItemSelection &deselected)
                         {
    
                           /*
                            * Here we pass a hard-coded max selected items
                            * value of 5 to the real callback/slot.
                            */
                           handle_selection_updated(5, sm, selected, deselected);
                         });
    }
    
    void handle_selection_updated (int selection_max, QItemSelectionModel *sm,
                                   const QItemSelection &selected,
                                   const QItemSelection &deselected)
    {
    
      /*
       * We need to remember the last valid selection.  The following
       * is declared static in this simple case but would generally be
       * a class member in `real' code.
       */
      static QItemSelection last_selected;
    
      /*
       * Because we update the selection model `sm' from within this
       * slot this function will recurse which will cause problems if
       * we don't detect it and take appropriate action.
       */
      static bool recursing = false;
      if (recursing)
        return;
    
      /*
       * If the number of rows selected is greater than the value
       * specified by `selection_max' then revert to the last valid
       * selection as specified by `last_selected'.
       */
      if (sm->selectedRows().size() > selection_max) {
    
        /*
         * The following call to QItemSelectionModel::clearSelection
         * will result in a recursive call to this function.  Set
         * `recursing' to true to catch this and avoid associated
         * problems.
         */
        recursing = true;
    
        /*
         * Now clear the selection and reset it to the items from
         * `last_selected'.
         */
        sm->clearSelection();
        for (const auto &i: last_selected.indexes()) {
          sm->select(i, QItemSelectionModel::Select);
        }
        recursing = false;
      }
    
      /*
       * Update `last_selected'.
       */
      last_selected = sm->selection();
    }