Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] ¿Se puede crear una interfaz heredando de otra clase?

Estas en el tema de ¿Se puede crear una interfaz heredando de otra clase? en el foro de C/C++ en Foros del Web. Bueno, me explico mejor. Me he dado cuenta de que tengo dos tablas en mi aplicación que son muy parecidas. Apenas cambian en el número ...
  #1 (permalink)  
Antiguo 23/01/2017, 15:14
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
¿Se puede crear una interfaz heredando de otra clase?

Bueno, me explico mejor.

Me he dado cuenta de que tengo dos tablas en mi aplicación que son muy parecidas. Apenas cambian en el número de columnas y obviamente en el contenido. Responden igual a los eventos de teclado aunque no de ratón.

Así que pienso que lo más correcto sería crear una clase base (entiendo que abstracta) de la cual hereden mis dos tablas, pero no sé si se puede ya que habrían de heredar de QTableView que a su vez es clase heredada de una clase abstracta.

¿Eso sería posible?
Gracias!
__________________
Mi calculadora en Qt
  #2 (permalink)  
Antiguo 27/01/2017, 05:34
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
Respuesta: ¿Se puede crear una interfaz heredando de otra clase?

Bueno, pues ya he probado y esta es mi solución.
Parto de la base de que tengo dos tablas, que comparten el filtro de eventos y algunos delegados. Además estas tablas tienen que poder tener alguna columna bloqueada a voluntad del usuario. Si las columnas están bloqueadas, al pulsar tabulador o cursores debo saltarme esa columna.

Esta ha sido mi solución (si alguien está interesado pongo el código completo)

Código C++:
Ver original
  1. class TablaBase : public QTableView
  2. {
  3.     Q_OBJECT
  4.  
  5. public:
  6.     TablaBase(int nColumnas, QWidget *parent=nullptr);
  7.     bool columnaBloqueada(int columna);
  8.     virtual void MostrarMenu(QPoint pos)=0;
  9.     ~TablaBase();
  10.  
  11.     int limiteIzquierdo;
  12.     int limiteDerecho;
  13.  
  14. private slots:
  15.     void Bloquear(int columna);
  16.  
  17. public slots:
  18.     void customMenuRequested(QPoint pos);
  19.  
  20. protected:
  21.     QHeaderView* cabecera;
  22.     QHeaderView* alturaFilas;
  23.     DelegadoEditorMediciones* dlgEM;
  24.     DelegadoColumnasBloqueadas* dlgCB;    
  25.     bool* celdaBloqueada;
  26.     Filter* filtro;
  27. };
  28.  
  29. class TablaPrincipal : public TablaBase
  30. {
  31. public:
  32.     explicit TablaPrincipal(int nColumnas, QWidget *parent=nullptr);
  33.     void MostrarMenu(QPoint pos);
  34.  
  35. };
  36.  
  37. class TablaMedicion : public TablaBase
  38. {
  39. public:
  40.     explicit TablaMedicion(int nColumnas, QWidget *parent=nullptr);
  41.     void MostrarMenu(QPoint pos);
  42.  
  43. };

