Qt-interest Archive, April 2007
Trying to understand Model/View workings
Message 1 in thread
Hello,
I am working with 2 different model/views in my application, and I have run up
against some problems, that made me realise I do not yet fully understand how
you are supposed to properly use this mechanism.
To be clear, I have "fixed" the problem I am going to explain, so I am not
asking for working code. This isn't a call for help containing not-working
code ... I simply want to understand if what I have is the way it *should* be
done, or if I am missing the bigger picture here. Also, I do not think I am
stupid, but if it makes explaining things more easier for you, you may assume
I am ;-)
Anyway,
I have 2 widgets;
+ a QTreeView linked with a QDirModel
+ a FileList (QListView subclass) linked to FileListModel (QAbstractListModel
subclass). I also have QItemDelegate subclass here, but it doesn't do
anything :)
The QTreeView lists all directories and when a directory is selected in the
QTreeView, I show all mp3 files recursively found in the subdirectories in
the FileList. FileListModel keeps a QLink with AudioFile (which is QFileInfo
subclass) objects representing its data.
Consider then this directory structure (each containing mp3 files):
/home/user/Music/
/home/user/Music/aaa
/home/user/Music/aaa/more
/home/user/Music/bbb
/home/user/Music/ccc
What I wanted to now, is toggle between 2 background colors. But not
alternating by ROW, but by DIRECTORY, so that it is obvious in the list what
files are in the same (sub)directory. So u would get this (for example):
white: /home/user/Music/*.mp3
green: /home/user/Music/aaa/*.mp3
white: /home/user/Music/aaa/more/*.mP3
green: /home/user/Music/bbb/*.mp3
white: /home/user/Music/ccc/*.mp3
And this is where I ended up wasting a lot of time trying to come up with a
clean solution. In the end, I kept a boolean value in my QFileInfo subclass
called isColoredDirRow, and I would use that boolean to return the OTHER
(then white) color in FileListModel::paint() function if that boolean is true
and if the role is the BackgroundRole.
That works, and is very few lines of code too actually. But IMO keeping the
boolean on the QFileInfo isn't the proper way to go, if you consider design.
I would rather just check in the paint() function the given modelindex
against the previous modelindex; get the color used to paint the background;
see if the directory differs and return a color.
But it turns out I have no way of retrieving the color used by the previous
index as background (correct if Im wrong here), and there were a bunch of
other problems I ran into, that made me forget doing it this way at all (cant
think of them now, I apologise).
So now I have a solution that works, but I feel that code deciding what
background color is needed, should really be in QListView class or the
QAbstractListModel class, not in the data itself....
Because, for example, what if I want to do sorting in my QListView, and allow
different background color modes for each sorting-mode ?? In that case, the
boolean on my QFileInfo becomes useless ...
Am I wrong?
Did I do something wrong or is what I want simply something that isn't
available in Qt (yet) ??
Regards,
Stefan Vunckx
ps: and I DO apologise for the long read too ;-)
--
[ signature omitted ]
Message 2 in thread
On 02.04.07 23:40:44, Stefan Vunckx wrote:
> What I wanted to now, is toggle between 2 background colors. But not
> alternating by ROW, but by DIRECTORY, so that it is obvious in the list what
> files are in the same (sub)directory. So u would get this (for example):
>
> white: /home/user/Music/*.mp3
> green: /home/user/Music/aaa/*.mp3
> white: /home/user/Music/aaa/more/*.mP3
> green: /home/user/Music/bbb/*.mp3
> white: /home/user/Music/ccc/*.mp3
>
> And this is where I ended up wasting a lot of time trying to come up with a
> clean solution. In the end, I kept a boolean value in my QFileInfo subclass
> called isColoredDirRow, and I would use that boolean to return the OTHER
> (then white) color in FileListModel::paint() function if that boolean is true
> and if the role is the BackgroundRole.
Forgive me if I stopped reading your post here, but the solution that
instantly comes to my mind is: Have data() return the "right" color for
BackgroundColorRole. You can easily check wether the previous sibling's
file path has the same dir as this one and then just return the proper
color. And you paint function can ask the model for the
backgroundcolorrole data for the index it should paint.
> That works, and is very few lines of code too actually. But IMO keeping the
> boolean on the QFileInfo isn't the proper way to go, if you consider design.
> I would rather just check in the paint() function the given modelindex
> against the previous modelindex; get the color used to paint the background;
> see if the directory differs and return a color.
Well, you can do that too. You have full access to the model, so you can
easily get the previous index and ask the model (via data) for the file
path. You could even use the UserRole to directly retrieve the directory
of a given index and not the full path. Then your paint method can
decide.
Andreas
--
[ signature omitted ]
Message 3 in thread
On Tuesday 03 April 2007 00:06:35 Andreas Pakulat wrote:
> Forgive me if I stopped reading your post here, but the solution that
> instantly comes to my mind is: Have data() return the "right" color for
> BackgroundColorRole. You can easily check wether the previous sibling's
> file path has the same dir as this one and then just return the proper
> color. And you paint function can ask the model for the
> backgroundcolorrole data for the index it should paint.
>
> > That works, and is very few lines of code too actually. But IMO keeping
> > the boolean on the QFileInfo isn't the proper way to go, if you consider
> > design. I would rather just check in the paint() function the given
> > modelindex against the previous modelindex; get the color used to paint
> > the background; see if the directory differs and return a color.
>
> Well, you can do that too. You have full access to the model, so you can
> easily get the previous index and ask the model (via data) for the file
> path. You could even use the UserRole to directly retrieve the directory
> of a given index and not the full path. Then your paint method can
> decide.
Sorry for the late reply (been lazy),
but I still dont understand. If I want to toggle the background color in
*some* way (other then Qt's default alternating color), I have to know what
the previous item's color has been, and to do that;
- i cannot save it in model's data function cause it is const
- there is member on the view class to retrieve the color
so the only way i see possible is to call data() with Qt::BackgroundRole, but
IMO it will recursively do this, since each item's color will need to
determined against the previous item, untill the *first* item is found. But
isn't this a bit too expensive for something as simple as setting the
background color for each row ? (mind you i have no real knowledge about
performance here)
Id like to remind again, that in my application everything works as wanted, im
just trying to understand what it is I am missing in the design ;-)
Regards,
Stefan Vunckx
--
[ signature omitted ]
Message 4 in thread
On 18.04.07 21:57:35, Stefan Vunckx wrote:
> On Tuesday 03 April 2007 00:06:35 Andreas Pakulat wrote:
> > Forgive me if I stopped reading your post here, but the solution that
> > instantly comes to my mind is: Have data() return the "right" color for
> > BackgroundColorRole. You can easily check wether the previous sibling's
> > file path has the same dir as this one and then just return the proper
> > color. And you paint function can ask the model for the
> > backgroundcolorrole data for the index it should paint.
> >
> > > That works, and is very few lines of code too actually. But IMO keeping
> > > the boolean on the QFileInfo isn't the proper way to go, if you consider
> > > design. I would rather just check in the paint() function the given
> > > modelindex against the previous modelindex; get the color used to paint
> > > the background; see if the directory differs and return a color.
> >
> > Well, you can do that too. You have full access to the model, so you can
> > easily get the previous index and ask the model (via data) for the file
> > path. You could even use the UserRole to directly retrieve the directory
> > of a given index and not the full path. Then your paint method can
> > decide.
>
> Sorry for the late reply (been lazy),
>
> but I still dont understand. If I want to toggle the background color in
> *some* way (other then Qt's default alternating color), I have to know what
> the previous item's color has been, and to do that;
>
> - i cannot save it in model's data function cause it is const
> - there is member on the view class to retrieve the color
>
> so the only way i see possible is to call data() with Qt::BackgroundRole, but
> IMO it will recursively do this, since each item's color will need to
> determined against the previous item, untill the *first* item is found. But
> isn't this a bit too expensive for something as simple as setting the
> background color for each row ? (mind you i have no real knowledge about
> performance here)
Uhm, I guess I misunderstood you. I thought you wanted to change the
color on specific files or dirs that you know already (without having to
always compute it from the previous item). If thats not possible I think
you should use something like a QList of QMaps as data storage, where
the QMap has a fileinfo and a color entry and thus you store the color
for each item (or a boolean value).
Andreas
--
[ signature omitted ]