PDA

View Full Version : QDataWidgetMapping multiple images to one Widget



caster89
1st October 2013, 21:19
Hello Everyone,
I'll try to be as clear as possible but I'll probably be missing some vital information so please let me know if I am not conveying the idea in my head well.
Suppose I have a database with 2 tables, one for storing "text" information and one for storing links to images, each record on the first table can be linked to multiple records on the "image" table. So basically a 1-n relationship. As of right now I just create two QVectors which store the data every time I select/add/modify a record, and then visualize it in widgets I made. in particular for the Images i use a QListWidget with a custom item delegate. When I am done with the record I update the database creating an sql string an executing it. I found out though that using the QDataWidgetMapper would make my life a whole lot simple, if I am not mistaken. I think I understood the basic concept behind how the mapper works, but here is my question, how do I map the multiple images I might have per record on the image table to my QListWidget so that when I change/remove add an image/description it will update it on the database table.
Thank you very much

anda_skoa
2nd October 2013, 10:30
Good question :)

The way the data widget mapper works is that it interfaces between two things: a model and widget properties.

So my take is that something like this could work:
1) you use a model that has all image links in a single cell, e.g. a table that has one row per entry of your text table and each of that rows has one column that contains all respective entries from the image table

2) have a list widget that has a property with compatible list type so that the data widget mapper can map the column directly into this

3) have a signal in the widget that is emitted then the image list changes and connect that to data widget mapper's submit() slot.

Cheers,
_

caster89
2nd October 2013, 11:58
Ok so what you are suggesting is to basically delete the image table which right now is basically a table with rows "id"-"file_path"-"description" and place it as one of the fields of my main_table (I could at this point remove the id field as i do not need to find the images anymore). I had originally though of doing something like that, but my problem was, how do I place a list in an SQLite table, especially since it's not going to be 1d but 2D (I also have a description for each image) so i would have to have a 'semi'-complex csv table within the row.
Thanks for the interest

anda_skoa
2nd October 2013, 13:35
No, I think you misunderstood me :)

I am suggesting that the model mapping the database content into the widget mapper is simplyfing the image table data into a column.

A model is basically always and adaptor between the actual data source and the requirements of the view. For example if your data is structured as a table, a table view can obviously directly work with that structure. But if the view is a list, then the table needs to be folded into a single column somehow.

In your case you would map two tables into one table like structure so that each widget the data widget mapper works with has to only deal with one column of that new table structure.

Cheers,
_

caster89
2nd October 2013, 14:06
Ok so what I should do is create a QDataWidgetMapper which reads the two tables and maps it as one in which one of the colums contains a list? I'm not too sure of what object I should create whether a QDataWidgetmapper or a QSqlModel ;s I kind of get lost in the Model/View approach, which was the reason for which initially I handled everything except the basic database to tableview interaction,

anda_skoa
2nd October 2013, 17:10
You would need to create a class derived from QAbstractTableModel which internall would use QSql.

But that could be a bit too much for you if you are new to all this.

Might be easier to just do everything explicitly, i.e. using QSqlQuery for getting the data from the database, putting the currently displayed data into some class members, interacting with the widgets through their C++ API.

The data widget mapper approach is more a convenience shortcut if your data is already in a suitable model.

Cheers,
_

caster89
2nd October 2013, 17:48
Well I might as well learn how to:) So let's see if I got this straight so I can do some research and maybe post the code here in a few days in case I have some problem or just for public knowledge.
I create a QAbstractTableModel, I can probably use most of QSqlTableModel methods, but have to reimplement the methods for the particular "image" field. The last question I have for now, which I've had also when creating a new ItemDelegate is: where do I find the methods I need to implement, and how they work in the "standard" way (i.e. how QSqlTableModel is implemented)

anda_skoa
3rd October 2013, 09:10
The base for all models is QAbstractItemModel. In its documentation you will see a couple of pure virtual methods, i.e. those that have to be implemented by the model developer.
For example rowCount(), data() or index()

The documentation of QAbstractTableModel has a section labelled "reimplemented public function" which contains index() so this one is off the list of things you have to implement.
Basically leaving: rowCount(), columnCount() and data()

Since you have a table and not a tree you can ignore the "parent" argument for rowCount() and columnCount().

For data(), you will get a QModelIndex and a role.
The model index contains row() and column() information.
The role tells you what kind of value the view is trying to get, e.g. for Qt::DisplayRole you should return a QString that is the text to display. For all roles that you don't have data for just return QVariant().

Cheers,
_

caster89
21st October 2013, 08:56
Sorry for the late reply, I wanted to try and get it to work before thanking, but I saw I have too many things to do in the meantime and it is going to take some time. I'll try to get it to work and maybe post my result as soon as possible. Right now I got stuck in trying to make a qvector of a custom class