How can I align the checkboxes in a view?

In order to align the checkboxes in a view, you need to create your own QStyledItemDelegate [doc.qt.nokia.com] and reimplement paint() [doc.qt.nokia.com] to draw the checkboxes with the alignment that you want.

In order to do this, QStyle::alignedRect() [doc.qt.nokia.com] is used to ensure that it is correctly aligned in the center of the rect for the index, then the base implementation is called with the new information so it takes care of rendering the checkbox.

It is also necessary to reimplement QStyledItemDelegate::editorEvent() [qt.nokia.com] to handle the toggling of the checkbox correctly since the checkbox has actually been moved to a different position, and therefore the events for the index need to be handled correctly.

The following example demonstrates how this can be done:

  1. #include <QtGui>
  2.  
  3. class ItemDelegate : public QStyledItemDelegate
  4. {
  5. public:
  6.     ItemDelegate(QObject *parent = 0)
  7.         : QStyledItemDelegate(parent)
  8.     {
  9.     }
  10.  
  11.     void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
  12.     {
  13.         QStyleOptionViewItemV4 viewItemOption(option);
  14.  
  15.         if (index.column() == 0) {
  16.             const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
  17.             QRect newRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
  18.                                                 QSize(option.decorationSize.width() + 5,option.decorationSize.height()),
  19.                                                 QRect(option.rect.x() + textMargin, option.rect.y(),
  20.                                                       option.rect.width() - (2 * textMargin), option.rect.height()));
  21.             viewItemOption.rect = newRect;
  22.         }
  23.         QStyledItemDelegate::paint(painter, viewItemOption, index);
  24.     }
  25.  
  26.     virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
  27.                              const QModelIndex &index)
  28.     {
  29.         Q_ASSERT(event);
  30.         Q_ASSERT(model);
  31.  
  32.         // make sure that the item is checkable
  33.         Qt::ItemFlags flags = model->flags(index);
  34.         if (!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled))
  35.             return false;
  36.         // make sure that we have a check state
  37.         QVariant value = index.data(Qt::CheckStateRole);
  38.         if (!value.isValid())
  39.             return false;
  40.         // make sure that we have the right event type
  41.         if (event->type() == QEvent::MouseButtonRelease) {
  42.             const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
  43.             QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
  44.                                                   option.decorationSize,
  45.                                                   QRect(option.rect.x() + (2 * textMargin), option.rect.y(),
  46.                                                         option.rect.width() - (2 * textMargin),
  47.                                                         option.rect.height()));
  48.             if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos()))
  49.                 return false;
  50.         } else if (event->type() == QEvent::KeyPress) {
  51.             if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space&& static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
  52.                 return false;
  53.         } else {
  54.             return false;
  55.         }
  56.         Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
  57.                                 ? Qt::Unchecked : Qt::Checked);
  58.         return model->setData(index, state, Qt::CheckStateRole);
  59.     }
  60. };
  61.  
  62. static int ROWS = 3; static int COLS = 1;
  63.  
  64. class Table : public QTableWidget
  65. {
  66.     Q_OBJECT
  67. public:
  68.     Table(QWidget *parent = 0)
  69.         : QTableWidget(ROWS, COLS, parent)
  70.     {
  71.         setItemDelegate(new ItemDelegate(this));
  72.         QTableWidgetItem *item = 0;
  73.         for (int i=0; i<rowCount(); ++i) {
  74.             for (int j=0; j<columnCount(); ++j) {
  75.                 setItem(i, j, item = new QTableWidgetItem);
  76.                 item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);
  77.                 item->setCheckState((i+j) % 2 == 0 ? Qt::Checked : Qt::Unchecked);
  78.             }
  79.         }
  80.     }
  81. };
  82.  
  83. #include "main.moc"
  84.  
  85. int main(int argc, char **argv)
  86. {
  87.     QApplication a(argc, argv);
  88.     Table w;
  89.     w.show();
  90.     return a.exec();
  91. }
  92.  

No comments

Write a comment

Sorry, you must be logged in to post a comment.