Solved Using model indexes
-
Hello, I am reading the Qt Model/View Documentation but can't get an example running. I am trying to put the code fragments from the section Using model indexes together. but it won't work. numRows is always 0.
Here is what I came up with:
int main(int argc, char *argv[]) { QApplication app(argc, argv); QFileSystemModel *model = new QFileSystemModel; // the following line was added by me, but didn't help model->setRootPath(QDir::currentPath()); QModelIndex parentIndex = model->index(QDir::currentPath()); int numRows = model->rowCount(parentIndex); qDebug() << numRows; for (int row = 0; row < numRows; ++row) { QModelIndex index = model->index(row, 0, parentIndex); QString text = model->data(index, Qt::DisplayRole).toString(); // Display the text in a widget. (this comment is from the documentation) qDebug() << text; // this debug statement was added by me } return app.exec(); }
I tried
int numCols = model->columnCount(parentIndex);
which is 4, but all entries are empty strings.The conclusion of the Documentation is "The above example demonstrates the basic principles used to retrieve data from a model." But I cant get it running. Can anybody help? Thanks a lot.
-
Hi and welcome to devnet,
QFilesystemModel is an asynchronous model. It's done so to avoid useless system load and resources consumption.
You are accessing too early hence the results you are getting.
-
Thank you for your help! :-)
I tried
QThread::sleep(1)
at various places, but its still the same.Any idea how to get this example running or is it in this simple way just not possible?
-
@king_leoric
QThread::sleep(1)
is not good. From what @SGaist said, I'm guessing you should look at signals https://doc.qt.io/qt-5/qfilesystemmodel.html#rootPathChanged and https://doc.qt.io/qt-5/qfilesystemmodel.html#directoryLoaded. Try your code in slots connected to those? -
Use the directoryLoaded signal.
-
Hello Jon and Gaist! Thank you for your help.
I managed the slots, but they are never triggered.
void MySlot::printDirectory(const QString text) { qDebug() << text; qDebug() << "printDirectory"; } void MySlot::printPath(const QString text) { qDebug() << text; qDebug() << "printPath"; }
and main.cpp
QFileSystemModel *model = new QFileSystemModel; MySlot* myslot = new MySlot(NULL); QObject::connect(model,SIGNAL(rootPathChanged(QString)),myslot,SLOT(printPath(QString))); QObject::connect(model,SIGNAL(directoryLoaded(QString)),myslot,SLOT(printDirectory(QString))); QModelIndex parentIndex = model->index(QDir::currentPath()); int numRows = model->rowCount(parentIndex); qDebug() << numRows; // 0
But it's not that important. I was just wondering that the documentation provides an incomplete example. Another example in the Model/View article using the QFileSystemModel with QTreeView and QListView works just fine: Using views with an existing model.
Nevertheless it would be great to fix this example :-)
-
@king_leoric
I think you are misunderstanding the fundamental.You do not put something like
int numRows = model->rowCount(parentIndex);
in yourmain()
, assuming it's still there. You create theQFileSystemModel
, set up theconnect()
s from signals to slots, and then allow your main to hit theapp.exec()
. That runs the main Qt event loop. When that is running yourQFileSystemModel
will get populated (asynchronously), and at that point will emit a signal likedirectoryLoaded
. Your attached slot will be called, and inside that is when you can examine the now-populated model.Are you aware that is how you are intended to write your code?
-
Thank you very much, Jon and SGaist, I really appreciate your help and I learned something fundamental :-)
I followed your instructions and here is the now working code: (just in case another newbie is stuck with the tutorial "Using model indexes")
// myslot.h #ifndef MYSLOT_H #define MYSLOT_H #include <QDebug> #include <QFileSystemModel> #include <QModelIndex> class MySlot : public QObject { Q_OBJECT public: explicit MySlot(QObject *parent) : QObject(parent) {} void setModel(QFileSystemModel* model); public slots: void printDirectory(const QString); private: QFileSystemModel* m_model; }; #endif // MYSLOT_H
// myslot.cpp #include "myslot.h" void MySlot::setModel(QFileSystemModel *model) { m_model = model; Object::connect(model,SIGNAL(directoryLoaded(QString)),this,SLOT(printDirectory(QString))); } void MySlot::printDirectory(const QString dir) { QModelIndex parentIndex = m_model->index(dir); int numRows = m_model->rowCount(parentIndex); // qDebug() << numRows; for (int row = 0; row < numRows; ++row) { QModelIndex index = m_model->index(row, 0, parentIndex); QString text = m_model->data(index, Qt::DisplayRole).toString(); // Display the text in a widget. qDebug() << text; } }
// main.cpp #include <QApplication> #include <QFileSystemModel> #include <QModelIndex> #include "myslot.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QFileSystemModel* model = new QFileSystemModel; model->setRootPath(QDir::currentPath()); MySlot* myslot = new MySlot(NULL); myslot->setModel(model); return app.exec(); }
Output is a list of all files and folders in the current path.
Thanks again for your kind support, I couldn't have done it without your help!