QT C++ Key-Value Pair Implementation with Template Class
Hello everyone, in this article we are going to talk about how can we create our custom key - value pair arrays in Qt C++ and Template programming and QVector.Let's begin.
In here we are going to use Template programming. So if you have no idea of Template programming firstly take a look at below article. https://thecodeprogram.com/explanation-of-template-programing-in-c---and-qt
In C# I used Dictionary class for this purpose very much. So I will use the Dictionary word since here.
Firstly we need to create a Header file and name it What you want. I here named this header file as QDictionary. Here we did not created cpp file because we can not access the private variables directly. One of our articles I will talk about PIMPL design patter to access them in C++.
In this header file we will create a template class and its private and public sections. Then I will implement required methods and variables in this class.
Below you can see our template class property and method structure.
qdictionary.h
#include <QVector>
#include <QString>
#include <QDebug>
template <typename TKey, typename TValue> class QDictionary
{
private:
TKey key;
TValue value;
unsigned int size =0;
QVector<TKey> * arrKeys = new QVector<TKey>(1);
QVector<TValue> * arrValues = new QVector<TValue>(1);
QString controlKeyOutput(TKey k){
std::string t = typeid(TKey).name();
if(t == "int" ) return QString::number(k);
//else if(t == "class QString" ) return k;
else return "";
}
//I have no ideo why it is returning 7QString.
//it was returning class QString at QT 5.8
QString controlValueOutput(TValue v){
std::string t = typeid(TValue).name();
if(QString::fromStdString(t).indexOf("QString") > -1) return v;
else return "";
}
public:
QDictionary();
void add(TKey k, TValue v){
arrKeys->append(k);
arrValues->append(v);
size++;
//prepare for next adding
arrKeys->resize(size+1);
arrKeys->resize(size+1);
}
TValue getWithkey(TKey k){
int index = arrKeys->indexOf(k);
return arrValues->at(index);
}
void removeFromIndex(int i){
arrKeys->remove(i);
arrValues->remove(i);
size--;
//prepare for next adding
arrKeys->resize(size-1);
arrKeys->resize(size-1);
}
void removeFromKey(TKey k){
int index = arrKeys->indexOf(k);
removeFromIndex(index);
}
void removeFromValue(TValue v){
int index = arrValues->indexOf(v);
removeFromIndex(index);
}
int getSize(){ return size; }
QString getPairAtKey(TKey k){
qDebug() << "TValue türü : " << typeid(TValue).name() << Qt::endl;
int index = arrKeys->indexOf(k);
QString rK = controlKeyOutput( arrKeys->at(index) ) ;
QString rV = controlValueOutput( arrValues->at(index) );
return rK + "=" + rV;
}
QString getAllValues(){
QString output = "";
for(unsigned int i=0; i<arrValues->size(); i++){
output += controlValueOutput(arrValues->at(i)) + "\n";
}
return output;
}
};
Let's talk about some of above methods.
add(TKey k, TValue v) method:
void add(TKey k, TValue v){
arrKeys->append(k);
arrValues->append(v);
size++;
//prepare for next adding
arrKeys->resize(size+1);
arrKeys->resize(size+1);
}
We will insert datas into our Dictionary with add method. We will use initialized data types. In here we are going to set the array size after insert to prepare the aray for next adding.
we will get data wusing key with getWithkey(TKey k) method.
TValue getWithkey(TKey k){
int index = arrKeys->indexOf(k);
return arrValues->at(index);
}
In here we find index of key and return the data from values vector at same index.
we will use removeFromIndex(int i) and removeFromKey(TKey k) methods to remove datas from Dictionary.
void removeFromIndex(int i){
arrKeys->remove(i);
arrValues->remove(i);
size--;
//prepare for next adding
arrKeys->resize(size-1);
arrKeys->resize(size-1);
}
void removeFromKey(TKey k){
int index = arrKeys->indexOf(k);
removeFromIndex(index);
}
In here using both method we find the index of data and removed its index. After removing data we resize the QVector to prepare it next adding. We will prevent the overflowing of QVectors.
Also we can get data types of variables with typeid.
QString controlKeyOutput(TKey k){
std::string t = typeid(TKey).name();
if(t == "int" ) return QString::number(k);
//else if(t == "class QString" ) return k;
else return "";
}
QString controlValueOutput(TValue v){
std::string t = typeid(TValue).name();
if(t == "class QString" ) return v;
else return "";
}
As you can see above we get the name of data type. It outputs as class QString or whatever it is. You can write in in debug console. You can also get other values of variable which usng typeid.
Until here out methods are ready. Now, It is time to test our QDictionary.
At my UI class
mainwindow.cpp
QString res = "";
Dictionary<int, QString> *dict = new Dictionary<int, QString>();
dict->add(1,"Burak");
dict->add(2,"Hamdi");
dict->add(3,"Tufan");
dict->add(4,"The");
dict->add(5,"Code");
dict->add(6,"Program");
res += "Added some values to dictionary with keys...\n";
res += "Dictionary Size : " + QString::number( dict->getSize() ) + " \n";
res += dict->getAllValues();
res += QStringLiteral("Value with key 3 : %1. \n").arg( dict->getWithkey(3) ) ;
res += QStringLiteral("Value with key 5 : %1. \n\n").arg( dict->getWithkey(5) ) ;
dict->removeFromKey(1);
res += "Removed data on Key 1...\n";
res += "Dictionary Size : " + QString::number( dict->getSize() ) + " \n";
res += QStringLiteral("Value with key 2 : %1. \n").arg( dict->getWithkey(2) ) ;
res += dict->getAllValues();
res += "Key-Value pair at key 4 -> " + dict->getPairAtKey(4);
ui->plainTextEdit->setPlainText(res);
That is all in this article.
You can reach the source code of example on Github via below link.
https://github.com/thecodeprogram/Dictionary-Impl.-With-Template-in-Qt-C-
Burak Hamdi TUFAN
Comments