浏览代码

ctkMatrixWidget doesn't derive from QTableWidget anymore

When using the designer, the user had too much control over ctkMatrixWidget
and most of the QTableWidget properties were not handled by ctkMatrixWidget
. For this reason, we hide all the features of QTableWidget and we try to
choose the best properties for it.
Julien Finet 14 年之前
父节点
当前提交
ff85fad316

+ 11 - 9
Libs/Visualization/VTK/Widgets/ctkVTKAbstractMatrixWidget.cpp

@@ -1,7 +1,7 @@
 /*=========================================================================
 
   Library:   CTK
- 
+
   Copyright (c) Kitware Inc.
 
   Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +15,7 @@
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
- 
+
 =========================================================================*/
 
 // Qt includes
@@ -30,9 +30,10 @@
 #include <vtkMatrix4x4.h>
 
 // --------------------------------------------------------------------------
-ctkVTKAbstractMatrixWidgetPrivate::ctkVTKAbstractMatrixWidgetPrivate(ctkVTKAbstractMatrixWidget& object)
-  :QObject(0) // will be reparented in init()
-  ,q_ptr(&object)
+ctkVTKAbstractMatrixWidgetPrivate
+::ctkVTKAbstractMatrixWidgetPrivate(ctkVTKAbstractMatrixWidget& object)
+  : QObject(0) // will be reparented in init()
+  , q_ptr(&object)
 {
 }
 
@@ -52,7 +53,7 @@ void ctkVTKAbstractMatrixWidgetPrivate::init()
 // --------------------------------------------------------------------------
 void ctkVTKAbstractMatrixWidgetPrivate::setMatrix(vtkMatrix4x4* matrixVariable)
 {
-  qvtkReconnect(this->Matrix.GetPointer(), matrixVariable, 
+  qvtkReconnect(this->Matrix.GetPointer(), matrixVariable,
                 vtkCommand::ModifiedEvent, this, SLOT(updateMatrix()));
 
   this->Matrix = matrixVariable;
@@ -74,7 +75,7 @@ void ctkVTKAbstractMatrixWidgetPrivate::updateMatrix()
 
   if (this->Matrix == 0)
     {
-    q->reset();
+    q->identity();
     return;
     }
   QVector<double> vector;
@@ -83,14 +84,15 @@ void ctkVTKAbstractMatrixWidgetPrivate::updateMatrix()
     {
     for (int j=0; j < 4; j++)
       {
-      vector.append(this->Matrix->GetElement(i,j)); 
+      vector.append(this->Matrix->GetElement(i,j));
       }
     }
   q->setVector( vector );
 }
 
 // --------------------------------------------------------------------------
-ctkVTKAbstractMatrixWidget::ctkVTKAbstractMatrixWidget(QWidget* parentVariable) : Superclass(parentVariable)
+ctkVTKAbstractMatrixWidget::ctkVTKAbstractMatrixWidget(QWidget* parentVariable)
+  : Superclass(parentVariable)
   , d_ptr(new ctkVTKAbstractMatrixWidgetPrivate(*this))
 {
   Q_D(ctkVTKAbstractMatrixWidget);

+ 9 - 6
Libs/Visualization/VTK/Widgets/ctkVTKAbstractMatrixWidget.h

@@ -1,7 +1,7 @@
 /*=========================================================================
 
   Library:   CTK
- 
+
   Copyright (c) Kitware Inc.
 
   Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +15,7 @@
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
- 
+
 =========================================================================*/
 
 #ifndef __ctkVTKAbstractMatrixWidget_h
@@ -23,7 +23,6 @@
 
 /// CTK includes
 #include <ctkMatrixWidget.h>
-#include <ctkPimpl.h>
 #include <ctkVTKObject.h>
 
 #include "CTKVisualizationVTKWidgetsExport.h"
@@ -31,12 +30,16 @@
 class vtkMatrix4x4;
 class ctkVTKAbstractMatrixWidgetPrivate;
 
-class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKAbstractMatrixWidget : public ctkMatrixWidget
+/// This base class is primarily used by ctkVTKMatrixWidget but can be the base
+/// of other classes (ctkVTKTransformWidget?) that don't want to expose
+/// setMatrix() publicly.
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKAbstractMatrixWidget
+  : public ctkMatrixWidget
 {
 public:
   /// Self/Superclass typedef
   typedef ctkMatrixWidget   Superclass;
-  
+
   /// Constructors
   ctkVTKAbstractMatrixWidget(QWidget* parent);
   virtual ~ctkVTKAbstractMatrixWidget();
@@ -51,6 +54,6 @@ protected:
 private:
   Q_DECLARE_PRIVATE(ctkVTKAbstractMatrixWidget);
   Q_DISABLE_COPY(ctkVTKAbstractMatrixWidget);
-}; 
+};
 
 #endif

+ 6 - 9
Libs/Visualization/VTK/Widgets/ctkVTKMatrixWidget.h

@@ -1,7 +1,7 @@
 /*=========================================================================
 
   Library:   CTK
- 
+
   Copyright (c) Kitware Inc.
 
   Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,33 +15,30 @@
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
- 
+
 =========================================================================*/
 
 #ifndef __ctkVTKMatrixWidget_h
 #define __ctkVTKMatrixWidget_h
 
 // CTK includes
-#include <ctkPimpl.h>
 #include "ctkVTKAbstractMatrixWidget.h"
-
 #include "CTKVisualizationVTKWidgetsExport.h"
- 
-class vtkMatrix4x4;
 
-class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKMatrixWidget : public ctkVTKAbstractMatrixWidget
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKMatrixWidget
+  : public ctkVTKAbstractMatrixWidget
 {
   Q_OBJECT
 public:
   /// Self/Superclass typedef
   typedef ctkVTKMatrixWidget  Self;
   typedef ctkVTKAbstractMatrixWidget   Superclass;
-  
+
   /// Constructors
   ctkVTKMatrixWidget(QWidget* parent);
 
 public slots:
   void setMatrix(vtkMatrix4x4* matrix);
-}; 
+};
 
 #endif

