PDA

View Full Version : How to use? And where to put QDir?



JaySDC
16th September 2015, 09:55
Hi,

I am trying to have a total count of the .png file of a folder and its subfolders.

Seems like QDir is the way to go but I have trouble placing it and using it. Damn am I such a noob :((.

What QDir attributes/properties should I use? Even with the doc and some example I can't wrap my head around it...

Once I have this count, I want to put it in a variable that I can use/read in my other .qml files...



If anyone would be so kind as to help me code this...



Yours,
--Jay

bartarya.parul
16th September 2015, 10:47
You have to calculate the total count of .png files in some directory structure....First You can use function void QDir::setNameFilters(const QStringList) for setting the filters in the directory struture.eg.
QStringList filters;
filters << "*.png";
dir.setNameFilters(filters);
Then you can use function QStringList QDir::entryList(const QStringList &filters) which will return the StringList for all .png files. Then you should use function uint QDir:: count() which is equivalent to entryList().count()...Try it..and you can also check these functions on Qt Help for the details.

anda_skoa
16th September 2015, 10:50
There is no direct way to use this in QML, you will have to go through C++.

There a re different ways of doing this, some more complex (but also more flexible) then others.

Do you have any object already exposed from C++ via setContextProperty()?

Cheers,
_

JaySDC
16th September 2015, 10:52
Yes anda_skoa I gathered from research that I'd have to go with C++ and QDir.

Thank you bartarya.parul I'll see what I can do with that : )

Yours,
--Jay

anda_skoa
16th September 2015, 11:50
Since you want to do recursive, you will be better of using QDirIterator with the respective flag.

If you already have an object that is exposed to QML via setContextProperty() then the easiest way is to add a Q_INVOKABLE marked method to that class.

Out of curiosity: how do you intend to use this count?

Cheers,
_

JaySDC
16th September 2015, 12:19
Here is my project:

I (try to) develop a FrontEnd to run on my arcade cabinet.

Qt is a nice way to display the images of the different games in a caroussel-way.


I have several counters on my FrontEnd design that are animated.
Each game have a unique property that is either HORIZONTAL or VERTICAL.

I have one counter (A) that display the # of HORIZONTAL games in the CURRENT category (working : D)
I have one counter (B) that display the # of VERTICAL games in the CURRENT category (working : D)

I have one counter (C) that display the # of HORIZONTAL games in TOTAL (non-working yet :( )
I have one counter (D) that display the # of VERTICAL games in TOTAL (non-working yet :( )

Right now my code only knows how many games there are WHEN switching to a category.
Then it displays the number of items in that category.


But as we only know the # in the current category, I also want to have an additional check/count when the application is INITIALLY ran.
This number will only be checked once. I don't even need to change that variable afterwards. So C & D should always display the same, but I still need to know C and D values : /.

Yours,
--Jay

anda_skoa
16th September 2015, 12:59
Ah, see, that makes it even simplier :)

While you still need to gather that information in C++, you can now just export the final values via setContextProperty().

At some place in your C++ code you are loading the main QML file, probably using a QQuickWindow or a QQuickView.
Both have a "root context" which basically holds "global variables".
You can add values to that by calling setContextProperty(), providing a name (to be used in QML) and the value (in your case the two numbers you've just gathered).

Something like this:


int totalHorizontalGames = ....;

QQuickView view;
view.rootContext()->setContextProperty("_totalHorizontalGamesCount", totalHorizontalGames);
view.setSource(...);

and anywhere in QML


Text {
text: "Total number of Horizontal games: " + _totalHorizontalGamesCount
}



Cheers,
_

JaySDC
16th September 2015, 13:29
Will give it a go.

Thanks again : )

Yours,
--Jay

JaySDC
17th September 2015, 09:53
Hey everyone,

The code almost works :P

Right now I succeeded in (obv. with both your help):

- Count the number of png files in any folder I choose
- Stock that variable
- Pass that variable to my qml component to use it
- Use it in qml



There is only one thing missing, I'd like to include subfolders relative to the path I gave initially, and also a filter for the beginning of the file name.

**short version**
Basically I want to browse 9 subfolders in order to count:
All the files HORI_*.png of these 9 subfolders
All the files VERTI_*.png of these 9 subfolders
**/end short version**




**detailed version**
a)
Each category is in a different folder, all of them are located here -> c:/temp/

