PDA

View Full Version : QMap problem



sophister
7th May 2009, 17:45
Hi, I am writing an application that needs to use QMap in the following way QMap<int, QMap<QString, QToolButton*> *> tabs. But now I want to insert value into the inner QMap<QString, QToolButton*>*, but the QMap::value() always return a constant that I cannot inset or modify any data in it.

Do you guys know some solutions?
Thanks in advance.

caduel
7th May 2009, 19:40
First, use operator[] instead of value().

Apart from that: make sure you really need to store a pointer to a QMap.
I doubt you need to do that. It is perfectly fine to have a map of maps.
(And maybe use a typedef to get things more readable.)


typedef QMap<QString,QToolButton>* TBMap;
QMap<int,TBMap> tbmap;
tbmap[1]["hello"] = new QToolButton(...);

HTH

spirit
7th May 2009, 19:58
First, use operator[] instead of value().

but value works fater then [].
from docs


In general, we recommend that you use contains() and value() rather than operator[]() for looking up a key in a map. The reason is that operator[]() silently inserts an item into the map if no item exists with the same key (unless the map is const). For example, the following code snippet will create 1000 items in memory:

caduel
7th May 2009, 20:30
I agree.
But the OP wrote he wants to insert into the map. You can't do that with value().

spirit
7th May 2009, 20:45
but we can use insert, since QMap stores unique values.
it's just IMHO. :)
but I preffered this method.

faldzip
7th May 2009, 22:53
but can you see the difference:


T & operator[] ( const Key & key );

and


const T value ( const Key & key ) const;

?
operator[] is returning reference to the stored item, so you can change it with that reference, but value() is returning const copy of the item, so you can change it, and even if it won't be const it's still a copy so you would be changing the copy only.

P.S. I copied finctions from docs.

spirit
8th May 2009, 07:17
I know about difference. ;)
using value/insertValue you can achive the same result.


...
QMap<int, QMap<QString,QToolButton> > tbmap;
...
QMap<QString,QToolButton> map = tbmap.value(1);
map.insertValue("toolButton", new QToolButton);
tmap.insert(1, map);

the theread starter should remember that if
map has a value and it is being reset then old value will be overwrote.

spirit
8th May 2009, 09:04
this is test of these approaches


#include <QMap>
#include <QTime>
#include <QDebug>

int main(int argc, char **argv)
{
Q_UNUSED(argc);
Q_UNUSED(argv);

QTime startInsertionsTest1;
startInsertionsTest1.start();
qDebug() << "start insertion (insert/value): " << startInsertionsTest1;
QMap<int, QMap<QString, QString> > map1;
for (int i = 0; i < 1000; ++i) {
QMap<QString, QString> tempMap;
for (int j = 0; j < 1000; ++j)
tempMap.insert(QString::number(j), QString::number(j));
map1.insert(i, tempMap);
}
const int test1 = startInsertionsTest1.elapsed();
qDebug() << "end: " << test1;

QTime startInsertionsTest2;
startInsertionsTest2.start();
qDebug() << "start insertion (operator []): " << startInsertionsTest2;
QMap<int, QMap<QString, QString> > map2;
for (int i = 0; i < 1000; ++i) {
QMap<QString, QString> tempMap;
for (int j = 0; j < 1000; ++j)
tempMap[QString::number(j)] = QString::number(j);
map2[i] = tempMap;
}
const int test2 = startInsertionsTest2.elapsed();
qDebug() << "end: " << test2;

QTime startInsertionsTest3;
startInsertionsTest3.start();
qDebug() << "start updatetion (insert/value): " << startInsertionsTest3;
for (int i = 0; i < 1000; ++i) {
QMap<QString, QString> tempMap(map1.value(i));
QMap<QString, QString>::iterator it(tempMap.begin());
for (; it != tempMap.end(); ++it)
it.value() = "a";
map1.insert(i, tempMap);
}
const int test3 = startInsertionsTest3.elapsed();
qDebug() << "end: " << test3;

QTime startInsertionsTest4;
startInsertionsTest4.start();
qDebug() << "start updatetion (operator []): " << startInsertionsTest4;
for (int i = 0; i < 1000; ++i) {
QMap<QString, QString> tempMap(map2[i]);
QMap<QString, QString>::iterator it(tempMap.begin());
for (; it != tempMap.end(); ++it)
it.value() = "a";
map1[i] = tempMap;
}
const int test4 = startInsertionsTest4.elapsed();
qDebug() << "end: " << test4;

qDebug() << "--------------------";
qDebug() << "insertion using (insert/value) time: " << test1;
qDebug() << "insertion using (operator[]) time: " << test2;
qDebug() << "insertion diff (insert/value - operator[]): " << test1 - test2;

qDebug() << "updation using (insert/value) time: " << test3;
qDebug() << "updation using (operator[]) time: " << test4;
qDebug() << "updation diff (insert/value - operator[]): " << test3 - test4;
return;
}

this is a result


start insertion (insert/value): QTime("10:03:22")
end: 11281
start insertion (operator []): QTime("10:03:33")
end: 11578
start updatetion (insert/value): QTime("10:03:45")
end: 4047
start updatetion (operator []): QTime("10:03:49")
end: 6703
--------------------
insertion using (insert/value) time: 11281
insertion using (operator[]) time: 11578
insertion diff (insert/value - operator[]): -297
updation using (insert/value) time: 4047
updation using (operator[]) time: 6703
updation diff (insert/value - operator[]): -2656

PS. maybe it's not so good, but anyway...:)

sophister
8th May 2009, 09:27
Thank you all very much!!!