+ 2 - 1
Libs/Widgets/Testing/Cpp/ctkMatrixWidgetTest1.cpp

@@ -33,8 +33,9 @@ int ctkMatrixWidgetTest1(int argc, char * argv [] )
 {
   QApplication app(argc, argv);
 
-  ctkMatrixWidget matrixWidget;
+  ctkMatrixWidget matrixWidget(5,6);
   matrixWidget.show();
+  matrixWidget.setRowCount(8);
 
   if (argc < 2 || QString(argv[1]) != "-I" )
     {

+ 152 - 98
Libs/Widgets/ctkMatrixWidget.cpp

@@ -22,15 +22,17 @@
 #include "ctkMatrixWidget.h"
 
 // Qt includes
-#include <Qt>
-#include <QHeaderView>
-#include <QVariant>
-#include <QTableWidgetItem>
-#include <QResizeEvent>
+#include <QDebug>
 #include <QDoubleSpinBox>
+#include <QHBoxLayout>
+#include <QHeaderView>
 #include <QItemEditorFactory>
+#include <QResizeEvent>
 #include <QStyledItemDelegate>
-#include <QDebug>
+#include <QTableWidget>
+#include <QTableWidgetItem>
+#include <QVariant>
+#include <Qt>
 
 //-----------------------------------------------------------------------------
 // Custom item editors
@@ -48,7 +50,7 @@ namespace
       // ctkMatrixWidget because this object is
       // created by the QItemEditorFactory
       ctkMatrixWidget* matrixWidget =
-        qobject_cast<ctkMatrixWidget*>(parentWidget->parentWidget());
+        qobject_cast<ctkMatrixWidget*>(parentWidget->parentWidget()->parent());
       Q_ASSERT(matrixWidget);
       this->setMinimum(matrixWidget->minimum());
       this->setMaximum(matrixWidget->maximum());
@@ -65,13 +67,16 @@ class ctkMatrixWidgetPrivate
 protected:
   ctkMatrixWidget* const q_ptr;
 public:
-  ctkMatrixWidgetPrivate(ctkMatrixWidget& object);
+  ctkMatrixWidgetPrivate(ctkMatrixWidget& object, int rows = 4, int columns = 4);
 
   void init();
-  void validateElements();
+  void validateItems();
+  void updateGeometries();
+  void setIdentityItem(int i, int j);
+
+  QTableWidget* Table;
 
   // Parameters for the spinbox used to change the value of matrix elements
-  /// TODO: use a QDoubleSpinBox directly ?
   double Minimum;
   double Maximum;
   int    Decimals;
@@ -79,9 +84,10 @@ public:
 };
 
 //-----------------------------------------------------------------------------
-ctkMatrixWidgetPrivate::ctkMatrixWidgetPrivate(ctkMatrixWidget& object)
+ctkMatrixWidgetPrivate::ctkMatrixWidgetPrivate(ctkMatrixWidget& object, int rows, int columns)
   :q_ptr(&object)
 {
+  this->Table = new QTableWidget(rows, columns);
 }
 
 //-----------------------------------------------------------------------------
@@ -89,6 +95,12 @@ void ctkMatrixWidgetPrivate::init()
 {
   Q_Q(ctkMatrixWidget);
 
+  this->Table->setParent(q);
+  QHBoxLayout* layout = new QHBoxLayout(q);
+  layout->addWidget(this->Table);
+  layout->setContentsMargins(0,0,0,0);
+  q->setLayout(layout);
+
   // Set parameters for the spinbox
   this->Minimum = -100;
   this->Maximum = 100;
@@ -96,70 +108,118 @@ void ctkMatrixWidgetPrivate::init()
   this->SingleStep = 0.01;
 
   // Don't select the items
-  q->setSelectionMode(QAbstractItemView::NoSelection);
+  this->Table->setSelectionMode(QAbstractItemView::NoSelection);
 
   // Hide headers
-  q->verticalHeader()->hide();
-  q->horizontalHeader()->hide();
+  this->Table->verticalHeader()->hide();
+  this->Table->horizontalHeader()->hide();
 
   // Disable scrollBars
-  q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-  q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+  this->Table->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+  this->Table->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
   // Don't expand for no reason
   q->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
 
   // Disable the frame by default
-  q->setFrameStyle(QFrame::NoFrame);
+  this->Table->setFrameStyle(QFrame::NoFrame);
 
   // Register custom editors
   QItemEditorFactory *editorFactory = new QItemEditorFactory;
   editorFactory->registerEditor(QVariant::Double, new QStandardItemEditorCreator<ctkMatrixDoubleSpinBox>);
 
   QStyledItemDelegate* defaultItemDelegate =
-    qobject_cast<QStyledItemDelegate*>(q->itemDelegate());
+    qobject_cast<QStyledItemDelegate*>(this->Table->itemDelegate());
   Q_ASSERT(defaultItemDelegate);
   defaultItemDelegate->setItemEditorFactory(editorFactory);
 
   // Define prototype item
-  QTableWidgetItem* _item = new QTableWidgetItem();
+  QTableWidgetItem* _item = new QTableWidgetItem;
   _item->setData(Qt::DisplayRole, QVariant(0.0));
   _item->setTextAlignment(Qt::AlignCenter);
 
   // The table takes ownership of the prototype.
-  q->setItemPrototype(_item);
+  this->Table->setItemPrototype(_item);
 
   // Set Read-only
   q->setEditable(true);
 
   // Initialize
-  q->identity();
+  this->validateItems();
+
+  this->updateGeometries();
 }
 
 // --------------------------------------------------------------------------
-void ctkMatrixWidgetPrivate::validateElements()
+void ctkMatrixWidgetPrivate::validateItems()
 {
   Q_Q(ctkMatrixWidget);
-  for (int i=0; i < q->rowCount(); i++)
+  for (int i=0; i < q->rowCount(); ++i)
     {
-    for (int j=0; j < q->columnCount(); j++)
+    for (int j=0; j < q->columnCount(); ++j)
       {
-      double value = q->item(i, j)->data(Qt::DisplayRole).toDouble();
-      if (value < this->Minimum)
+      QTableWidgetItem* item = this->Table->item(i, j);
+      if (!item)
         {
-        q->item(i,j)->setData(Qt::DisplayRole, QVariant(this->Minimum));
+        this->Table->setItem(i, j , this->Table->itemPrototype()->clone());
+        this->setIdentityItem(i, j);
         }
-      if (value > this->Maximum)
+      else
         {
-        q->item(i,j)->setData(Qt::DisplayRole, QVariant(this->Maximum));
+        double value = item->data(Qt::DisplayRole).toDouble();
+        item->setData(Qt::DisplayRole,
+                      qBound(this->Minimum, value, this->Maximum));
         }
       }
     }
 }
 
 // --------------------------------------------------------------------------
+void ctkMatrixWidgetPrivate::setIdentityItem(int i, int j)
+{
+  Q_Q(ctkMatrixWidget);
+  // the item must exist first
+  Q_ASSERT(this->Table->item(i, j));
+  // identity matrix has 1 on the diagonal, 0 everywhere else
+  double value = (i == j ? 1. : 0.);
+  // set the value to the table
+  q->setValue(i, j, value);
+}
+
+// --------------------------------------------------------------------------
+void ctkMatrixWidgetPrivate::updateGeometries()
+{
+  Q_Q(ctkMatrixWidget);
+  QSize viewportSize = q->size();
+  // columns
+  const int ccount = q->columnCount();
+  int colWidth = viewportSize.width() / ccount;
+  int lastColWidth = colWidth
+    + (viewportSize.width() - colWidth * ccount);
+  for (int j=0; j < ccount; j++)
+    {
+    bool lastColumn = (j==(ccount-1));
+    int newWidth = lastColumn ? lastColWidth : colWidth;
+    this->Table->setColumnWidth(j, newWidth);
+    Q_ASSERT(this->Table->columnWidth(j) == newWidth);
+    }
+  // rows
+  const int rcount = q->rowCount();
+  int rowHeight = viewportSize.height() / rcount;
+  int lastRowHeight = rowHeight + (viewportSize.height() - rowHeight * rcount);
+  for (int i=0; i < rcount; i++)
+    {
+    bool lastRow = (i==(rcount-1));
+    int newHeight = lastRow ? lastRowHeight : rowHeight;
+    this->Table->setRowHeight(i, newHeight);
+    Q_ASSERT(this->Table->rowHeight(i) == newHeight);
+    }
+  this->Table->updateGeometry();
+}
+
+// --------------------------------------------------------------------------
 ctkMatrixWidget::ctkMatrixWidget(QWidget* _parent)
-  :Superclass(4, 4, _parent)
+  :Superclass(_parent)
   ,d_ptr(new ctkMatrixWidgetPrivate(*this))
 {
   Q_D(ctkMatrixWidget);
@@ -168,17 +228,17 @@ ctkMatrixWidget::ctkMatrixWidget(QWidget* _parent)
 
 // --------------------------------------------------------------------------
 ctkMatrixWidget::ctkMatrixWidget(int rows, int columns, QWidget* _parent)
-  :Superclass(rows, columns, _parent)
-  ,d_ptr(new ctkMatrixWidgetPrivate(*this))
+  : QWidget(_parent)
+  , d_ptr(new ctkMatrixWidgetPrivate(*this, rows, columns))
 {
   Q_D(ctkMatrixWidget);
   d->init();
 }
 
 // --------------------------------------------------------------------------
-ctkMatrixWidget::ctkMatrixWidget(int rows, int columns, ctkMatrixWidgetPrivate& pvt,
+ctkMatrixWidget::ctkMatrixWidget(ctkMatrixWidgetPrivate& pvt,
                                  QWidget* _parent)
-  :Superclass(rows, columns, _parent)
+  : Superclass(_parent)
   ,d_ptr(&pvt)
 {
   Q_D(ctkMatrixWidget);
@@ -191,22 +251,50 @@ ctkMatrixWidget::~ctkMatrixWidget()
 }
 
 // --------------------------------------------------------------------------
+int ctkMatrixWidget::columnCount()const
+{
+  Q_D(const ctkMatrixWidget);
+  return d->Table->columnCount();
+}
+
+// --------------------------------------------------------------------------
+void ctkMatrixWidget::setColumnCount(int rc)
+{
+  Q_D(ctkMatrixWidget);
+  d->Table->setColumnCount(rc);
+  d->validateItems();
+  d->updateGeometries();
+}
+
+// --------------------------------------------------------------------------
+int ctkMatrixWidget::rowCount()const
+{
+  Q_D(const ctkMatrixWidget);
+  return d->Table->rowCount();
+}
+
+// --------------------------------------------------------------------------
+void ctkMatrixWidget::setRowCount(int rc)
+{
+  Q_D(ctkMatrixWidget);
+  d->Table->setRowCount(rc);
+  d->validateItems();
+  d->updateGeometries();
+}
+
+// --------------------------------------------------------------------------
 bool ctkMatrixWidget::editable()const
 {
-  return this->editTriggers();
+  Q_D(const ctkMatrixWidget);
+  return d->Table->editTriggers();
 }
 
 // --------------------------------------------------------------------------
 void ctkMatrixWidget::setEditable(bool newEditable)
 {
-  if (newEditable)
-    {
-    this->setEditTriggers(ctkMatrixWidget::DoubleClicked);
-    }
-  else
-    {
-    this->setEditTriggers(ctkMatrixWidget::NoEditTriggers);
-    }
+  Q_D(ctkMatrixWidget);
+  d->Table->setEditTriggers(
+    newEditable ? QTableWidget::DoubleClicked : QTableWidget::NoEditTriggers);
 }
 
 // --------------------------------------------------------------------------
@@ -222,7 +310,7 @@ void ctkMatrixWidget::setMinimum(double newMinimum)
 {
   Q_D(ctkMatrixWidget);
   d->Minimum = newMinimum;
-  d->validateElements();
+  d->validateItems();
 }
 
 // --------------------------------------------------------------------------
@@ -230,7 +318,7 @@ void ctkMatrixWidget::setMaximum(double newMaximum)
 {
   Q_D(ctkMatrixWidget);
   d->Maximum = newMaximum;
-  d->validateElements();
+  d->validateItems();
 }
 
 // --------------------------------------------------------------------------
@@ -239,21 +327,22 @@ void ctkMatrixWidget::setRange(double newMinimum, double newMaximum)
   Q_D(ctkMatrixWidget);
   d->Minimum = newMinimum;
   d->Maximum = newMaximum;
-  d->validateElements();
+  d->validateItems();
 }
 
 // --------------------------------------------------------------------------
 QSize ctkMatrixWidget::minimumSizeHint() const
 {
-  int maxWidth = this->sizeHintForColumn(0);
+  Q_D(const ctkMatrixWidget);
+  int maxWidth = d->Table->horizontalHeader()->sectionSizeHint(0);
   for (int j = 1; j < this->columnCount(); ++j)
     {
-    maxWidth = qMax(maxWidth, this->sizeHintForColumn(j));
+    maxWidth = qMax(maxWidth, d->Table->horizontalHeader()->sectionSizeHint(j));
     }
-  int maxHeight = this->sizeHintForRow(0);
+  int maxHeight = d->Table->verticalHeader()->sectionSizeHint(0);
   for (int i = 1; i < this->rowCount(); ++i)
     {
-    maxHeight = qMax(maxHeight, this->sizeHintForRow(i));
+    maxHeight = qMax(maxHeight, d->Table->verticalHeader()->sectionSizeHint(i));
     }
   return QSize(maxWidth*this->columnCount(), maxHeight*this->rowCount());
 }
@@ -265,34 +354,11 @@ QSize ctkMatrixWidget::sizeHint() const
 }
 
 // --------------------------------------------------------------------------
-void ctkMatrixWidget::updateGeometries()
+void ctkMatrixWidget::resizeEvent(QResizeEvent* event)
 {
-  QSize viewportSize = this->viewport()->size();
-  // columns
-  const int ccount = this->columnCount();
-  int colWidth = viewportSize.width() / ccount;
-  int lastColWidth = colWidth
-    + (viewportSize.width() - colWidth * ccount);
-  for (int j=0; j < ccount; j++)
-    {
-    bool lastColumn = (j==(ccount-1));
-    int newWidth = lastColumn ? lastColWidth : colWidth;
-    this->setColumnWidth(j, newWidth);
-    Q_ASSERT(this->columnWidth(j) == newWidth);
-    }
-  // rows
-  const int rcount = this->rowCount();
-  int rowHeight = viewportSize.height() / rcount;
-  int lastRowHeight = rowHeight + (viewportSize.height() - rowHeight * rcount);
-  for (int i=0; i < rcount; i++)
-    {
-    bool lastRow = (i==(rcount-1));
-    int newHeight = lastRow ? lastRowHeight : rowHeight;
-    this->setRowHeight(i, newHeight);
-    Q_ASSERT(this->rowHeight(i) == newHeight);
-    }
-
-  this->Superclass::updateGeometries();
+  Q_D(ctkMatrixWidget);
+  this->Superclass::resizeEvent(event);
+  d->updateGeometries();
 }
 
 // --------------------------------------------------------------------------
@@ -304,22 +370,7 @@ void ctkMatrixWidget::identity()
     {
     for (int j=0; j < this->columnCount(); j++)
       {
-      this->setItem(i, j, this->itemPrototype()->clone());
-      if (i == j)
-        {
-        if (d->Maximum < 1.0)
-          {
-          this->setValue(i, j, d->Maximum);
-          }
-        else if (d->Minimum > 1.0)
-          {
-          this->setValue(i, j, d->Minimum);
-          }
-        else
-          {
-          this->setValue(i, j, 1.0);
-          }
-        }
+      d->setIdentityItem(i,j);
       }
     }
 }
