QTreeView / QFileSystemModel / QLineEdit的奇怪行为

时间:2016-10-14 13:30:38

标签: c++ qt qtreeview qlineedit qfilesystemmodel

我有一个QTreeView链接到QFileSystemModel。我还有一个有两个目的的QLineEdit:

  1. 当用户点击QTreeView时,QLineEdit会填充点击的项目(如果应用了路径和文件名)
  2. 当用户编辑QLineEdit并按回车键时,我想:

    一个。如果路径存在,则将QTreeView同步到该位置

    湾如果路径不存在,我想用QTreeView的当前位置重新填充QLineEdit

  3. 一切都运作良好,除非满足上述条件2a,我想:

    1. 重点关注QTreeView
    2. 展开当前文件夹
    3. 将第1列调整为内容
    4. 并将视图滚动到该索引(滚动到顶部)
    5. 以下是我实施的代码:

      QDirectorySelector::QDirectorySelector(QString const & title, QWidget *parent)
          : QWidget(parent)
      {
          mDirectoryModel = new QFileSystemModel;
          mDirectoryModel->setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
          mDirectoryModel->setRootPath("");
      
          mDirectoryTitle = new QLabel(title);
      
          mDirectoryView = new QTreeView;
          mDirectoryView->setModel(mDirectoryModel);
          mDirectoryView->setSortingEnabled(true);
          mDirectoryView->sortByColumn(0, Qt::AscendingOrder);
          mDirectoryView->setSelectionMode(QAbstractItemView::ExtendedSelection);
      
          mDirectoryEdit = new QLineEdit;
      
          QVBoxLayout * layout = new QVBoxLayout;
          layout->addWidget(mDirectoryTitle);
          layout->addWidget(mDirectoryView);
          layout->addWidget(mDirectoryEdit);
          layout->setContentsMargins(0, 0, 0, 0);
      
          setLayout(layout);
      
          connect(mDirectoryView, &QTreeView::clicked, this, &QDirectorySelector::synchronizeEditFromTree);
          connect(mDirectoryEdit, &QLineEdit::returnPressed, this, &QDirectorySelector::synchronizeTreeFromEdit);
          connect(this, &QDirectorySelector::synchronizationDone, this, &QDirectorySelector::reactToExpansionStep1, Qt::QueuedConnection);
          connect(this, &QDirectorySelector::synchronizationStep1Done, this, &QDirectorySelector::reactToExpansionStep2, Qt::QueuedConnection);
      }
      
      void QDirectorySelector::synchronizeEditFromTree(QModelIndex const & index)
      {
          QString directory{ mDirectoryModel->fileInfo(index).absoluteFilePath() };
          mDirectoryEdit->setText(directory);
      }
      
      void QDirectorySelector::synchronizeTreeFromEdit()
      {
          if (QDir(mDirectoryEdit->text()).exists()) {
              mDirectoryView->setFocus();
              mDirectoryView->setCurrentIndex(mDirectoryModel->index(mDirectoryEdit->text()));
              mDirectoryView->setExpanded(mDirectoryView->currentIndex(), true);
              emit synchronizationDone(mDirectoryView->currentIndex());
          } else {
              selectDirectory(mDirectoryView->currentIndex());
          }
      }
      
      void QDirectorySelector::reactToExpansionStep1(QModelIndex const & index)
      {
          mDirectoryView->resizeColumnToContents(0);
          emit synchronizationStep1Done(mDirectoryView->currentIndex());
      }
      
      void QDirectorySelector::reactToExpansionStep2(QModelIndex const & index)
      {
          mDirectoryView->scrollTo(mDirectoryView->currentIndex(), QAbstractItemView::PositionAtTop);
      }
      

      如果我输入现有路径并按Enter键,我会遇到这种意外行为:

      • 焦点完成(确定)
      • 视图的当前索引正确完成(ok)
      • 完成子文件夹的扩展(确定)
      • 第一列的调整大小仅在路径级别完成,不包括扩展部分(不是预期的)
      • 根本没有完成滚动(不正常)

      此时,如果我返回QLineEdit并再次按回车键,一切都正常完成。事实上,我观察到这种模式,如果指定的文件夹永远不会“打开”(看到/加载/扩展),我会得到意想不到的行为。如果指定的是“打开”(看到/加载/扩展),我会得到预期的行为。

      我也尝试在finishDirectoryEditing中调用两次代码,但没有成功。一切都是一样的。

      有人对这里发生的事情有任何想法吗?更好的是,任何解决这种意外行为的建议。

      我认为使用QFileSystemModel的QTreeView在行为方面已经太尴尬了。我的意思是,它永远不会隐藏空文件夹的扩展标记。可能有可能改变这一点,但我没有成功采用我在网上其他地方找到的更多策略。

      感谢所有人!

0 个答案:

没有答案