Problems in understanding how to use a QComboBox in my QTableView derived class
Hi community,
in my code I have added a view derived from QTableView having 2 columns and x rows ( x is not fixed but grows ).
The first column contains text and there I show the content of the model that stores internally a string of strings.
The second columns have show a QComboBox where the user should be able to choose one of the combobox options (also a QString). I am using a class derived from QStyledItemDelegate for that purpose.
I have no problems with the first column, I can correctly add new rows with the right text.
My problem is with the column #2, I can show the combobox with the options but, after choosing one, if I click anywhere in the view, the combobox value clears.
So seems I am doing something wrong in storing and read the corect combobox value.
Here the code I used to create the item delegate
*.h
Code:
#ifndef SELECTEDLISTITEMDELEGATE_H
#define SELECTEDLISTITEMDELEGATE_H
#include <QStyledItemDelegate>
class SelectedListItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
SelectedListItemDelegate
(QObject *parent
= nullptr
);
~SelectedListItemDelegate() override;
};
#endif
and the cpp
Code:
#include "SelectedListItemDelegate.h"
#include <QComboBox>
#include <QDebug>
SelectedListItemDelegate
::SelectedListItemDelegate(QObject* parent
) : QStyledItemDelegate(parent)
{
}
SelectedListItemDelegate::~SelectedListItemDelegate()
{
}
{
Q_UNUSED(option)
// I considere 3 options just as an example
const int row = index.row();
comboBox
->addItem
(QString("Option %1").
arg(row
));
comboBox
->addItem
(QString("Option %1").
arg(row
));
comboBox
->addItem
(QString("Option %1").
arg(row
));
return comboBox;
}
// This routine does not set any value in the combobox
void SelectedListItemDelegate
::setEditorData(QWidget *editor,
const QModelIndex &index
) const {
QString value
= index.
model()->data
(index, Qt
::EditRole).
toString();
qDebug() << "Value:" << value; // Value is empty
QComboBox *comboBox
= qobject_cast<QComboBox
*>
(editor
);
comboBox->setCurrentIndex(comboBox->findText(value));
}
// Seems that the combobox value is not correctly written because is not kept in the cell. If I click outside its cleared
{
QComboBox *comboBox
= qobject_cast<QComboBox
*>
(editor
);
QString value
= comboBox
->currentText
();
model->setData(index, value, Qt::EditRole);
}
Can I have a help in understanding what's I am doing wrong?
Thanx
Re: Problems in understanding how to use a QComboBox in my QTableView derived class
Quote:
Can I have a help in understanding what's I am doing wrong?
In your model's setData() method, are you issuing the signals to tell views that the data has changed? QAbstractItemModel::dataChanged(), QAbstractItemModel::layoutAboutToBeChanged(), QAbstractItemModel::layoutChanged() or the protected methods when rows / columns are added or removed?
If the model does not send out the signals to tell views that its content has changed, then the view does not know it has to update. And when editing is finished, the delegate is destroyed along with whatever it was showing on screen. So the view remains the same as it was before editing.
Re: Problems in understanding how to use a QComboBox in my QTableView derived class
Thank you for the answer.
Can I have a piece of code to better understand?
Re: Problems in understanding how to use a QComboBox in my QTableView derived class
Quote:
Can I have a piece of code to better understand?
It would be better if you posted the code you have in your model's setData() method. That's where whatever needs to be done to notify views of a change in the model has to occur.
Re: Problems in understanding how to use a QComboBox in my QTableView derived class
Quote:
Originally Posted by
d_stranz
It would be better if you posted the code you have in your model's setData() method. That's where whatever needs to be done to notify views of a change in the model has to occur.
Below the code of setData()
Code:
{
if (role == Qt::EditRole && index.isValid())
{
m_reports[index.row()].replace("actionName", value.toString());
emit dataChanged(index, index, {role});
return true;
}
return false;
}
And data()
Code:
{
if (!index.isValid())
{
}
if (index.row() >= m_reports.size() || index.row() < 0)
{
}
if (role == Qt::DisplayRole)
{
const QMultiMap<QString, QString>& report = m_reports.at(index.row());
QString reportName
= report.
value("reportName");
QString actionName
= report.
value("actionName");
if (index.column() == 0)
{
return reportName;
}
else if (index.column() == 1)
{
return actionName;
}
}
else if (role == Qt::BackgroundRole)
{
if (index.column() == 1)
{
QString cellContent
= index.
data().
toString();
if (cellContent.contains("Click here"))
{
}
else
}
}
else if (role == Qt::TextAlignmentRole && index.column() == 1)
{
return Qt::AlignHCenter;
}
else if (role == Qt::FontRole)
{
font.setFamily("Optima");
font.setPointSize(10);
return font;
}
}
In the data() method I have a condition to specify the cells of column 1 background color but, the color does't not change until i click anywhere in the tableview.
How can I fix it?
Thank you
Re: Problems in understanding how to use a QComboBox in my QTableView derived class
Quote:
emit dataChanged(index, index, {role});
I think your "role" here needs to be Qt::DisplayRole. EditRole is used only when editing, not when updating the view after editing.
Quote:
In the data() method I have a condition to specify the cells of column 1 background color but, the color does't not change until i click anywhere in the tableview.
How can I fix it?
The Qt::BackgroundRole is used when drawing items that have the default delegate. Since you have a custom delegate, you may need to implement the QStyledItemDelegate::paint() method to draw the delegate with the correct background color. Note that if you do this, you also have to implement the sizeHint() method.