@@ -327,10 +378,11 @@ void ctkMatrixWidget::identity()
 // --------------------------------------------------------------------------
 double ctkMatrixWidget::value(int i, int j)const
 {
+  Q_D(const ctkMatrixWidget);
   Q_ASSERT( i>=0 && i<this->rowCount() &&
             j>=0 && j<this->columnCount());
 
-  return this->item(i, j)->data(Qt::DisplayRole).toDouble();
+  return d->Table->item(i, j)->data(Qt::DisplayRole).toDouble();
 }
 
 // --------------------------------------------------------------------------
@@ -340,8 +392,8 @@ void ctkMatrixWidget::setValue(int i, int j, double _value)
   Q_ASSERT( i>=0 && i<this->rowCount() &&
             j>=0 && j<this->columnCount());
 
-  _value = qBound(d->Minimum, _value, d->Maximum);
-  this->item(i, j)->setData(Qt::DisplayRole, QVariant(_value));
+  d->Table->item(i, j)->setData(Qt::DisplayRole,
+                                QVariant(qBound(d->Minimum, _value, d->Maximum)));
 }
 
 // --------------------------------------------------------------------------
@@ -352,8 +404,10 @@ void ctkMatrixWidget::setVector(const QVector<double> & vector)
     {
     for (int j=0; j < this->columnCount(); j++)
       {
-      double value = qBound(d->Minimum, vector.at(i * this->columnCount() + j), d->Maximum);
-      this->item(i,j)->setData(Qt::DisplayRole, QVariant(value));
+      double value = qBound(d->Minimum,
+                            vector.at(i * this->columnCount() + j),
+                            d->Maximum);
+      d->Table->item(i,j)->setData(Qt::DisplayRole, QVariant(value));
       }
     }
 }

