Qtquick / qml with QFileSystemModel and GridView
-
Hi :)
I'm new to qt and i'm really confused about this qtquick/qml/qt/c++ mixing thing ;).
I want to show the content of a particular folder (some pdfs) in a thumbnail-wise way, like a common file-browser. I found GridView to be appropriate for this, but now i'm not so sure anymore.
I started with creating a QtQuick Application with C++ from the Wizard (Version 2.8.1
Based on Qt 5.1.1) operating on Mac OsX Snow Leopard.I tried many variations of the following code, but i think i misunderstood something in general:
@#include <QApplication>
#include "qmlapplicationviewer.h"
#include <QDir>
#include <QDebug>
#include <QtDeclarative>
#include <QFileSystemModel>Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));QmlApplicationViewer viewer; viewer.addImportPath(QLatin1String("modules")); viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); // Set up the file system model QFileSystemModel *model = new QFileSystemModel; model->setRootPath("/Users/myusername/testpath"); viewer.rootContext()->setContextProperty("dirmodel", model); viewer.setMainQmlFile(QLatin1String("qml/projectname/main.qml")); viewer.showExpanded(); return app->exec();
}@
The qml-file :
@import QtQuick 1.1
Rectangle {
width: 360
height: 360
Text {
x: 13
y: 14
text: qsTr("content:")
anchors.verticalCenterOffset: -158
anchors.horizontalCenterOffset: -145
anchors.centerIn: parent
}
GridView {
id: grid_view1
x: 19
y: 41
width: 321
height: 301
cellWidth: 70
cellHeight: 70
anchors.fill: parentmodel: dirmodel } MouseArea { x: 0 y: 0 anchors.rightMargin: 0 anchors.bottomMargin: 0 anchors.leftMargin: 0 anchors.topMargin: 0 anchors.fill: parent onClicked: { Qt.quit(); } }
}@
What am i doing wrong? There's no error, but there are no files either.
I am now trying to get this simple task done for almost 13 hours :(All the tutorials and videos are using qt (instead of qtquick) with DeclarativeView and whatsoever, i tried every example code, but still - empty frame :(
Now i doubt about GridView being the right choice ...
Thanks in advance,
bergeule
-
The GridView also needs a delegate. A delegate tells the View how to paint data. In your case, you probably want some Image and Text components to work on the data from the model, so that they are getting displayed properly.
-
Ok i tried to figure out how to delegate this model, but all examples i could find are widget based and not qtquick.
i think i'll start from scratch again, but this time i'll thry the widget based approach. it's more clear for me there.
too bad, i kinda like this declarative style :(
thanks of course for your help!
-
There are plenty of explanations in the documentation, maybe you have not searched well enough. Make sure you've read "this":http://qt-project.org/doc/qt-5.1/qtquick/qml-qtquick2-gridview.html and "this":http://qt-project.org/doc/qt-5.1/qtquick/qtquick-modelviewsdata-modelview.html.
A live example can be found in my CCF project: "link":https://github.com/sierdzio/closecombatfree/blob/master/qml/gui/menus/RosterMenu.qml#L38.
Delegates are easy: you just need to use the variable provided by the Model and do something with it (for example, display it with Image component). Feel free to ask more questions, I'm happy to help.
-
Hey :)
I achieved some progress, even if it's not working properly. I knew the articles you posted already, but after i read them again and took a closer look at your code i recognized, that i have to call the qfilesystemmodel methods different.
My delegate is now (minimal example):
@delegate: Column {
Image {source: model.fileIcon;} Text {text: model.fileName;} }@
Two problems still exist:
fileIcon returns a QIcon, which is not displayed. There's an error which says "Unable to assign QIcon to QUrl", so source needs a path to a image. I can't find a solution on the web, but i think i might be able to solve this by creating my own model as a derived class model. Or is there another solution?Second Problem is, even if i set a root path, it shows just one object with the file name "/". Is this because somethings works wrong, or is this just my root directory?
But the important thing is, i understood the principle of how to pass data from model to view, thanks :)
I also browsed through your code and i learned a few more things how to manage a bigger project :)
(Sorry for posting so late, i have not very much time to code at the moment and i try to read and try things before posting back)
Greetings,
bergeule
-
I have not used that particular model class, it seems that indeed you will need a custom derived class (or a customized Image component).
For the root path, see "this":http://qt-project.org/forums/viewthread/1846.
(that's OK, I don't remember much about timing of conversations in my posts; I participate in far too many threads here)
-
Hi :)
I managed to solve the path problem by setting up a VisualDataModel and setting the rootIndex to the path, thx :)
But now i have some different problems:
I made a new model by inheriting the QFileSystemModel with a function which returns the text at the bottom of the grid item.
@class newmodel : public QFileSystemModel
{Q_OBJECT
public:
newmodel(); Q_INVOKABLE QModelIndex pathIndex(const QString &path, int column); Q_INVOKABLE QString newmodel::Title(const QModelIndex & index);
};
// just the title function:
QString newmodel::Title(const QModelIndex & index);
{
QString thing = " Text " ;
qDebug() << thing;
return thing;
}
@in reality, the qstring is determined otherwise, but the problem is this error message:
@Unable to assign [undefined] to QString text@
So for debugging this issue i made the function just to return a QString likt it is supposed to and i return the string in the debug console to make sure the method is called.
And unfortunately, it is not.
There is no debug message and no text to the files.
If i use the QFileSystemModel internal method "fileName", GridView shows the file name. According to the Documentation, this method also returns a QString.
I also made sure i exposed the model to qml (using the Q_INVOKABLE macro and viewer.rootContext()->setContextProperty("dirmodel", model); )
What am i missing? How do i make sure that this function is called for every item in the model as well as the original functions? I cannot find anything about how it works that the model is calling functions for every item.
Maybe you can help me :)
Thanks in advance
best wishes
bergeule
-
Please also post the code of your delegate.
I am not sure what is the problem here.
-
Here it is:
@model: VisualDataModel {
model: dirmodel rootIndex: dirmodel.pathIndex("/Users/myusername/testpath",0) // Delegate für die Ausgabe delegate: Rectangle { width: 10 height: 10 color: "blue" //Image {source: model.fileIcon;} Text {text: model.Title;} }
}
@It creates a blue rectangle representing the files or folders, with the text.
I tried dirmodel.Title instead of model.Titel, but it doesn't work either :(Thx for helping!
-
I think just "model.modelData.Title" might work. It's been too long since I last did that kind of coding, I don't remember the details. Check out the docs, they are usually quite helpful.