Мы уже помещали произвольные виджеты в QListWidget. В этот раз разберемся, как добавлять виджеты в Qt-Представления на примере QTableWidget
. Сразу замечу, что описанный подход одинаково хорошо работает для любой реализации QAbstractItemView
.
Разместим в ячейке таблицы кнопку QPushButton
. В результате получится нечто подобное:
На подготовительном этапе воспользуемся QtDesigner. Создадим простой виджет, на который добавим QTableWidget
. Заполним его произвольными данными:
Обратите внимание, что мы зарезервировали пустой столбец "Действие". В его ячейки мы и добавим кнопки.
Для нумерации столбцов определим перечисление:
enum {
COLUMN_LAST_NAME,
COLUMN_FIRST_NAME,
COLUMN_MIDDLE_NAME,
COLUMN_ACTION
};
По умолчанию виджет, добавленный в ячейку Представления, занимает всю площадь этой ячейки. Для кнопки это нежелательно, поэтому обернем ее во вспомогательный виджет:
QWidget* ViewButtonDemo::createButtonWidget() const {
QWidget* wgt = new QWidget;
QBoxLayout* l = new QHBoxLayout;
QPushButton* btn = new QPushButton( "Click me!" );
connect( btn, SIGNAL( clicked( bool ) ), SLOT( onBtnClicked() ) );
l->setMargin( 0 );
l->addWidget( btn );
l->addStretch();
wgt->setLayout( l );
return wgt;
}
Кнопку соединяем со слотом onBtnClicked()
:
void ViewButtonDemo::onBtnClicked() {
if( QPushButton* btn = qobject_cast< QPushButton* >( sender() ) ) {
QModelIndex index = ui->tableWidget->indexAt( btn->parentWidget()->pos() );
qDebug() << index.row() << "x" << index.column();
QStringList name;
for( int i = COLUMN_LAST_NAME; i <= COLUMN_MIDDLE_NAME; ++i ) {
name << ui->tableWidget->model()->data(
ui->tableWidget->model()->index( index.row(), i )
).toString();
}
QMessageBox::information( this, "The button was clicked", name.join( " " ) );
}
}
Имея указатель на кнопку-отправителя в onBtnClicked()
, мы находим табличный Индекс. Он содержит информацию о номере строки и столбца ячейки, в которой расположена кнопка. По номеру строки запрашиваем данные модели (ФИО), которые затем отображаем в диалоговом окне QMessageBox
.
Осталось лишь добавить кнопки в заготовленные для этого ячейки таблицы с помощью setIndexWidget()
:
ViewButtonDemo::ViewButtonDemo( QWidget* parent ) :
QWidget( parent ),
ui( new Ui::ViewButtonDemo ) {
ui->setupUi( this );
for( int i = 0; i < ui->tableWidget->rowCount(); ++i ) {
ui->tableWidget->setIndexWidget(
ui->tableWidget->model()->index( i, COLUMN_ACTION ),
createButtonWidget()
);
}
}
Заголовочный файл viewbuttondemo.h
:
#ifndef VIEWBUTTONDEMO_H
#define VIEWBUTTONDEMO_H
#include <QWidget>
namespace Ui {
class ViewButtonDemo;
}
class ViewButtonDemo : public QWidget {
Q_OBJECT
public:
explicit ViewButtonDemo( QWidget* parent = 0 );
~ViewButtonDemo();
private slots:
void onBtnClicked();
private:
QWidget* createButtonWidget() const;
private:
Ui::ViewButtonDemo* ui;
};
#endif // VIEWBUTTONDEMO_H
Реализация в viewbuttondemo.cpp
:
#include "viewbuttondemo.h"
#include "ui_viewbuttondemo.h"
#include <QPushButton>
#include <QMessageBox>
#include <QDebug>
enum {
COLUMN_LAST_NAME,
COLUMN_FIRST_NAME,
COLUMN_MIDDLE_NAME,
COLUMN_ACTION
};
ViewButtonDemo::ViewButtonDemo( QWidget* parent ) :
QWidget( parent ),
ui( new Ui::ViewButtonDemo ) {
ui->setupUi( this );
for( int i = 0; i < ui->tableWidget->rowCount(); ++i ) {
ui->tableWidget->setIndexWidget(
ui->tableWidget->model()->index( i, COLUMN_ACTION ),
createButtonWidget()
);
}
}
ViewButtonDemo::~ViewButtonDemo() {
delete ui;
}
void ViewButtonDemo::onBtnClicked() {
if( QPushButton* btn = qobject_cast< QPushButton* >( sender() ) ) {
QModelIndex index = ui->tableWidget->indexAt( btn->parentWidget()->pos() );
qDebug() << index.row() << "x" << index.column();
QStringList name;
for( int i = COLUMN_LAST_NAME; i <= COLUMN_MIDDLE_NAME; ++i ) {
name << ui->tableWidget->model()->data(
ui->tableWidget->model()->index( index.row(), i )
).toString();
}
QMessageBox::information( this, "The button was clicked", name.join( " " ) );
}
}
QWidget* ViewButtonDemo::createButtonWidget() const {
QWidget* wgt = new QWidget;
QBoxLayout* l = new QHBoxLayout;
QPushButton* btn = new QPushButton( "Click me!" );
connect( btn, SIGNAL( clicked( bool ) ), SLOT( onBtnClicked() ) );
l->setMargin( 0 );
l->addWidget( btn );
l->addStretch();
wgt->setLayout( l );
return wgt;
}
Скачать пример добавления виджетов в ячейку таблицы QTableWidget