I have two models, Users (First Name, Last Name, Country) and Countries (Name). I made a delegate for the combobox in the Country field of the Users table. How can I fill it with data from the Country table?
Country.cpp
#include "Country.h"
Country::Country()
{
}
void Country::setName(const QString name)
{
m_name = name;
}
QString Country::getName() const
{
return m_name;
}
CountryTable.cpp
#include "CountryTable.h"
CountryTable::CountryTable(QObject *parent) : QAbstractTableModel (parent)
{
listOfCountries = new QList <Country> ();
}
int CountryTable::columnCount(const QModelIndex & parent) const {
return 1;
}
int CountryTable::rowCount(const QModelIndex & parent) const {
return listOfCountries->size();
}
QVariant CountryTable::data(const QModelIndex & index, int role) const {
if (index.isValid() && role == Qt ::DisplayRole)
return getData(index.row(), index.column());
return QVariant ();
}
QVariant CountryTable::getData(int num, int position) const {
switch (position) {
case 0:
return QVariant (listOfCountries->at(num).getName());
default:
return QVariant ();
}
}
bool CountryTable::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid()) {
return false;
}
Country &country = this->getCountry(index);
switch (index.column()) {
case 0:
country.setName(value.toString());
break;
default:
return false;
}
emit dataChanged(index, index);
return true;
}
QVariant CountryTable::headerData(int section, Qt ::Orientation orientation, int role) const {
if (role != Qt ::DisplayRole)
return QVariant ();
if (orientation == Qt ::Vertical)
return QVariant (section + 1);
else
switch (section) {
case 0:
return QVariant ("Name");
default:
return QVariant ();
}
}
Qt ::ItemFlags CountryTable::flags(const QModelIndex & index) const {
return Qt ::ItemIsSelectable | Qt ::ItemIsEnabled | Qt ::ItemIsEditable;
}
Country& CountryTable::getCountry(const QModelIndex & index) const {
return (*listOfCountries)[index.row()];
}
void CountryTable::addCountry(Country& newCountry) {
beginInsertRows(QModelIndex (), listOfCountries->size(), listOfCountries->size());
listOfCountries->append(newCountry);
endInsertRows();
}
void CountryTable::delCountry(const QModelIndex &index) {
beginRemoveRows(QModelIndex (), index.row(), index.row());
listOfCountries->removeAt(index.row());
endRemoveRows();
}
User.cpp
#include "User.h"
QVector<User*> User::usersList;
User::User()
{
usersList.push_back(this);
}
User::~User()
{
}
void User::setName(const QString name)
{
m_name = name;
}
void User::setSurname(const QString surname)
{
m_surname = surname;
}
void User::setCountry(const QString country)
{
m_country = country;
}
QString User::getName() const
{
return m_name;
}
QString User::getSurname() const
{
return m_surname;
}
QString User::getCountry() const
{
return m_country;
}
QVector<User*> User::getAllUsers()
{
return usersList;
}
UsersTable.cpp
#include "UsersTable.h"
#include <QDebug>
UsersTable::UsersTable(QObject *parent) : QAbstractTableModel (parent)
{
listOfUsers = new QList <User> ();
}
int UsersTable::columnCount(const QModelIndex & parent) const {
return 3;
}
int UsersTable::rowCount(const QModelIndex & parent) const {
return listOfUsers->size();
}
QVariant UsersTable::data(const QModelIndex & index, int role) const {
if (index.isValid() && role == Qt ::DisplayRole)
return getData(index.row(), index.column());
return QVariant ();
}
QVariant UsersTable::getData(int num, int position) const {
switch (position) {
case 0:
return QVariant (listOfUsers->at(num).getName());
case 1:
return QVariant (listOfUsers->at(num).getSurname());
case 2:
return QVariant (listOfUsers->at(num).getCountry());
default:
return QVariant ();
}
}
bool UsersTable::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid()) {
return false;
}
User &user = this->getUser(index);
switch (index.column()) {
case 0:
user.setName(value.toString());
break;
case 1:
user.setSurname(value.toString());
break;
case 2:
user.setCountry(value.toString());
break;
default:
return false;
}
emit dataChanged(index, index);
return true;
}
QVariant UsersTable::headerData(int section, Qt ::Orientation orientation, int role) const {
if (role != Qt ::DisplayRole)
return QVariant ();
if (orientation == Qt ::Vertical)
return QVariant (section + 1);
else
switch (section) {
case 0:
return QVariant ("Name");
case 1:
return QVariant ("Surname");
case 2:
return QVariant ("Country");
default:
return QVariant ();
}
}
Qt ::ItemFlags UsersTable::flags(const QModelIndex & index) const {
return Qt ::ItemIsSelectable | Qt ::ItemIsEnabled | Qt ::ItemIsEditable;
}
User& UsersTable::getUser(const QModelIndex & index) const {
return (*listOfUsers)[index.row()];
}
void UsersTable::addUser(User& newUser) {
beginInsertRows(QModelIndex (), listOfUsers->size(), listOfUsers->size());
listOfUsers->append(newUser);
endInsertRows();
}
void UsersTable::delUser(const QModelIndex & index) {
beginRemoveRows(QModelIndex (), index.row(), index.row());
listOfUsers->removeAt(index.row());
endRemoveRows();
}
DelegateComboBox.cpp
#include "DelegateComboBox.h"
#include <QLineEdit>
#include <QComboBox>
#include <QDebug>
DelegateComboBox::DelegateComboBox(const QStringList &country, QObject *parent)
:QStyledItemDelegate(parent), countryList(country)
{ }
QWidget* DelegateComboBox::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QComboBox *comboBox = new QComboBox(parent);
comboBox->addItems(countryList);
comboBox->setCurrentIndex(-1);
return comboBox;
}
void DelegateComboBox::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString text = index.model()->data(index, Qt::EditRole).toString();
QComboBox *comboBox = static_cast<QComboBox*>(editor);
if(text.isEmpty()){
QLineEdit *edit=new QLineEdit;
QFont font=edit->font();
font.setBold(true);
font.setItalic(true);
edit->setFont(font);
edit->setPlaceholderText("Select country");
comboBox->setLineEdit(edit);
comboBox->lineEdit()->setReadOnly(true);
return;
}
int idx=comboBox->findText(text);
comboBox->setCurrentIndex(idx);
}
void DelegateComboBox::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox *comboBox = static_cast<QComboBox*>(editor);
QString text = comboBox->currentText();
model->setData(index, text, Qt::EditRole);
}
void DelegateComboBox::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
MainWindow.cpp
dataTable = new UsersTable(this);
view = new QTableView (this);
view->setModel(dataTable);
view->resizeColumnsToContents();
add = new QPushButton ("Add new User");
del = new QPushButton ("Delete selected User");
showQDebug = new QPushButton ("Show");
QWidget *box = new QWidget ();
QVBoxLayout *layout = new QVBoxLayout ();
layout->addWidget(view);
QHBoxLayout *buttonLayout = new QHBoxLayout ();
layout->addLayout(buttonLayout);
buttonLayout->addWidget(add);
buttonLayout->addWidget(del);
buttonLayout->addWidget(showQDebug);
box->setLayout(layout);
setCentralWidget(box);
setWindowTitle("Table of Users");
QStringList country;
country<<"Burundi"<<"Burkina Faso"<<"Cambodia"<<"Cameroon";
auto delegate = new DelegateComboBox(country);
view->setItemDelegateForColumn(2, delegate);
connect(add, SIGNAL(clicked()), this, SLOT(addButtonClicked()));
connect(del, SIGNAL(clicked()), this, SLOT(delButtonClicked()));
connect(showQDebug, SIGNAL(clicked()), this, SLOT(showUsersData()));
As you can see, in the MainWindow file, now I just write the data manually to the QStringList. Tell me how to take data from the Country model?
my attempts
CountriesTable.h
static QList<Country>* getAllCountries();
private:
static QList <Country> *allCountries;
CountriesTable.cpp
QList <Country> *CountriesTable::allCountries;
QList<Country>* CountriesTable::getAllCountries() {
return allCountries;
}
to add and remove
void CountriesTable::addCountry(Country& newCountry) {
beginInsertRows(QModelIndex (), listOfCountries->size(), listOfCountries->size());
listOfCountries->append(newCountry);
endInsertRows();
allCountries->append(newCountry);
}
void CountryTable::delCountry(const QModelIndex &index) {
beginRemoveRows(QModelIndex (), index.row(), index.row());
listOfCountries->removeAt(index.row());
endRemoveRows();
allCountries->removeAt(index.row());
}
And then I tried in the constructor of the delegate of the combobox to somehow use the static method that I created, but it didn’t work out for me (((
DelegateComboBox::DelegateComboBox(QObject *parent)
:QStyledItemDelegate(parent)
{
......CountryTable::getAllCountries(); ......
}