QMap with multifields - qt

I need to store some data of table type like a QTableWidget but without a GUI. Something along the line of the following code:
QMap<QString, QString, int, QString, int>
Is there a way of achieve this in Qt? My Qt version is 5.3.

You seem to be unclear on a few concepts.
A map (also known in some languages as a dictionary) is an associative array. It associates a key to a value, that's about it, there are no "fields" involved whatsoever, just a key and a value.
There is no data type in Qt to model a database table. For such tasks you usually directly use SQL, Qt supports SQL with various different database drivers.
If you don't want to use a database but instead want to have "native" C++ types, you can simply create an object with all the desired fields:
struct Entry {
QString s1, s2, s3;
int i1, i2;
};
And then put that into whatever container you want.
QList<Entry> entryList;
QVector<Entry> entryVec;
QSet<Entry> entrySet;
You can wrap the container in a QAbstractListModel, implement the key functions and roles and have that model be used for a table widget or a QML view.

Related

Communication between models

My program loads records (one per line) from file in raw format.
I have some Views for displaying this data in different ways:
Byte View
Decimal View (by doing some calculations with byte ranges)
Both Views must provide the ability for editing values.
Here is some code:
class Record
{
public:
void setByte (int position, Byte byte);
void setValue (ValueType type, Value value);
Byte getByte (int position) const;
Value getValue (ValueType type) const;
private:
RawData data;
}
I'm loading records in
QVector<Record> records;
Byte View is a simple table with hex bytes (row - line number, column - byte position). Decimal View is a table too (row - line number, one column - value).
So,what's the best way to design Model(s) for my Views with the ability to communicate with each other (f.e. sending signals when a data was modified from one of the Views)?
As you're using Qt, it's usually best to subclass one of the Qt's own models. This way you'll get a lot of view widgets for free, and at the same time make your code more consistent by following the same standard as the rest of the toolkit you use. Qt's documentation have some guidelines stating which methods/signals/slots you must implement.
Some classes to take a look at: QAbstractItemModel, QAbstractTableModel and QAbstractListModel
For the view side, you should prefer to use widgets provided by Qt, and if necessary, implement a delegate to change it's appearance.
In your specific case, I'd subclass QAbstractTableModel, and wrap your records inside this class.

Storing pointers using QListWidgetItem::setData

I have a QListWidget of calendars. Each QListWidgetItem is logically associated with an instance of Calendar, which is a class that belongs to the Model side of the application.
Can I store this association in the form of a pointer using QListWidgetItem::setData? When I attempt to do this, I get the following error:
error: 'QVariant::QVariant(void*)' is private
There is another constructor for void*: QVariant::QVariant(int typeOrUserType, const void * copy) where you should pass an unique integer to represent the pointer type.
But as stated by the documentation, you could declare your pointer type with Q_DECLARE_METATYPE(Calendar*) and use QVariant::fromValue<Calendar*>(...) and QVariant::value<Calendar*>() to store and retrieve the value.
Or instead, because you are using a QListWidget instead of a regular model, you can just subclass QListWidgetItem, and add a Calendar* member variable with the required accessors, to avoid the overhead of using QVariant.
I would suggest looking at this solution as well, which I think is quite elegant:
(there are minor syntax errors, but you will spot them quickly or the compiler will issue an error)
https://web.archive.org/web/20171025163314/http://blog.bigpixel.ro/2010/04/storing-pointer-in-qvariant/

Qt Get signal-slot connection information from a widget

I have a feeling this isn't possible with the current API, but I have to ask. Is it possible to query a particular QObject's signal or slot name (from the metaObject) and retrieve all the QObjects and their slot or signals names that are connected to it?
I'm doing this because, in effect, I have a large number of layouts that contain an identical arrangement of widgets, for each layout there an object and each of the layout's widgets control the various properties of it. I want to keep one layout, and connect it's widgets' signal/slots to all the other objects in the same pattern, but in order to do this I need to 'record' all the signal-slot data.
Is it possible?
There is an interesting file in Qt - %Qtdir%/src/corelib/kernel/qobject_p.h, it contains class QObjectPrivate, used by Qt internally.
Use
static QObjectPrivate *get(QObject *o) function to get QObjectPrivate member for your widgets, and try to call its interesting members like
QObjectList receiverList(const char *signal) const; or QObjectList senderList() const;. File is totally undocumented, but it seems to contain exactly what you need...

Qt: QAbstractItemModel and 'const'

I'm trying to use a QTreeView for the first time with QAbstractItemModel and instantly have a problem. QAbstractItemModel interface declares methods as const, assuming they will not change data. But I want the result of a SQL query displayed, and returning data for a record with specified index requires the use of QSqlQuery::seek() which is non-const. Are there any 'official' guidelines to using a QAbstractItemModel with data that must be changed in order to get the number of items, data per item etc? Or must I hack C++ with const casts?
You can get away without any const casts by holding a pointer to the QSqlQuery; your pointer won't change, only the value to which you point, hence the operation will still be considered "const".

Binding a Qt model to an existing data-structure

I've a tree-like polymorphic data-structure, where the nodes are instances of class Node (implemented by me) or any its subclass. My application heavily uses Boost and the nodes are actually represented by boost::shared_ptr type rather than Node*.
Now, I want to create a Qt model to wrap my tree data-structure. Therefore I need a way to associate any model index with a node in my internal data structure. And here comes the problem:
Qt supports two ways of doing it:
First:
QModelIndex QAbstractItemModel::createIndex ( int row, int column, void * ptr = 0 ) const
Creates a model index for the given
row and column with the internal
pointer ptr.
And second:
QModelIndex QAbstractItemModel::createIndex ( int row, int column, quint32 id ) const
Creates a model index for the given
row and column with the internal
identifier, id.
Ok, and how exactly should I associate the node in my case? There is no possibility to associate a shared_ptr with the model index... Yes, I know, I can receive a raw pointer from my shared_ptr and supply it to CreateIndex(), but it smells bad - seems too unsafe to me.
Any ideas?
By the way, I feel that in general Boost / Qt integration seems to be not trivial at least in the area of memory management.
10x a lot.
If you want to do an easy association without passing a raw pointer, put the shared memory in a container and pass the ID value for that container element into the model index. For example, you could created declare
QMap< quint32, boost::shared_ptr< Foo > > index_map;
and use that. You'd have to be careful to not duplicate IDs for existing pointers, perhaps. It seems somewhat overly complicated to me....
You could also just keep a list of the pointers (to ensure continued availability as you need them) and then use the actual address of the pointer in the QModelIndex as well. This is probably what I would do.

Resources