+ 25 - 16
Libs/Widgets/ctkMatrixWidget.h

@@ -22,7 +22,7 @@
 #define __ctkMatrixWidget_h
 
 /// Qt includes
-#include <QTableWidget>
+#include <QWidget>
 
 /// CTK includes
 #include "ctkPimpl.h"
@@ -35,18 +35,20 @@ class ctkMatrixWidgetPrivate;
 /// \todo Wrap model signals to emit signals when the matrix is changed.
 /// Right now you can connect to the signal:
 /// matrixWidget->model()->dataChanged(...)
-class CTK_WIDGETS_EXPORT ctkMatrixWidget : public QTableWidget
+class CTK_WIDGETS_EXPORT ctkMatrixWidget: public QWidget
 {
   Q_OBJECT
+  Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount)
+  Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount)
   Q_PROPERTY(bool editable READ editable WRITE setEditable)
   Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
-  Q_PROPERTY(double maximum READ maximum WRITE setMaximum)   
+  Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
   Q_PROPERTY(int decimals READ decimals WRITE setDecimals)
   Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
 
 public:
   /// Superclass typedef
-  typedef QTableWidget Superclass;
+  typedef QWidget Superclass;
 
   /// Constructor, builds a 4x4 matrix
   explicit ctkMatrixWidget(QWidget* parent = 0);
