Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

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 ]