QTableView doesn't update and has strange cell style by default
-
Hi,
Why do the cells have these two squares on the right? This is a QTableView created with the Design tab.
Moreover, When I click de "Add product" button I call the update function on the model but the table doesn't display the value, what I'm missing?
The model of the table uses the m_activeProduct as underlying data.Button logic
connect(ui->addProductButton, &QPushButton::clicked, this, [this](){ Product p; p.m_name = "New product"; p.m_price = 0.0; m_activeReceipt->addProduct(p); auto model = static_cast<ProductModel*>(ui->productsTableView->model()); model->update(); });
Model update
void ProductModel::update(){ qDebug() << rowCount() << columnCount(); auto top_left = index(0,0,QModelIndex()); auto bottom_right = index(rowCount(),columnCount(),QModelIndex()); emit dataChanged(top_left, bottom_right, {Qt::EditRole}); }
-
Please show us your model. I don't see how changing m_activeReceipt should somehow magically update the model.
-
Here is the .h
#ifndef PRODUCTMODEL_H #define PRODUCTMODEL_H #include <QAbstractTableModel> #include "receipt.h" class ProductModel : public QAbstractTableModel { public: ProductModel(Receipt * data, QObject* parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); Qt::ItemFlags flags(const QModelIndex &index) const; void update( ) ; private: Receipt * m_data; }; #endif // PRODUCTMODEL_H
And the .cpp
#include "productmodel.h" #include <QDebug> ProductModel::ProductModel(Receipt *data, QObject *parent): QAbstractTableModel(parent), m_data(data) { } int ProductModel::rowCount(const QModelIndex &parent) const { return m_data->products().size(); } int ProductModel::columnCount(const QModelIndex &parent) const { return 2; } QVariant ProductModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { if (section % 2 == 0) return "Product"; else return "Price"; } else { return QString("%1").arg(section + 1); } } QVariant ProductModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { auto p = m_data->products(); if(index.column() == 0) return p[index.row()].m_name; else if(index.column() == 1){ return p[index.row()].m_price; } } else if (role == Qt::EditRole ) { auto p = m_data->products(); if(index.column() == 0) return p[index.row()].m_name; else if(index.column() == 1){ return p[index.row()].m_price; } }else{ return QColor(Qt::white); } return QVariant(); } bool ProductModel::setData(const QModelIndex &index, const QVariant &value, int role) { bool ok; if (index.isValid() && role == Qt::EditRole) { if(index.column() == 0){ auto p = m_data->products(); p[index.row()].m_name = value.toString(); emit dataChanged(index, index); return true; } else if( float val = value.toFloat(&ok); index.column() == 1 && ok){ auto p = m_data->products(); p[index.row()].m_price =val; emit dataChanged(index, index); return true; } } return false; } Qt::ItemFlags ProductModel::flags(const QModelIndex &index) const { return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; } void ProductModel::update(){ auto top_left = index(rowCount()-1,columnCount()-1,QModelIndex()); auto bottom_right = index(rowCount()-1,columnCount()-1,QModelIndex()); emit dataChanged(top_left, bottom_right, {Qt::EditRole}); }
-
So my question stands - how do you put your new data into the model?
Also you should not returnQColor(Qt::white);
for every role you don't process./edit: looks like you hold the data outside the model - don't do this.
-
@pachedo said in QTableView doesn't update and has strange cell style by default:
auto bottom_right = index(rowCount(),columnCount(),QModelIndex()); emit dataChanged(top_left, bottom_right, {Qt::EditRole});
In addition to @Christian-Ehrlicher .
This may not matter/be relevant to the behaviour you show, but I have two observations here:
-
I think it ought be
bottom_right = index(rowCount() - 1, columnCount() - 1, QModelIndex());
-
If
addProduct()
adds a row to your model(?),dataChanged
is not the right signal to emit. You should be usingbegin
/endInsertRows()
.
Your
}else{ return QColor(Qt::white); }
probably means you are returning
QColor(Qt::white);
when this is called asking about whether the item has a checkbox, and maybe that is causing your checkbox(es) to be shown? -