Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    [SOLVED] QTreeView blocking SIGNAL expanded

    General and Desktop
    2
    4
    1453
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      Binary91 last edited by

      Hi,
      I'd like to create a QDialog for selecting one/multiple files from the file system.
      I'm using QFileSystemModel, QTreeview and QListWidget:
      @ myQDialogGetFile::myQDialogGetFile(QWidget *parent, const QString &title) : QDialog(parent)
      {
      this->layoutMain = new QVBoxLayout;
      this->layoutTop = new QHBoxLayout;
      this->filesystemmodel = new QFileSystemModel;
      this->filesystemmodel->setRootPath(QDir::currentPath());
      this->filesystemmodel->setFilter(QDir::Drives|QDir::AllDirs|QDir::Dirs|QDir::NoDotAndDotDot);

      this->treeview = new QTreeView;
      this->layoutTop->addWidget(this->treeview);
      this->treeview->setModel(this->filesystemmodel);
      this->treeview->setHeaderHidden(true);
      for(int i = 1; i < this->filesystemmodel->columnCount(); i++)
        this->treeview->hideColumn(i);
      this->treeview->setIndentation(20);
      this->treeview->setSortingEnabled(true);
      this->treeview->setAnimated(false);
      this->treeview->setCurrentIndex(this->filesystemmodel->index(QApplication::applicationDirPath()));
      connect(this->treeview, SIGNAL(clicked(const QModelIndex &)), this, SLOT(treeviewClicked(const QModelIndex &)));
      connect(this->treeview, SIGNAL(expanded(const QModelIndex &)), this, SLOT(treeviewClicked(const QModelIndex &)));
      
      //...
      

      }

      myQDialogGetFile::treeviewClicked(const QModelIndex &currentIndex)
      {
      if(!currentIndex.isValid())
      return;
      QDir directory = QDir(this->filesystemmodel->filePath(currentIndex));
      QStringList dirContents = directory.entryList(QDir::Files|QDir::NoDotAndDotDot, QDir::DirsFirst);
      if(this->listDirContents->count() > 0)
      this->listDirContents->clear();

      for(int i = 0; i < dirContents.count(); i++)
      {
        QFileInfo fileInfo;
        if(this->filesystemmodel->filePath(currentIndex).right(1) == "\\" || this->filesystemmodel->filePath(currentIndex).right(1) == "/")
          fileInfo.setFile&#40;this->filesystemmodel->filePath(currentIndex&#41;+dirContents.at(i&#41;);
        else
          fileInfo.setFile&#40;this->filesystemmodel->filePath(currentIndex&#41;+"/"+dirContents.at(i&#41;);
      
        QFileIconProvider iconProvider;
        this->listDirContents->addItem(new QListWidgetItem(iconProvider.icon(fileInfo), dirContents.at(i)));
        this->listDirContents->item(this->listDirContents->count()-1)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
      }
      

      }@
      As you can see, the QListWidget displays the contents (files and subdirectories) of the directory that is clicked or expanded in the QTreeView.

      Everything works fine, except the initial executing of QDialog. As you can see, I set the treeview's currentIndex to the directory where the running program is located. The only problem is, that for reasons I don't understand, the SIGNAL expanded() is fired a lot of times (for each directory above the current one). And the last fired expanded() SIGNAL forces the QListWidget to display the contents of the rootDirectory (C:/), but the treeview displays the focus on the current working directory.

      I don't know how to fix this, because all this happens after calling the QDialog::exec() so I can't intervent anymore...

      Has anyone a solution for that problem?
      Thank you in anticipation!

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        If I'm not mistaken it could be because QFileSystemModel loading is threaded so the population of the data is not done in only one go. What you could try is to use the directoryLoaded signal to finish your dialog setup.

        Hope it helps

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply Reply Quote 0
        • B
          Binary91 last edited by

          Hi,
          thank you for your reply. Unfortunatelly, the problem doesn't occure in QDialogs constructor.
          I debugged the code and let the expanded() SLOT (treeviewClicked()) print a message to see when the expanded() signal is fired. It is not fired while creating the QDialog with its contents (QFileSystemModel, QTreeview and so on), but it is fired when calling it via QDialog::exec().
          That is the problem, because I can't intervene anymore after calling exec()... Maybe I do have to overload the exec() function and debug it to see which step of it lets the expanded() signal fire?

          1 Reply Last reply Reply Quote 0
          • B
            Binary91 last edited by

            Hi again,

            I found a solution by myself:
            I reimplemented the QDialog::showEvent function, and called the treeviewClicked() slot manually:
            @ void myQDialogGetFile::showEvent(QShowEvent *event)
            {
            QDialog::showEvent(event);
            this->treeviewClicked(this->treeview->currentIndex());
            }@

            Works great :-)

            1 Reply Last reply Reply Quote 0
            • First post
              Last post