IT Notes

QListWidget: Примеры использования

Скомпоновать список QListWidget, состоящий из текстовых элементов, в Qt довольно просто. Следующий пример демонстрирует, как это сделать:

#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

Разберемся с различными частями примера поподробнее.

Заполнение списка содержимым

Чтобы заполнить QListWidget, мы использовали функцию-член addItems(), передав в нее список строк QStringList:

listWgt.addItems( LIST_ITEMS );

Однако можно добавлять и по одному пункту:

foreach( const QString& item, LIST_ITEMS ) {
    listWgt.addItem( item );
}

Если требуется более тонкий контроль над элементами списка, то придется использовать перегруженную функцию QListWidget::addItem(), принимающую указатель на QListWidgetItem:

// Устанавливаем размер иконок
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 );
}

В этом примере мы заполняем список не просто текстом, а элементами с графическими иконками:

qlistwidget-icons-list-mode

Графика для иконок загружается из файлов, расположенных в одном каталоге с исполняемым файлом, с помощью строки:

listItem->setIcon( QPixmap( item + ".png" ) );

Размер иконок определяется на уровне всего виджета списка с помощью:

listWgt.setIconSize( QSize( 32, 32 ) );

К тому же, для элементов установлен флаг возможности редактирования (обратите внимание на пункт PHP на скриншоте):

listItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled );

Для списка можно использовать режим иконок:

listWgt.setViewMode( QListWidget::IconMode );

Выглядит это следующим образом:

qlistwidget-icon-mode

В режиме иконок для элементов поддерживается функционал drag & drop. Например, для включения перетаскивания (drag) устанавливаем флаги элемента:

listItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );

В дополнение можно обеспечить возможность множественного выделения элементом на уровне всего списка:

listWgt.setSelectionMode( QListWidget::MultiSelection );

Соответствующий скриншот:

qlistwidget-drag-and-drop

Получить список всех выбранных в данный момент элементов можно с помощью QListWidget::selectedItems(), которая возвращает QList< QListWidgetItem* >.

Вставлять элементы можно не только в конец списка (с помощью QListWidget::addItem()), но и в любое место с помощью QListWidget::insertItems() и QListWidget::insertItem(). Разница заключается лишь в том, что первым аргументом эти функции принимают номер ряда, в который должны быть вставлены новые элементы.

Реклама

Удаление элементов списка

В примере из начала удаление элементов привязано к двойному щелчку по элементу:

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:

#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().

Понравилась статья?
Не забудь поделиться ей с друзьями!
Реклама

Похожие публикации

Комментарии

Спасибо Вам что Вы есть.

Помогите пожалуйста, в следующем:

Как мне после this->item(row)->setIcon(...); удалить её из строки оставив текст????

Пкркпробовал многие методы ничего не работает. ((((((((((

Здравствуйте, Macros! Спасибо за комментарий =)

Если я правильно понял, то можете попробовать вызов: lstWgt->item( row )->setIcon( QPixmap() ).

RSS RSS-рассылка

Популярное