Hola eferion:
Ahora pondré el código completo. Realmente no es más que una excusa para poner en práctica todas las cosas que he aprendido.
Así que me he creado una estructura tal que así:
Código C++:
Ver originalenum eEstado{feliz,normal,triste};
struct Persona
{
QString Nombre;
QString Sexo;
int Edad;
eEstado estado;
};
Y este es el modelo:
mimodelo.h
Código C++:
Ver original#ifndef MIMODELO_H
#define MIMODELO_H
#include <QAbstractTableModel>
#include <QDebug>
enum eEstado{feliz,normal,triste};
struct Persona
{
QString Nombre;
QString Sexo;
int Edad;
eEstado estado;
};
const int FILAS=4;
const int COLUMNAS=4;
class MiModelo : public QAbstractTableModel
{
Q_OBJECT
public:
explicit MiModelo(QObject *parent = 0);
~MiModelo();
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);
QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex & index, const QVariant& value, int role);
private:
Persona persona[FILAS];
QStringList cabecera;
};
#endif // MIMODELO_H
mimodelo.cpp
Código C++:
Ver original#include "mimodelo.h"
MiModelo::MiModelo(QObject *parent) : QAbstractTableModel(parent)
{
cabecera<<"Nombre"<<"Sexo"<<"Edad"<<"Animo";
for (int i=0;i<FILAS;i++)
{
persona[i].Nombre="Noname";
persona[i].Sexo="Undefined";
persona[i].Edad=0;
persona[i].estado=normal;
}
}
MiModelo::~MiModelo()
{
for (int i=0;i<FILAS;i++)
{
qDebug()<<persona[i].Nombre<<" - "<<persona[i].Sexo<<" - "<<persona[i].Edad;
}
}
int MiModelo::rowCount (const QModelIndex & parent) const
{
Q_UNUSED (parent);
return FILAS;
}
int MiModelo::columnCount (const QModelIndex & parent) const
{
Q_UNUSED (parent);
return COLUMNAS;
}
QVariant MiModelo::headerData (int section, Qt::Orientation orientation, int role)
{
qDebug()<<"Funcion headerdata";
/*{
if (orientation == Qt::Horizontal)
{
if (role == Qt::DisplayRole)
{
qDebug()<<cabecera.at(section);
return cabecera.at(section);
}
}
qDebug()<<cabecera.at(section);
return QAbstractTableModel::headerData(section, orientation, role);
}*/
}
QVariant MiModelo::data (const QModelIndex & index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
if (index.column()==0)
{
return persona[index.row()].Nombre;
}
if (index.column()==1)
{
return persona[index.row()].Sexo;
}
if (index.column()==2)
{
return persona[index.row()].Edad;
}
if (index.column()==3)
{
return persona[index.row()].estado;
}
}
return QVariant();
}
Qt::ItemFlags MiModelo::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
bool MiModelo::setData(const QModelIndex & index, const QVariant& value, int role)
{
if (index.isValid() && (role == Qt::EditRole || role == Qt::DisplayRole))
{
if (index.column()==0)
{
persona[index.row()].Nombre=value.toString();
}
if (index.column()==1)
{
persona[index.row()].Sexo=value.toString();
}
if (index.column()==2)
{
persona[index.row()].Edad=value.toInt();
}
if (index.column()==3)
{
switch (value.toInt())
{
case 0:
{
persona[index.row()].estado=eEstado::feliz;
break;
}
case 1:
{
persona[index.row()].estado=eEstado::normal;
break;
}
case 2:
{
persona[index.row()].estado=eEstado::triste;
break;
}
default:
break;
}
}
emit dataChanged(index, index);
return true;
}
return false;
}
Y luego un delegado por cada columna.
He usado un delegado para la columna del nombre, en este caso con el único objetivo de usar expresiones regulares para que sólo acepte letras y no números:
midelegado0.cpp (para la columna 0):
Código C++:
Ver original#include "midelegado0.h"
#include <QLineEdit>
#include <QRegExpValidator>
MiDelegado0::MiDelegado0(QWidget *parent) : QStyledItemDelegate(parent){}
QWidget * MiDelegado0::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
Q_UNUSED (index);
Q_UNUSED (option);
QLineEdit* miEditor = new QLineEdit(parent);
QRegExpValidator* validadorTexto = new QRegExpValidator(QRegExp("[A-Za-z ]{1,20}"),miEditor);
miEditor->setValidator(validadorTexto);
return miEditor;
}
void MiDelegado0::setEditorData ( QWidget * editor, const QModelIndex & index ) const
{
QLineEdit* miEditor = static_cast<QLineEdit*>(editor);
miEditor->setText(index.data().toString());
}
void MiDelegado0::setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const
{
QLineEdit* miEditor = static_cast<QLineEdit*>(editor);
model->setData(index,miEditor->text());
}
void MiDelegado0::updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
Q_UNUSED (index);
editor->setGeometry(option.rect);
}
Luego un delegado para la columna de Sexo. En este caso es un QComboBox y además hago uso del método paint() para poner color a las letras en función del sexo.
midelegado1.cpp
Código C++:
Ver original#include "midelegado1.h"
#include <QComboBox>
#include <QStringList>
#include <QPainter>
#include <QColor>
MiDelegado1::MiDelegado1(QWidget *parent) : QStyledItemDelegate(parent)
{
lista<<"Masculino"<<"Femenino";
}
QWidget * MiDelegado1::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
Q_UNUSED (index);
Q_UNUSED (option);
QComboBox* miCombo = new QComboBox(parent);
miCombo->addItems(lista);
return miCombo;
}
void MiDelegado1::setEditorData ( QWidget * editor, const QModelIndex & index ) const
{
QComboBox* miCombo = static_cast<QComboBox*>(editor);
miCombo->setCurrentText(index.data().toString());
}
void MiDelegado1::setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const
{
QComboBox* miCombo = static_cast<QComboBox*>(editor);
model->setData(index,miCombo->currentText());
}
void MiDelegado1::updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
Q_UNUSED (index);
editor->setGeometry(option.rect);
}
void MiDelegado1::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QColor colorMasculino(Qt::cyan);
QColor colorFemenino(Qt::magenta);
painter->save();
if (index.data().toString()==lista.at(0))
{
QPen colorTexto(colorMasculino);
painter->setPen(colorTexto);
painter->drawText(option.rect,Qt::AlignCenter,index.data().toString());
}
else if (index.data().toString()==lista.at(1))
{
QPen colorTexto(colorFemenino);
painter->setPen(colorTexto);
painter->drawText(option.rect,Qt::AlignCenter,index.data().toString());
}
painter->restore();
}
(sigue)