пятница, 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);
}

7 комментариев:

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

    ОтветитьУдалить
  2. Где можно посмотреть полный пример?

    ОтветитьУдалить
  3. абсолютно бесполезная статья, информация в которой не соответствует названию, и не проверена автором

    ОтветитьУдалить
    Ответы
    1. Статья написана лично мной и все информация достоверна, код рабочий.

      Удалить
    2. Статья - не соответствует названию, и не проверена автором. В QTableWidget НЕТ метода setItemWidet, поэтому невозможно в неё поместить виджет описанным способом.

      Удалить
  4. Заголовок статьи НЕ соответствует содержимому статьи. Раз написано, что пример для QTableWidget, значит и в статье код должен быть представлен для QTableWidget.

    ОтветитьУдалить
  5. автор дурик, название одно - примеры левые, спасибо, наелся

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