Ver Mensaje Individual
  #3 (permalink)  
Antiguo 15/03/2015, 10:25
dehm
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 2 meses
Puntos: 10
Respuesta: Qt. Delegados. Usar diferente widget para editar y para mostrar

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 original
  1. enum eEstado{feliz,normal,triste};
  2.  
  3. struct Persona
  4. {
  5.     QString Nombre;
  6.     QString Sexo;
  7.     int Edad;
  8.     eEstado estado;
  9. };

Y este es el modelo:

mimodelo.h
Código C++:
Ver original
  1. #ifndef MIMODELO_H
  2. #define MIMODELO_H
  3.  
  4. #include <QAbstractTableModel>
  5. #include <QDebug>
  6.  
  7. enum eEstado{feliz,normal,triste};
  8.  
  9. struct Persona
  10. {
  11.     QString Nombre;
  12.     QString Sexo;
  13.     int Edad;
  14.     eEstado estado;
  15. };
  16.  
  17. const int FILAS=4;
  18. const int COLUMNAS=4;
  19.  
  20. class MiModelo : public QAbstractTableModel
  21. {
  22.     Q_OBJECT
  23. public:
  24.     explicit MiModelo(QObject *parent = 0);
  25.     ~MiModelo();
  26.     int rowCount (const QModelIndex & parent = QModelIndex()) const;
  27.     int columnCount (const QModelIndex & parent = QModelIndex()) const;
  28.     QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole);
  29.     QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
  30.     Qt::ItemFlags flags(const QModelIndex &index) const;
  31.     bool setData(const QModelIndex & index, const QVariant& value, int role);
  32.  
  33. private:
  34.  
  35.     Persona persona[FILAS];
  36.     QStringList cabecera;
  37. };
  38.  
  39. #endif // MIMODELO_H

mimodelo.cpp

