Come combinare QAbstractTableModel e QItemDelegate una fonte di lavoro?
-
27-09-2019 - |
Domanda
Ho un QTableView
definisce nel file utente. Ecco la figura:
Mi piacerebbe fare il cambiamento mese (dove il Red punti di array) con widget di QComboBox
, si occupano di delegati, ma per me, per il mio delegato personalizzato e il modello è un problema troppo complesso, e io non riesco a capire che cosa è sbagliato?!
problema : il mio parere, non può QAbstractTableModel
lavoro con QItemDelegate
, perché sono in grado di unire la mia widget di ComboBoxDelegate
semplice personalizzato con QTableView. Wtf?
Ecco quello che ho:
I miei delegato personalizzato dei dati di intestazione / origine:
class ComboBoxDelegate : public QItemDelegate
{
Q_OBJECT
public:
ComboBoxDelegate(QObject *parent = 0);
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
ComboBoxDelegate::ComboBoxDelegate(QObject *parent)
: QItemDelegate(parent)
{}
QWidget *ComboBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &index) const
{
QComboBox* editor = new QComboBox(parent);
editor->addItem(index.data(Qt::DisplayRole).toString());
return editor;
}
void ComboBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QComboBox *comboBox = static_cast<QComboBox*>(editor);
comboBox->setCurrentIndex(comboBox->findText(value));
}
void ComboBoxDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox *comboBox = static_cast<QComboBox*>(editor);
QString value = comboBox->currentText();
model->setData(index, value, Qt::EditRole);
}
Modello di dati:
class PortfolioModel : public QAbstractTableModel
{
Q_OBJECT;
// types
enum Position
{
ePosValue = 0
, eColumnCount
};
enum Constants
{
eLocalCcy = 0
, eCurrentTime
, eCurrentMonthName
, eRowCount
};
// data
static QFont font_;
static QBrush foreground_;
static QBrush background_;
// methods
QVariant _valueName(int index) const;
QVariant _valueNameTooltip(int index) const;
QVariant _data(int index, int col, bool tooltip) const;
public:
PortfolioModel(QObject* parent = 0);
~PortfolioModel();
int rowCount(const QModelIndex& parent = QModelIndex()) const;
int columnCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
signals:
void resizeToContents(void);
public slots:
void refreshData(void);
};
QFont PortfolioModel::font_ = QFont("Tahoma", 8, QFont::Normal);
QBrush PortfolioModel::foreground_ = QBrush(QColor("#000000")); // Black
QBrush PortfolioModel::background_ = QBrush(QColor("#C3FDB8")); // Dark Sea Green1
PortfolioModel::PortfolioModel(QObject* parent)
: QAbstractTableModel(parent)
{}
PortfolioModel::~PortfolioModel()
{}
void PortfolioModel::refreshData(void)
{
emit dataChanged(QModelIndex(), QModelIndex());
emit resizeToContents();
}
int PortfolioModel::rowCount(const QModelIndex& parent/* = QModelIndex()*/) const
{
return eRowCount;
}
int PortfolioModel::columnCount(const QModelIndex& parent/* = QModelIndex()*/) const
{
return eColumnCount;
}
QVariant PortfolioModel::data(const QModelIndex& index, int role/* = Qt::DisplayRole*/) const
{
if (!index.isValid())
return QVariant();
switch (role)
{
case Qt::DisplayRole:
return _data(index.row(), index.column(), false);
case Qt::FontRole:
break;
case Qt::BackgroundRole:
return background_;
case Qt::ForegroundRole:
return foreground_;
case Qt::TextAlignmentRole:
case Qt::DecorationRole:
case Qt::EditRole:
break;
case Qt::ToolTipRole:
return _data(index.row(), index.column(), true);
case Qt::StatusTipRole:
case Qt::WhatsThisRole:
case Qt::SizeHintRole:
break;
}
return QVariant();
}
QVariant PortfolioModel::headerData(int section, Qt::Orientation orientation, int role) const
{
switch (orientation)
{
case Qt::Horizontal:
switch (role)
{
case Qt::DisplayRole:
if (section == ePosValue)
{
return QVariant("Value");
}
case Qt::ToolTipRole:
if (section == ePosValue)
{
return QVariant("Fund values");
}
break;
}
case Qt::Vertical:
switch (role)
{
case Qt::DisplayRole:
return _valueName(section);
case Qt::ToolTipRole:
return _valueNameTooltip(section);
}
break;
}
return QVariant();
}
QVariant PortfolioModel::_valueNameTooltip(int index) const
{
switch (index)
{
case eLocalCcy:
return QObject::tr("Local currency");
case eCurrentTime:
return QObject::tr("Current time");
case eCurrentMonthName:
return QObject::tr("Current Month");
}
return QVariant();
}
QVariant PortfolioModel::_valueName(int index) const
{
switch (index)
{
case eLocalCcy:
return QObject::tr("Local Currency");
case eCurrentTime:
return QObject::tr("Current Time");
case eCurrentMonthName:
return QObject::tr("Month");
}
return QVariant();
}
QVariant PortfolioModel::_data(int index, int col, bool tooltip) const
{
switch (index)
{
case eLocalCcy:
if (col == ePosValue)
{
return QString(Nav::bk()->currentFund().currency(Nav::bk()->currentFund().localCcy()).code());
}
break;
case eCurrentTime:
if (col == ePosValue)
{
return Nav::bk()->currentFund().currentTime();
}
break;
case eCurrentMonthName:
if (col == ePosValue)
{
return QDate::longMonthName(Nav::bk()->currentFund().currentTime().date().month());
}
break;
}
return QVariant();
}
E dopo che ho fatto delegato init così:
ComboBoxDelegate *delegate_ = new ComboBoxDelegate(this);
this->ui.tableView->setItemDelegate(delegate_);
PS: Ci scusiamo per la lunga uscita, ma penso che sia sarà meglio se tutte le fonti saranno presentati qui
.Grazie!
Soluzione
Dalla panoramica dei QAbstractItemModel (vedere la sottoclasse voce):
Per abilitare la modifica nel modello, è deve anche implementare setData (), e bandiere reimplementare () per garantire che ItemIsEditable viene restituito.
La stessa informazione è riportata nella panoramica dei QAbstractTableModel . La classe PortfolioModel
non reimplementare una di queste funzioni. Per poter usare il redattore del delegato, è necessario utilizzare farlo.
In alternativa, si può solo vuole che appaia come se una casella combinata è lì (in realtà non consentire la modifica). Se questo è il caso, si avrà probabilmente bisogno di fare alcuni hack disegno voi stessi a far sembrare quel modo ... o contrassegnare come modificabile, ma disabilitare il widget, o qualcosa del genere.
Altri suggerimenti
http://qt-articles.blogspot.com/2010/07/how-to-customize-listview-in-qt-using.html un esempio è dato delegato .. si prega di controllare il delegato con l'esempio del campione del delegato presente nel blog. la speranza si potrebbe ottenere qualche indizio.