y luego las implementaciones:
Código C++:
Ver original
  1. TablaBase::TablaBase(int nColumnas, QWidget *parent): QTableView(parent)
  2. {
  3.     celdaBloqueada =  new bool[nColumnas];
  4.     for (int i=0;i<nColumnas;i++)
  5.     {
  6.         celdaBloqueada[i]=false;
  7.     }
  8.     cabecera = this->horizontalHeader();    
  9.     dlgCB = new DelegadoColumnasBloqueadas;
  10.     dlgEM = new DelegadoEditorMediciones;
  11.     filtro = new Filter;
  12.     installEventFilter(filtro);
  13.     cabecera->setContextMenuPolicy(Qt::CustomContextMenu);
  14.     QObject::connect(cabecera, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
  15. }
  16.  
  17. TablaBase::~TablaBase()
  18. {
  19.  
  20. }
  21.  
  22. bool TablaBase::columnaBloqueada(int columna)
  23. {
  24.     return celdaBloqueada[columna];
  25. }
  26.  
  27. void TablaBase::Bloquear(int columna)
  28. {
  29.     if (columna>=limiteIzquierdo && columna<=limiteDerecho)
  30.     {
  31.         celdaBloqueada[columna]=!celdaBloqueada[columna];
  32.         if (columnaBloqueada(columna))
  33.         {
  34.             setItemDelegateForColumn(columna,dlgCB);
  35.         }
  36.         else
  37.         {
  38.             setItemDelegateForColumn(columna,dlgEM);
  39.         }
  40.         clearSelection();
  41.     }
  42. }
  43.  
  44. void TablaBase::customMenuRequested(QPoint pos)
  45. {
  46.     MostrarMenu(pos);
  47. }
  48.  
  49. TablaPrincipal::TablaPrincipal(int nColumnas, QWidget *parent): TablaBase(nColumnas, parent)
  50. {
  51.     limiteIzquierdo=tipoColumna::NATURALEZA;
  52.     limiteDerecho=tipoColumna::PRCERT;
  53.  
  54.     celdaBloqueada[tipoColumna::CODIGO]=true;
  55.     celdaBloqueada[tipoColumna::PORCERTPRES]=true;
  56.     celdaBloqueada[tipoColumna::IMPPRES]=true;
  57.     celdaBloqueada[tipoColumna::IMPCERT]=true;
  58.     setItemDelegateForColumn(tipoColumna::CODIGO,dlgCB);
  59.     setItemDelegateForColumn(tipoColumna::PORCERTPRES,dlgCB);
  60.     setItemDelegateForColumn(tipoColumna::IMPPRES,dlgCB);
  61.     setItemDelegateForColumn(tipoColumna::IMPCERT,dlgCB);
  62. }
  63.  
  64. void TablaPrincipal::MostrarMenu(QPoint pos)
  65. {
  66.     int column=this->horizontalHeader()->logicalIndexAt(pos);
  67.     qDebug()<<"Columna: "<<column;
  68.  
  69.     QMenu *menu=new QMenu(this);
  70.     menu->addAction(new QAction("Bloquear columna", this));
  71.     menu->popup(this->horizontalHeader()->viewport()->mapToGlobal(pos));
  72.     //QObject::connect(menu->actions().at(0),SIGNAL(triggered(bool)),this,SLOT(Bloquear(int)));
  73. }
  74.  
  75. TablaMedicion::TablaMedicion(int nColumnas, QWidget *parent): TablaBase(nColumnas, parent)
  76. {
  77.     limiteIzquierdo=tipoColumna::COMENTARIO;
  78.     limiteDerecho=tipoColumna::FORMULA;
  79.  
  80.     celdaBloqueada[tipoColumna::FASE]=true;
  81.     celdaBloqueada[tipoColumna::PARCIAL]=true;
  82.     celdaBloqueada[tipoColumna::SUBTOTAL]=true;
  83.     celdaBloqueada[tipoColumna::ID]=true;
  84.     setItemDelegateForColumn(tipoColumna::FASE,dlgCB);
  85.     setItemDelegateForColumn(tipoColumna::PARCIAL,dlgCB);
  86.     setItemDelegateForColumn(tipoColumna::SUBTOTAL,dlgCB);
  87.     setItemDelegateForColumn(tipoColumna::ID,dlgCB);
  88.  
  89.     QObject::connect(cabecera, SIGNAL(sectionClicked(int)), this,SLOT(Bloquear(int)));
  90.  
  91. }
  92.  
  93. void TablaMedicion::MostrarMenu(QPoint pos)
  94. {
  95.     int column=this->horizontalHeader()->logicalIndexAt(pos);
  96.     qDebug()<<"Columna: "<<column;
  97.  
  98.     QMenu *menu=new QMenu(this);
  99.     menu->addAction(new QAction("Hacer algo", this));
  100.     menu->popup(this->horizontalHeader()->viewport()->mapToGlobal(pos));
  101. }
__________________
Mi calculadora en Qt
  #3 (permalink)  
Antiguo 27/01/2017, 05:39
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
Respuesta: ¿Se puede crear una interfaz heredando de otra clase?

Lo que no me gusta de esta implementación es que tengo que construir la tabla con el número de columnas como parámetro. No es mucho problema porque el dato lo saco del modelo, pero no termina de estar todo bien.

Por otro lado, necesito que la forma de bloquear/desbloquear columnas sea diferente en cada tabla. El la TablaMedicion lo consigo haciendo click sobre la cabecera, pero en la TablaPrincipal necesitaría que fuera mediante un menú contextual.

Este menú lo tengo hecho como se ve en el código, pero por lo que veo no tengo ninguna señal de QAction que me envíe un parámetro int que necesitaría para saber sobre qué columna estoy situado y por tanto voy a bloquear/desbloquear.
__________________
Mi calculadora en Qt
  #4 (permalink)  
Antiguo 27/01/2017, 06:11
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
Respuesta: ¿Se puede crear una interfaz heredando de otra clase?

Bueno, definitivamente marco el tema como solucionado.
El problema con QAction se resuelve con un QSignalMapper

Aquí un ejemplo de uso:
http://www.qtcentre.org/threads/7819...t-to-send-int?

Y aplicado a mi menú contextual:
Código C++:
Ver original
  1. void TablaPrincipal::MostrarMenu(QPoint pos)
  2. {
  3.     int column=this->horizontalHeader()->logicalIndexAt(pos);
  4.     qDebug()<<"Columna: "<<column;
  5.  
  6.     QMenu *menu=new QMenu(this);
  7.     QAction *AccionBloquearColumna = new QAction("Bloquear columna", this);
  8.     menu->addAction(AccionBloquearColumna);
  9.     mapper->setMapping(AccionBloquearColumna,column);
  10.     QObject::connect(AccionBloquearColumna, SIGNAL(triggered()), mapper, SLOT(map()));
  11.     QObject::connect(mapper, SIGNAL(mapped(int)), this, SLOT(Bloquear(int)));
  12.  
  13.     menu->popup(this->horizontalHeader()->viewport()->mapToGlobal(pos));
  14.  
  15. }

Bueno, pues marco el tema como solucionado
__________________
Mi calculadora en Qt

Etiquetas: interfaz, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 00:00.