Russian Qt Forum

Qt => Model-View (MV) => Тема начата: zamazan4ik от Январь 04, 2016, 20:03



Название: MVC модель, QTableView и QComboBox
Отправлено: zamazan4ik от Январь 04, 2016, 20:03
Доброго времени суток.

Стала у меня задача : нужно вывести данные в таблицу из двух столбцов, где в первом все элементы 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