How to hook QStringListModel up to a ListView?
-
Hi and welcome to devnet,
At the bottom of the QtQuick model view documentation, you can find a link to the QtQuick CPP models documentation that explains how to implement interaction between both.
-
Hi and welcome to devnet,
At the bottom of the QtQuick model view documentation, you can find a link to the QtQuick CPP models documentation that explains how to implement interaction between both.
@SGaist Hey SGaist, thank you for the quick response and resources! I'm still trying to wrap my head around the whole model thing with Qt, so forgive me if I have a few "obvious" questions. I've noticed how in the documentation they have the required property string "modelData" is it required to have that variable initialized in order to use modelData? I swear I've seen it used without even having the property in code. In my most recent build, when I remove the property, I get "undefined" when I log out modelData.
Another problem I have is even though the modelData property no longer comes up as "undefined" (due to "required property string modelData" being added) in my code, it logs " " in the console.log function. And I know that the list isn't empty as right before I run console.log, I print the QList in c++ and I currently have 1 item: QList("TargetDirectories.txt")
ListView{ id:fileinfo model: FileDataHandler.files Layout.topMargin: 10 Layout.fillWidth: true Layout.fillHeight: true spacing: 10 delegate: Flow{ required property string modelData anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 20 anchors.rightMargin: 20 spacing: 10 width: fileinfo.width ColumnLayout{ Layout.alignment: Qt.AlignHCenter Layout.preferredWidth: window.width * .2 Layout.preferredHeight: window.height * .1 Image { Layout.alignment: Qt.AlignHCenter id: myImage source: "Icons/document.svg" fillMode: Image.PreserveAspectFit sourceSize: Qt.size(24,24) Layout.preferredWidth: window.width * .1 Layout.preferredHeight: window.height * .05 } TextField{ color: "#000000" Layout.alignment: Qt.AlignHCenter text: modelData //this is now valid onTextChanged: function(){ console.log(modelData, "MODEL") } background: Rectangle{ radius: 30 } clip: true } } } }
-
You should provide the C++ part as well so we have a better picture of what you are doing.
-
@SGaist
The code is being marked as spam. What should I do? -
@SGaist
The code is being marked as spam. What should I do?@Jay_emissary I have an idea.
#include "filedatahandler.h" #include <QFIleDialog> #include <QDir> #include <QStandardPaths> #include <QFileSystemModel> FileDataHandler::FileDataHandler(QObject * parent) : QFileSystemModel(parent) { //qurls return an empty string when converted into a local file without file:/// //QStandardPaths doesn't return a string in that format, so we handle this manually defaultPath = "file:///" + (QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); filters << "*.txt"; setNameFilters(filters); setRootDirectory(defaultPath); } void FileDataHandler::setRootDirectory( QUrl selectedFolderPath) { //convert url into a qstring that's compatible with setRootPath() QString selectedPath = selectedFolderPath.toLocalFile(); if (QDir(selectedPath).exists()){ setRootPath(selectedPath); setRootIndex(index(selectedPath)); if(m_files){ m_files->setStringList( QDir(selectedPath).entryList(filters, QDir::Files)); setFiles(m_files); qInfo() << m_files->stringList(); } else { qWarning() << "m_files is invalid"; } qInfo() << rootPath()<< selectedPath; return; } else{ qWarning() << "Cannot set a default path."; } } QString FileDataHandler::getDefaultRootDirectory() { //returns documents directory as string (note that writeableLocation is used if you're just reading or writing) return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); } QModelIndex FileDataHandler::rootIndex() const { return m_rootIndex; } void FileDataHandler::setRootIndex(const QModelIndex &newRootIndex) { if (m_rootIndex == newRootIndex) return; m_rootIndex = newRootIndex; emit rootIndexChanged(); } QStringListModel *FileDataHandler::files() const { return m_files; } void FileDataHandler::setFiles(QStringListModel *newFiles) { if (m_files == newFiles) return; m_files = newFiles; emit filesChanged(); }
-
The
QML_ELEMENT
macro is missing.
Have you read the documentation about writing QML extensions? -
The
QML_ELEMENT
macro is missing.
Have you read the documentation about writing QML extensions?@Axel-Spoerl I admit that I haven't read this part of the document yet. I've been using youtube tutorials to help me understand the QML_ELEMENT macro for the most part. To my understanding, you don't need the macro if you register your class via qmlRegisterSingletonInstance, No?
-
@Axel-Spoerl I admit that I haven't read this part of the document yet. I've been using youtube tutorials to help me understand the QML_ELEMENT macro for the most part. To my understanding, you don't need the macro if you register your class via qmlRegisterSingletonInstance, No?
Hm, you haven't said that you are implementing the model as a singleton.
There is nothing in the code, that worries me particularly.
I suggest you boil this down to a minimal reproducible example, to narrow the problem down to the smallest possible amount of code.
Start with a model that isn't a singleton and see if it works. -
Hm, you haven't said that you are implementing the model as a singleton.
There is nothing in the code, that worries me particularly.
I suggest you boil this down to a minimal reproducible example, to narrow the problem down to the smallest possible amount of code.
Start with a model that isn't a singleton and see if it works.@Axel-Spoerl Hey so, I went ahead and made an example project, with minimal code. I created the type, initialized the string list in the constructor, and sent the data to the model. Strangely enough, nothing appears on the text and when I trigger the console.log function, I get
"qml: Model Data: undefined"
-
You registered a type and used it as a singleton in QML. Also avoid using
qmlRegister***
function now, you should useQML_xxx
macros instead. -
You registered a type and used it as a singleton in QML. Also avoid using
qmlRegister***
function now, you should useQML_xxx
macros instead.@GrecKo In my original project, the object with the StringListModel is a singleton. In this new one, the StringListModelExampleClass isn't. Anyway, I had no idea that using macros is now considered "best practice" for communicating with qml, so thank you for the advice! My project is now using the QML_ELEMENT macro, but the console is still logging "undefined."