Доброго времени суток.
Стала у меня задача : нужно вывести данные в таблицу из двух столбцов, где в первом все элементы QString и просто должны отображать как надписи(тут всё ок), а во втором столбце - должны быть виджеты QCheckBox, QLineEdit, QComboBox (какой именно виджет, зависит от данных, которые передаются с модели).
Я только начал изучение реализации модели MVC в QT, и пока не совсем понимаю это модели с Моделями, Представлениями и Делегатами. Как я понял, Модель это интерфейс к данным, Представление - это графическое представление данных, которое оно получают от модели, а Делегат это некое связующее звено. По моему пониманию, все запросы между моделью и данными должны проходить через делегат.
Что касается практической части : я пока только пытаюсь вывести таблицу, в которой все элементы буду QComboBox с заданными значениями. Но не получается. Вот мой код (можете видить, что является некоторой компоновкой примеров из Шлее):
main.cpp
#include <QtWidgets>
#include <QObject>
#include "simpledelegate.h"
#include "tablemodel.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
TableModel model(200, 200);
QTableView tableView;
tableView.setModel(&model);
tableView.setItemDelegate(new SimpleDelegate(&tableView));
tableView.viewport()->setAttribute(Qt::WA_Hover);
tableView.show();
return app.exec();
}
simple.h
#ifndef SIMPLEDELEGATE
#define SIMPLEDELEGATE
#include <QWidget>
#include <QStyledItemDelegate>
#include <QComboBox>
#include <QObject>
class SimpleDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
SimpleDelegate(QObject* pobj = 0);
QWidget* createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index);
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index);
void setEditorData(QWidget *editor, const QModelIndex &index);
};
#endif // SIMPLEDELEGATE
simple.cpp
#include "simpledelegate.h"
SimpleDelegate::SimpleDelegate(QObject* pobj) : QStyledItemDelegate(pobj)
{
}
QWidget* SimpleDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
QStringList values;
values << "Enabled" << "Disabled";
QComboBox* comboBox = new QComboBox(parent);
comboBox->addItems(values);
return comboBox;
}
void SimpleDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index)
{
QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
QString value = comboBox->currentText();
model->setData(index, value, Qt::EditRole);
}
void SimpleDelegate::setEditorData(QWidget *editor, const QModelIndex &index)
{
QString value = index.model()->data(index, Qt::EditRole).toString();
//qDebug() << "Value:" << value;
QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
comboBox->setCurrentIndex(comboBox->findText(value));
}
tablemodel.h
#ifndef TABLEMODEL
#define TABLEMODEL
#include <QWidget>
#include <QStyledItemDelegate>
#include <QComboBox>
#include <QObject>
class TableModel : public QAbstractTableModel
{
Q_OBJECT
private:
int m_nRows;
int m_nColumns;
QHash<QModelIndex, QVariant> m_hash;
public:
TableModel(int nRows, int nColumns, QObject* pobj = 0);
QVariant data(const QModelIndex& index, int nRole) const;
bool setData(const QModelIndex& index,
const QVariant& value,
int nRole
);
int rowCount(const QModelIndex&) const ;
int columnCount(const QModelIndex&) const ;
Qt::ItemFlags flags(const QModelIndex& index) const;
};
#endif // TABLEMODEL
tablemodel.cpp
#include "tablemodel.h"
TableModel::TableModel(int nRows, int nColumns, QObject* pobj)
: QAbstractTableModel(pobj)
, m_nRows(nRows)
, m_nColumns(nColumns)
{
}
QVariant TableModel::data(const QModelIndex& index, int nRole) const
{
if (!index.isValid())
{
return QVariant();
}
QString str = QString("%1,%2").arg(index.row() + 1).arg(index.column() + 1);
return (nRole == Qt::DisplayRole || nRole == Qt::EditRole)
? m_hash.value(index, QVariant(str))
: QVariant();
}
bool TableModel::setData(const QModelIndex& index,
const QVariant& value,
int nRole
)
{
if (index.isValid() && nRole == Qt::EditRole) {
m_hash[index] = value;
emit dataChanged(index, index);
return true;
}
return false;
}
int TableModel::rowCount(const QModelIndex&) const
{
return m_nRows;
}
int TableModel::columnCount(const QModelIndex&) const
{
return m_nColumns;
}
Qt::ItemFlags TableModel::flags(const QModelIndex& index) const
{
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
return index.isValid() ? (flags | Qt::ItemIsEditable)
: flags;
}
Что я пытаюсь сделать на этих исходниках : сделать свою модель данных, которую я хочу соединить со стандартным QTableView через делегат SimpleDelegate. Но у меня вместо моих QComboBox в коде обычные поля редактирования.
Подскажите пожалуйста, где здесь ошибки? Я понимаю, что из модели я передаю данные для заполнения индексы строки и столбца, но почему QComboBox нигде нет?
Если важно : Qt 5.5.1, IDE - Qt Creator 3.5.1, Linux Mint 17.2 KDE