Скомпоновать список QListWidget, состоящий из текстовых элементов, в Qt довольно просто. Следующий пример демонстрирует, как это сделать:
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 |
#include <QApplication> #include <QListWidget> static const QStringList LIST_ITEMS = QStringList() << "C++" << "Python" << "Java" << "C#" << "PHP" << "Ruby" << "JavaScript"; // Класс-обработчик сигналов от виджета списка class ListController : public QObject { Q_OBJECT public slots: void onListDoubleClicked( const QModelIndex& index ) { if( !index.isValid() ) { return; } if( QListWidget* listWgt = dynamic_cast< QListWidget* >( sender() ) ) { if( QListWidgetItem* item = listWgt->takeItem( index.row() ) ) { delete item; } } } }; int main( int argc, char* argv[] ) { QApplication a( argc, argv ); QListWidget listWgt; listWgt.addItems( LIST_ITEMS ); listWgt.resize( 300, 300 ); listWgt.show(); ListController listController; QObject::connect( &listWgt, SIGNAL( doubleClicked( QModelIndex ) ), &listController, SLOT( onListDoubleClicked( QModelIndex ) ) ); return a.exec(); } // Без этого инклюда приложение не скомпилируется // Это связано с тем, что объявление класса ListController расположено в cpp-файле, // в котором использован макрос Q_OBJECT #include "main.moc" |
В результате получили приложение, которое позволяет удалить любой элемент списка двойным щелчком мыши по нему.
Разберемся с различными частями примера поподробнее.
Заполнение списка содержимым
Чтобы заполнить QListWidget, мы использовали функцию-член addItems(), передав в нее список строк QStringList:
1 |
listWgt.addItems( LIST_ITEMS ); |
Однако можно добавлять и по одному пункту:
1 2 3 |
foreach( const QString& item, LIST_ITEMS ) { listWgt.addItem( item ); } |
Если требуется более тонкий контроль над элементами списка, то придется использовать перегруженную функцию QListWidget::addItem(), принимающую указатель на QListWidgetItem:
1 2 3 4 5 6 7 8 9 10 |
// Устанавливаем размер иконок listWgt.setIconSize( QSize( 32, 32 ) ); foreach( const QString& item, LIST_ITEMS ) { QListWidgetItem* listItem = new QListWidgetItem( item ); listItem->setIcon( QPixmap( item + ".png" ) ); // Включаем возможность редактирования listItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled ); listWgt.addItem( listItem ); } |
В этом примере мы заполняем список не просто текстом, а элементами с графическими иконками.
Графика для иконок загружается из файлов, расположенных в одном каталоге с исполняемым файлом, с помощью строки:
1 |
listItem->setIcon( QPixmap( item + ".png" ) ); |
Размер иконок определяется на уровне всего виджета списка с помощью:
1 |
listWgt.setIconSize( QSize( 32, 32 ) ); |
К тому же, для элементов установлен флаг возможности редактирования (обратите внимание на пункт PHP на скриншоте):
1 |
listItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled ); |
Для списка можно использовать режим иконок:
1 |
listWgt.setViewMode( QListWidget::IconMode ); |
В режиме иконок для элементов поддерживается функционал drag & drop. Например, для включения перетаскивания ( drag) устанавливаем флаги элемента:
1 |
listItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled ); |
В дополнение можно обеспечить возможность множественного выделения элементом на уровне всего списка:
1 |
listWgt.setSelectionMode( QListWidget::MultiSelection ); |
Получить список всех выбранных в данный момент элементов можно с помощью QListWidget::selectedItems(), которая возвращает QList< QListWidgetItem* >.
Вставлять элементы можно не только в конец списка (с помощью QListWidget::addItem()), но и в любое место с помощью QListWidget::insertItems() и QListWidget::insertItem(). Разница заключается лишь в том, что первым аргументом эти функции принимают номер ряда, в который должны быть вставлены новые элементы.
Удаление элементов списка
В примере из начала удаление элементов привязано к двойному щелчку по элементу:
1 2 3 4 5 6 7 8 9 10 11 |
void onListDoubleClicked( const QModelIndex& index ) { if( !index.isValid() ) { return; } if( QListWidget* listWgt = dynamic_cast< QListWidget* >( sender() ) ) { if( QListWidgetItem* item = listWgt->takeItem( index.row() ) ) { delete item; } } } |
Сигнал списка doubleClicked() передает индекс QModelIndex, указывающий на элемент, по которому был произведен двойной щелчок мышью. Чтобы удалить элемент, извлекаем его из списка с помощью takeItem() по номеру ряду, полученному от индекса. Однако память освобождена после этого не будет, поэтому не забудьте вызвать delete.
В следующем примере привяжем нажатие клавиши Del к событию удаления выделенных элементов списка, воспользовавшись QShortcut:
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 |
#include <QApplication> #include <QKeySequence> #include <QShortcut> #include <QListWidget> static const QStringList LIST_ITEMS = QStringList() << "C++" << "Python" << "Java" << "C#" << "PHP" << "Ruby" << "JavaScript"; class ListController : public QObject { Q_OBJECT public: ListController( QListWidget* listWgt ) : m_listWgt( listWgt ) { } public slots: void onDeleteItems() { if( m_listWgt ) { QList< QListWidgetItem* > items = m_listWgt->selectedItems(); foreach( QListWidgetItem* item, items ) { int row = m_listWgt->row( item ); m_listWgt->takeItem( row ); delete item; } } } private: QListWidget* m_listWgt; }; int main( int argc, char* argv[] ) { QApplication a( argc, argv ); QListWidget listWgt; listWgt.setSelectionMode( QListWidget::MultiSelection ); listWgt.setIconSize( QSize( 32, 32 ) ); foreach( const QString& item, LIST_ITEMS ) { QListWidgetItem* listItem = new QListWidgetItem( item ); listItem->setIcon( QPixmap( item + ".jpg" ) ); listItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable ); listWgt.addItem( listItem ); } listWgt.resize( 300, 300 ); listWgt.show(); ListController listController( &listWgt ); QShortcut* shortcut = new QShortcut( QKeySequence( Qt::Key_Delete ), &listWgt ); QObject::connect( shortcut, SIGNAL( activated() ), &listController, SLOT( onDeleteItems() ) ); return a.exec(); } #include "main.moc" |
Также не забудьте, что полностью очистить содержимое списка можно с помощью QListWidget::clear().