@@ -54,6 +56,16 @@ public:
   explicit ctkMatrixWidget(int rows, int columns, QWidget* parent = 0);
   virtual ~ctkMatrixWidget();
 
+  /// Set the number of columns of the matrix
+  /// \sa rowCount, setRowCount
+  int columnCount()const;
+  void setColumnCount(int newColumnCount);
+
+  /// Set the number of rows of the matrix
+  /// \sa columnCount, setColumnCount
+  int rowCount()const;
+  void setRowCount(int newRowCount);
+
   ///
   /// Set / Get values of the matrix
   /// \li i is the row index, \li j is the column index
@@ -70,15 +82,15 @@ public:
   bool editable()const;
   void setEditable(bool newEditable);
 
-  /// 
+  ///
   /// This property holds the minimum value of matrix elements.
   ///
   /// Any matrix elements whose values are less than the new minimum value will be reset to equal
   /// the new minimum value.
   double minimum()const;
   void setMinimum(double newMinimum);
-  
-  /// 
+
+  ///
   /// This property holds the maximum value of matrix elements.
   ///
   /// Any matrix elements whose values are greater than the new maximum value will be reset to equal
@@ -90,7 +102,7 @@ public:
   /// Utility function that sets the min/max at once.
   void setRange(double newMinimum, double newMaximum);
 