b)
I have 9 of them -> c:/temp/category1, c:/temp/category2, c:/temp/category3, ...

c)
So I want the code to scan these 9 subfolders for all the .png
Right now it only scans the current path that I give it. It does not check the subfolders.

d)
Finally I want a last filter depending on the START of the name of the .png file:
it either starts with HORI_ *or* VERTI_

So I am pretty sure there is some filter I could use to achieve that, but can't find which : /
what code should I add as a filter?
**/end detailed version**




#pragma once
#include <QDir>
#include <QObject>

class FolderInfo : public QObject {
Q_OBJECT
Q_PROPERTY(int numFiles READ GetNumFiles)
Q_PROPERTY(QString currentPath READ GetCurrentPath)
QStringList filters;

public:
FolderInfo() {
SetFromPath("c:/temp/");
}

Q_INVOKABLE void SetFromPath(const QString& path) {
QDir dir(path);
filters<<"*.png";
m_currentPath = dir.absolutePath();
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
dir.setNameFilters(filters);
m_numFiles = dir.count();
}

int GetNumFiles() const {
return m_numFiles;
}


QString GetCurrentPath() const {
return m_currentPath;
}

private:
int m_numFiles;
QString m_currentPath;

};




Yours,
--Jay

anda_skoa
17th September 2015, 11:18
So I want the code to scan these 9 subfolders for all the .png
Right now it only scans the current path that I give it. It does not check the subfolders.

QDirIterator with the iterator flag for subdirectories.


Finally I want a last filter depending on the START of the name of the .png file:
it either starts with HORI_ *or* VERTI_

Just include the prefix in the name filters (two entries, one for each pattern).

Cheers,
_

JaySDC
17th September 2015, 11:54
Wow the HORI_/VERTI_ filter was as simple as that...
I did not even think about trying that haha.

As for the subfolders, I'll see what I can do, thank you!

--Jay

Added after 26 minutes:

Darn, I am such a noob, because of my lack of knowledge and experience, I can't even use doc to add the QDirIterator part :(.

I tried to add it here:
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDirIterator::Subdirectories);

Also some other places. But in the end a piece of the puzzle is missing.


Would you be so kind as to be more specific with QDirIterator usage?



#pragma once
#include <QDir>
#include <QObject>

class FolderInfo : public QObject {
Q_OBJECT
Q_PROPERTY(int numFiles READ GetNumFiles)
Q_PROPERTY(QString currentPath READ GetCurrentPath)
QStringList filters;

public:
FolderInfo() {
SetFromPath("c:/temp/Bat/YOKO_SP_");
}

Q_INVOKABLE void SetFromPath(const QString& path) {
QDir dir(path);

filters<<"YOKO_*.png";
m_currentPath = dir.absolutePath();
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
dir.setNameFilters(filters);
m_numFiles = dir.count();
}

int GetNumFiles() const {
return m_numFiles;
}



QString GetCurrentPath() const {
return m_currentPath;
}

private:
int m_numFiles;
QString m_currentPath;

};



Yours,
--Jay

anda_skoa
17th September 2015, 12:17
You will be using QDirIterator instead of the QDir.

Create the QDirIterator and pass in the path, filters and the recursion flag to the constructor.
Then you iterate like in the docs, but instead of doing anything with the return value of next(), you simply increment m_numFiles (which you reset to 0 before starting the loop).

Cheers,
_

JaySDC
21st September 2015, 08:42
Working. Cheers : D.

--Jay