[SOLVED] QTreeView blocking SIGNAL expanded
-
wrote on 7 Dec 2014, 11:38 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 ¤tIndex)
{
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(this->filesystemmodel->filePath(currentIndex)+dirContents.at(i)); else fileInfo.setFile(this->filesystemmodel->filePath(currentIndex)+"/"+dirContents.at(i)); 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! -
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
-
wrote on 7 Dec 2014, 16:12 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? -
wrote on 7 Dec 2014, 16:28 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/4