-  /// 
+  ///
   /// This property holds the step value of the spinbox.
   ///
   /// When the user uses the arrows to change the value of the spinbox used to adjust the value of
@@ -98,7 +110,7 @@ public:
   double singleStep()const;
   void setSingleStep(double step);
 
-  /// 
+  ///
   /// This property holds the precision of the spinbox, in decimals.
   ///
   /// Dictates how many decimals will be used for displaying and interpreting doubles by the spinbox
@@ -112,20 +124,17 @@ public:
   virtual QSize sizeHint () const;
 
 public slots:
+
   ///
   /// Reset the matrix to identity
   void identity();
 
 protected:
-  ///
-  /// Reimplemented from QTableView
-  /// Share the width/height evenly between columns/rows.
-  virtual void updateGeometries();
-  
+  virtual void resizeEvent(QResizeEvent* event);
+
   ///
   /// protected constructor to derive private implementations
-  ctkMatrixWidget(int rows, int columns,
-                  ctkMatrixWidgetPrivate& pvt, QWidget* parent=0);
+  ctkMatrixWidget(ctkMatrixWidgetPrivate& pvt, QWidget* parent=0);
 private:
   QScopedPointer<ctkMatrixWidgetPrivate> d_ptr;
   Q_DECLARE_PRIVATE(ctkMatrixWidget);