PDA

View Full Version : GridView without reflow



shaolin
11th May 2014, 16:19
Hi guys,

I'm facing a problem implementing a map viewer with QML and a C++ model (Qt 5.2). The model is ok.
For the view I'm using GridView and I found that it reflows contents as you resize the app window. I would like to cancel this behaviour and being able to just scroll vertically and horizontally in case the map is too big to fit in the window, but I don't know how. I tried to use a Grid with a Repeater, but the Repeater seems to place items randomly and, even if I could manage to use it correctly, it instantiates all image tiles when loaded (with a zoom level of 19 in Open Street Map there are more than 500.000 x 500.000 image tiles).

Do you have any suggestions?

Thanks

EDIT: I just understood that GridView is a ListView but with reflow. Any other idea for a bidimensional view? Already tried TableView without success

wysota
12th May 2014, 10:46
An option is to use a bare Flickable and implement element instantiating/destruction manually as the content is scrolled.

shaolin
12th May 2014, 10:50
Thank you for the answer.

I'm considering this option, but in general I would like to implement a simple view for QAbstarctTableModel, maybe using a Flickable. I found a lot of documentation on implementing a model, but I can't find A clear guide on how to implement a simple model

wysota
12th May 2014, 11:03
You mean "a simple view"? With Qt Quick you basically have two options -- do it in C++ or in QML (or a hybrid approach). The biggest problem is to make a decision on how to handle the model. I think in Qt5 (Qt Quick 2) most of the models used in QML are actually subclasses of QAbstractItemModel (this is not the case with Qt Quick 1) but there is no guarantee on that (e.g. an array is also considered a model in Qt Quick) so you can either force a QAbstractItemModel subclass or provide a more relaxed definition of a model. Since therre is no common view definition in Qt Quick (compared to the widget world where you have QAbstractItemView) you will have to attach to model signals manually. In your particular situation what you surely need is information about data insertion and removal to the model (unless you want to make your view wok with stationary models only). Then it is just a matter of two things:
1. fetching info from the model
2. managing items (delegates) providing visualisation of the model data

contentX and contentY will give you information about the current area visible in the view so that you can instantiate and destroy delegates according to your needs.

shaolin
12th May 2014, 11:20
For simple I mean that my model is fed by network requests, so I just need to react to the dataChanged signal.
What I would like to avoid is manually creating, arranging and destroying delegates when the view moves (both in c++ and in QML).
The only reason to prefer QML is that Image has the asynchronous option that is quite useful.

Anyway, is there any example on how to subclass QAbstractItemModel?

wysota
12th May 2014, 11:25
For simple I mean that my model is fed by network requests, so I just need to react to the dataChanged signal.
dataChanged is emitted when data for existing items changes. If new items are added to the model then this results in other signals being emitted (e.g. rowsInserted).


What I would like to avoid is manually creating, arranging and destroying delegates when the view moves (both in c++ and in QML).
That's what implementing a view is all about.


The only reason to prefer QML is that Image has the asynchronous option that is quite useful.
You can load images in C++ asynchronically as well with the use of QtConcurrent.


Anyway, is there any example on how to subclass QAbstractItemModel?
There are many examples of subclassing a model available in Qt docs. However what I understood is that you already had a model.

anda_skoa
12th May 2014, 11:31
When creating models for lists or tables then using one of the intermediate helper classes (QAbstractListModel, QAbstractTableModel) is a good way to start, since they implement some of the functionality that is abstract in QAbstractItemModel.

The problem with GridView is that it basically works on a list model, not a table. I think QtQuick.Controls has a table view though.

Cheers,
_

shaolin
12th May 2014, 11:35
Sorry, I mean QAbstractItemView and not QAbstractItemModel. Are there example of subclassing QAbstractItemView?

@anda_skoa I already tried QML TableView but with no succes..

wysota
12th May 2014, 11:46
Sorry, I mean QAbstractItemView and not QAbstractItemModel. Are there example of subclassing QAbstractItemView?

Yes, there is an example showing how to implement a chart view. But if you already have a table model and then why don't you use QTableView with a custom delegate?

shaolin
12th May 2014, 11:48
I tried with a QML TableView (should be very similar), but it displays just a column with a single tile. Probably I'm doing something wrong. how would you do it?

wysota
12th May 2014, 12:15
I didn't mean QML's TableView. I meant C++ QTableView. You said that the only reason to use QML for you is asynchronous loading of images and this can be easily achieved in C++ so I don't see why you wouldn't use QTableView where you only need to implement a custom delegate.

anda_skoa
12th May 2014, 12:19
single column sounds like you have a list model.
What does the model's columnCount() method return when you call it in C++?

Since you wrote about OpenStreetMap, have you had a look at Marble? http://marble.kde.org/dev-intro.php

Cheers,
_

shaolin
12th May 2014, 12:21
Oh sorry, you are right. In the end I will use it in QML, so if I have to implement the full view, I can export it as a QML Component. But if I just implement a delegate for QTableView, than I will not be able to export the full view in QML.

@anda: building Marble on Mac Os X is a hell, I tried..

wysota
12th May 2014, 12:25
If you want a custom view in QML then there is no base type to build upon, you have to implement all communication with the model by yourself.

shaolin
12th May 2014, 12:34
I think so too. But before this I will try 2 things:
creating a QML view using an horizontal ListView in which every element delegate is a vertical ListView.
If this will not work I could try to subclass QTableView, implementing its custom delegate, and exporting my QTableView subclass as a QML component...

anda_skoa
12th May 2014, 15:14
@anda: building Marble on Mac Os X is a hell, I tried..

In which case I would get in touch with the Marble developers.

Not only is a specialized for displaying maps and has all the related functionality that you would otherwise have to implement itself, it is also almost certainly that there is work to use it at least with QtQuick1 (I have marble on a Nokia N9, with pinch zoom, etc) and I wouldn't be surprised if there is at least a plan on making it work with QtQuick2.

I've used libmarblewidget in a widget based desktop application and was very glad that I only had to concern myself with the application speciifc data I needed to drow on top of the map.

Cheers,
_