пятница, 30 сентября 2011 г.

Вставка QWidget в QTableWidget

Надо бы рассказать о способе вставки QWidget в QTableWidget.
Вообще, я не очень люблю QTableWidget, т.к. больше привык к QTableView и QAbstractItemModel, QStyledItemDelegate. Но в случае если быстро нужна таблица, связанная с одной готовой моделью, то можно воспользоваться QTableWidget. В принципе, QTableWidget порожден от QTableView и умеет всё то, что умеет и QTableView.

Перейдем к делу. Точнее к постановке задачи.
Надо вставить в ячейки QTableWidget виджеты. Пример на картинке.


То есть, виджеты всегда на виду, а не скрываются, как это делается в случае с делегатом.
В первом столбце банальный QLineEdit, во втором - пользовательский виджет для ввода даты.

Как это сделать?
В коде я приведу работу с QTreeWidget, а не с QTableWidget, но разницы особой нет.

Создаем QTreeWidget:
treeWidget_ = new QTreeWidget(this);
treeWidget_->setRootIsDecorated(false);
treeWidget_->setSelectionBehavior(QAbstractItemView::SelectRows);
treeWidget_->setAlternatingRowColors(false);
treeWidget_->header()->setDefaultAlignment(Qt::AlignCenter);
treeWidget_->setEditTriggers(QAbstractItemView::NoEditTriggers);
treeWidget_->setFocusPolicy(Qt::NoFocus);
treeWidget_->header()->setStretchLastSection(false);
Метод для добавления строки виджетов:
void SomeClass::appendRow(const QWidgetList & widgets)
{
  //Создаем Item
  QTreeWidgetItem * treeItem = new QTreeWidgetItem(treeWidget_);
  int col = 0;
  //Добавляем виджеты в строку
  foreach (QWidget * widget, widgets)
  {
     //Создаем новый виджет, на котором разместим исходный виджет
     //Разместим исходный виджет в Layout нового
     QWidget * newWidget = new QWidget(treeWidget_);
     QVBoxLayout * vb = new QVBoxLayout;
     vb->setMargin(3);
     vb->addWidget(widget);
     newWidget->setLayout(vb);
     //Добавляем виджет и увеличиваем счетчик столбцов
     treeWidget_->setItemWidget(treeItem, col++, newWidget);
  }

  treeWidget_->scrollTo(treeWidget_->model()->index(
               treeWidget_->model()->rowCount() - 1, 0));

  treeWidget_->setCurrentItem(treeItem);
}

 

1 коммент.:

  1. можно и делегата заставить рисовать виджет всегда

    ОтветитьУдалить