Мы уже помещали произвольные виджеты в QListWidget. В этот раз разберемся, как добавлять виджеты в Qt-Представления на примере QTableWidget. Сразу замечу, что описанный подход одинаково хорошо работает для любой реализации QAbstractItemView.
Разместим в ячейке таблицы кнопку QPushButton.
На подготовительном этапе воспользуемся QtDesigner. Создадим простой виджет, на который добавим QTableWidget. Заполним его произвольными данными.
Обратите внимание, что мы зарезервировали пустой столбец «Действие». В его ячейки мы и добавим кнопки.
Для нумерации столбцов определим перечисление:
1 2 3 4 5 6 |
enum { COLUMN_LAST_NAME, COLUMN_FIRST_NAME, COLUMN_MIDDLE_NAME, COLUMN_ACTION }; |
По умолчанию виджет, добавленный в ячейку Представления, занимает всю площадь этой ячейки. Для кнопки это нежелательно, поэтому обернем ее во вспомогательный виджет:
1 2 3 4 5 6 7 8 9 10 11 12 |
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():
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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():
1 2 3 4 5 6 7 8 9 10 11 12 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#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; } |