Código C++:
Ver original
  1. #include "mimodelo.h"
  2.  
  3. MiModelo::MiModelo(QObject *parent) : QAbstractTableModel(parent)
  4. {
  5.     cabecera<<"Nombre"<<"Sexo"<<"Edad"<<"Animo";
  6.     for (int i=0;i<FILAS;i++)
  7.     {
  8.         persona[i].Nombre="Noname";
  9.         persona[i].Sexo="Undefined";
  10.         persona[i].Edad=0;
  11.         persona[i].estado=normal;
  12.     }
  13. }
  14.  
  15. MiModelo::~MiModelo()
  16. {
  17.     for (int i=0;i<FILAS;i++)
  18.     {
  19.         qDebug()<<persona[i].Nombre<<" - "<<persona[i].Sexo<<" - "<<persona[i].Edad;
  20.     }
  21. }
  22.  
  23. int MiModelo::rowCount (const QModelIndex & parent) const
  24. {
  25.     Q_UNUSED (parent);
  26.     return FILAS;
  27. }
  28.  
  29. int MiModelo::columnCount (const QModelIndex & parent) const
  30. {
  31.     Q_UNUSED (parent);
  32.     return COLUMNAS;
  33. }
  34.  
  35. QVariant MiModelo::headerData (int section, Qt::Orientation orientation, int role)
  36. {
  37.     qDebug()<<"Funcion headerdata";
  38.     /*{
  39.         if (orientation == Qt::Horizontal)
  40.         {
  41.             if (role == Qt::DisplayRole)
  42.             {
  43.                 qDebug()<<cabecera.at(section);
  44.                 return cabecera.at(section);
  45.             }
  46.         }
  47.         qDebug()<<cabecera.at(section);
  48.         return QAbstractTableModel::headerData(section, orientation, role);
  49.     }*/
  50. }
  51.  
  52. QVariant MiModelo::data (const QModelIndex & index, int role) const
  53. {
  54.     if (!index.isValid())
  55.     {
  56.         return QVariant();
  57.     }
  58.     if (role == Qt::DisplayRole || role == Qt::EditRole)
  59.     {
  60.         if (index.column()==0)
  61.         {
  62.             return persona[index.row()].Nombre;
  63.         }
  64.         if (index.column()==1)
  65.         {
  66.             return persona[index.row()].Sexo;
  67.         }
  68.         if (index.column()==2)
  69.         {
  70.             return persona[index.row()].Edad;
  71.         }
  72.         if (index.column()==3)
  73.         {
  74.             return persona[index.row()].estado;
  75.         }
  76.     }
  77.     return QVariant();
  78. }
  79.  
  80. Qt::ItemFlags MiModelo::flags(const QModelIndex &index) const
  81. {
  82.     if (!index.isValid())
  83.         return 0;
  84.     return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
  85. }
  86.  
  87. bool MiModelo::setData(const QModelIndex & index, const QVariant& value, int role)
  88. {
  89.     if (index.isValid() && (role == Qt::EditRole || role == Qt::DisplayRole))
  90.     {
  91.         if (index.column()==0)
  92.         {
  93.             persona[index.row()].Nombre=value.toString();
  94.         }
  95.         if (index.column()==1)
  96.         {
  97.             persona[index.row()].Sexo=value.toString();
  98.         }
  99.         if (index.column()==2)
  100.         {
  101.             persona[index.row()].Edad=value.toInt();
  102.         }
  103.         if (index.column()==3)
  104.         {
  105.             switch (value.toInt())
  106.             {
  107.             case 0:
  108.             {
  109.                 persona[index.row()].estado=eEstado::feliz;
  110.                 break;
  111.             }
  112.             case 1:
  113.             {
  114.                 persona[index.row()].estado=eEstado::normal;
  115.                 break;
  116.             }
  117.             case 2:
  118.             {
  119.                 persona[index.row()].estado=eEstado::triste;
  120.                 break;
  121.             }
  122.             default:
  123.                 break;
  124.             }
  125.         }
  126.         emit dataChanged(index, index);
  127.         return true;
  128.     }
  129.     return false;
  130. }

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
  1. #include "midelegado0.h"
  2.  
  3. #include <QLineEdit>
  4. #include <QRegExpValidator>
  5.  
  6. MiDelegado0::MiDelegado0(QWidget *parent) : QStyledItemDelegate(parent){}
  7.  
  8. QWidget * MiDelegado0::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const
  9. {
  10.     Q_UNUSED (index);
  11.     Q_UNUSED (option);
  12.     QLineEdit* miEditor = new QLineEdit(parent);
  13.     QRegExpValidator* validadorTexto = new QRegExpValidator(QRegExp("[A-Za-z ]{1,20}"),miEditor);
  14.     miEditor->setValidator(validadorTexto);
  15.     return miEditor;
  16. }
  17.  
  18. void MiDelegado0::setEditorData ( QWidget * editor, const QModelIndex & index ) const
  19. {
  20.     QLineEdit* miEditor = static_cast<QLineEdit*>(editor);
  21.     miEditor->setText(index.data().toString());
  22. }
  23.  
  24. void MiDelegado0::setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const
  25. {
  26.     QLineEdit* miEditor = static_cast<QLineEdit*>(editor);
  27.     model->setData(index,miEditor->text());
  28. }
  29.  
  30. void MiDelegado0::updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const
  31. {
  32.     Q_UNUSED (index);
  33.     editor->setGeometry(option.rect);
  34. }

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
  1. #include "midelegado1.h"
  2.  
  3. #include <QComboBox>
  4. #include <QStringList>
  5. #include <QPainter>
  6. #include <QColor>
  7.  
  8. MiDelegado1::MiDelegado1(QWidget *parent) : QStyledItemDelegate(parent)
  9. {
  10.     lista<<"Masculino"<<"Femenino";
  11. }
  12.  
  13.  
  14. QWidget * MiDelegado1::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const
  15. {
  16.     Q_UNUSED (index);
  17.     Q_UNUSED (option);
  18.     QComboBox* miCombo = new QComboBox(parent);    
  19.     miCombo->addItems(lista);
  20.     return miCombo;
  21. }
  22.  
  23. void MiDelegado1::setEditorData ( QWidget * editor, const QModelIndex & index ) const
  24. {
  25.     QComboBox* miCombo = static_cast<QComboBox*>(editor);
  26.     miCombo->setCurrentText(index.data().toString());
  27. }
  28.  
  29. void MiDelegado1::setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const
  30. {
  31.     QComboBox* miCombo = static_cast<QComboBox*>(editor);
  32.     model->setData(index,miCombo->currentText());
  33. }
  34.  
  35. void MiDelegado1::updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const
  36. {
  37.     Q_UNUSED (index);
  38.     editor->setGeometry(option.rect);
  39. }
  40.  
  41. void MiDelegado1::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
  42. {
  43.     QColor colorMasculino(Qt::cyan);
  44.     QColor colorFemenino(Qt::magenta);
  45.     painter->save();
  46.     if (index.data().toString()==lista.at(0))
  47.     {
  48.         QPen colorTexto(colorMasculino);
  49.         painter->setPen(colorTexto);
  50.         painter->drawText(option.rect,Qt::AlignCenter,index.data().toString());
  51.  
  52.     }
  53.     else if (index.data().toString()==lista.at(1))
  54.     {
  55.         QPen colorTexto(colorFemenino);
  56.         painter->setPen(colorTexto);
  57.         painter->drawText(option.rect,Qt::AlignCenter,index.data().toString());
  58.     }
  59.     painter->restore();
  60. }

(sigue)
__________________
Mi calculadora en Qt