Основы работы с QListWidget мы уже рассматривали. Эту заметку можно считать продолжением. Разберемся с добавлением произвольных виджетов в QListWidget.
Для класса главного окна определим следующую функцию:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void MainWidget::makeItem( QListWidget* lstWgt ) { QWidget* wgt = new QWidget; QLayout* l = new QHBoxLayout; l->addWidget( new QLineEdit ); QPushButton* btn = new QPushButton( "Click me" ); connect( btn, SIGNAL( clicked() ), SLOT( onBtnClicked() ) ); l->addWidget( btn ); wgt->setLayout( l ); QListWidgetItem* item = new QListWidgetItem( lstWgt ); item->setSizeHint( wgt->sizeHint() ); lstWgt->setItemWidget( item, wgt ); } |
Входным аргументом makeItem() служит указатель на виджет списка lstWgt. В этот список и будет добавлен тестовый виджет.
Виджет wgt содержит QLineEdit и QPushButton. Эти элементы выбраны совершенно произвольным образом. Вы можете использовать любой другой виджет, который хотите добавить в QListWidget.
Обратите внимание на соединение сигнала кнопки clicked() и слота onBtnClicked(). Реализацию этого слота мы обсудим чуть ниже.
Главная часть сосредоточена в конце функции. Именно там мы создаем QListWidgetItem. А затем связываем этот item с созданным ранее wgt вызовом setItemWidget().
Чтобы размер элемента соответствовал содержимому виджета, мы устанавливаем для него sizeHint, полученный от wgt.
А вот реализация слота onBtnClicked():
1 2 3 4 5 6 7 8 |
void MainWidget::onBtnClicked() { if( QPushButton* btn = qobject_cast< QPushButton* >( sender() ) ) { if( QLineEdit* e = btn->parent()->findChild< QLineEdit* >() ) { QMessageBox::information( this, "Button was clicked!", e->text() ); return; } } } |
Наибольший интерес здесь представляет использование функций sender() и findChild(). Наличие этих функций в Qt позволяет нам не хранить указатели на содержимое каждого виджета в списке.
Функция sender() возвращает указатель на QObject, для которого сработал сигнал. В нашем случае — сигнал clicked() для QPushButton.
С помощью findChild() мы находим объект текстового поля. Заметим, что вызов этой функции происходит для родителя кнопки: btn->parent().
Таким образом, в результате щелчка на кнопке содержимое соседнего QLineEdit будет отображено в информационном диалоговом окне.
А теперь определим конструктор MainWidget, в котором заполним список содержимым:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
MainWidget::MainWidget( QWidget* parent ) : QWidget( parent ) { QListWidget* lstWgt = new QListWidget; QLayout* l = new QVBoxLayout; l->addWidget( lstWgt ); setLayout( l ); // Добавим в список 10 элементов for( int i = 0; i < 10; ++i ) { makeItem( lstWgt ); } resize( 500, 500 ); } |
Спасибо! Очень помогло.