QListWidgetQt框架中提供的一个基于项目的列表控件,它管理着一系列的QListWidgetItem

  • QListWidget 本身:负责整体的展示框架、滚动、选择管理等
  • QListWidgetItem:列表中的每一个条目。它可以包含文本、图标,并可以设置字体、对齐方式等属性。

用户可以查看、增加、删除、修改列表项,并进行点击等操作进行交互。

1. 效果演示

本节实现以下效果:

  • 列表模式、图标模式
  • 交替背景色
  • 追加、插入、删除操作
  • 单击回显、双击编辑

QListWidget

2. 属性和方法

QListWidget有很多属性和方法,完整的可查看帮助文档。这里列出常用的属性和方法:

2.1 显示模式

支持两种显示模式:列表模式和图标模式。

// 获取和设置显示模式
QListView::ViewMode viewMode() const
void setViewMode(QListView::ViewMode mode)

其中,QListView::ViewMode是一个枚举,有两个取值:列表模式(QListView::ListMode)、图标模式(QListView::IconMode

2.2 交替背景色

设置相邻行交替显示不同的背景色,便于显示和浏览时的定位

// 获取和设置交替显示
bool alternatingRowColors() const
void setAlternatingRowColors(bool enable)

2.3 添加条目

既可以在UI设计师界面双击列表框来添加,也可以通过代码动态添加,如下:

// 在尾部添加
void addItem(const QString &label)
void addItem(QListWidgetItem *item)
void addItems(const QStringList &labels)

// 在指定行之前添加
void insertItem(int row, QListWidgetItem *item)
void insertItem(int row, const QString &label)
void insertItems(int row, const QStringList &labels)    

使用包含QListWidgetItem参数的函数,可以为条目指定图标

QListWidgetItem::QListWidgetItem(const QIcon &icon, const QString &text, QListWidget *parent = nullptr, int type = Type)  

2.4 删除条目

列表框中的条目可以删除,以下以删除当前行为例:

// 方法一
QListWidgetItem* item = ui->lwProvince->currentItem();
ui->lwProvince->removeItemWidget(item);
delete item;

// 方法二
int row = ui->lwProvince->currentRow();
QListWidgetItem* item = ui->lwProvince->takeItem(row);
delete item; // 注意:需要手动 delete 掉条目

2.5 信号槽

当然了,列表控件的信号和槽有很多,大家需要用到其他信号槽时,直接去查看官方文档即可。

// 当条目被单击时,发射该信号
void itemClicked(QListWidgetItem *item);

// 当条目被双击时,发射该信号
void itemDoubleClicked(QListWidgetItem *item);

3. 从零实现

从零写代码实现整体效果,以演示进度条的属性以及信号槽的用法

3.1 布局

在UI设计师界面,拖拽对应的控件,修改显示的文字、控件的名称,然后完成布局

  • 在右侧的属性窗口中,将MyWidget窗口的Point Size属性修改为14
  • 修改lineEditSelectedreadOnly属性为true,设置为只读的
  • 设置lineEditInputplaceholderText属性值为 “请输入要添加/插入的省份”,以提示用户
  • 双击listProvince添加几个条目,并设置条目的图标

布局完成效果如下:
qt-base

3.2 添加资源文件

把用到的图标,作为资源文件添加到项目中,如下:
qt-base

3.3 代码实现

从零写代码实现整体效果,以演示列表框的属性以及信号槽的用法

3.3.1 增加和删除条目

首先,在mywidget.h中声明槽函数,如下:

class MyWidget : public QWidget {
    
public slots:
    void onBtnAddClicked();
    void onBtnInsertClicked();
    void onBtnDeleteClicked();
};

然后,在mywidget.cpp中实现这3个槽函数,这里用到了QRandomGenerator类产生一个随机数,为条目随机指定一个图标

  • 追加条目
#include <QRandomGenerator>

QStringList iconStringList = {
    ":/res/apple.ico", 
    ":/res/banana.ico", 
    ":/res/orange.ico", 
    ":/res/peach.ico", 
    ":/res/strawberry.ico"
};

void MyWidget::onBtnAddClicked() {
    int iconIndex = QRandomGenerator::global()->generate() % 5;  // 产生5以内的随机数 0-4
    qDebug() << iconIndex;

    QIcon icon(iconStringList[iconIndex]);
    QString text = ui->lineEditInput->text();

    QListWidgetItem* item = new QListWidgetItem(icon, text);
    ui->listProvince->addItem(item);
}
  • 插入条目
void MyWidget::onBtnInsertClicked() {
    int iconIndex = QRandomGenerator::global()->generate() % 5;  // 产生5以内的随机数 0-4

    QIcon icon(iconStringList[iconIndex]);
    QString text = ui->lineEditInput->text();

    QListWidgetItem* item = new QListWidgetItem(icon, text);

    int currentRow = ui->listProvince->currentRow();
    ui->listProvince->insertItem(currentRow, item);
}
  • 删除条目
void MyWidget::onBtnDeleteClicked() {
#if 0
    // 方法一
    QListWidgetItem* item = ui->listProvince->currentItem();
    ui->listProvince->removeItemWidget(item);
    delete item;
#else
    // 方法二
    int row = ui->listProvince->currentRow();
    QListWidgetItem* item = ui->listProvince->takeItem(row);
    delete item;
#endif
}

最后,在构造函数中关联信号槽,如下:

MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {

    // 追加、插入、删除
    connect(ui->btnAdd, &QPushButton::clicked, this, &MyWidget::onBtnAddClicked);
    connect(ui->btnInsert, &QPushButton::clicked, this, &MyWidget::onBtnInsertClicked);
    connect(ui->btnDelete, &QPushButton::clicked, this, &MyWidget::onBtnDeleteClicked);
}

3.3.2 显示模式、背景交替

首先,在mywidget.h中声明槽函数,并且定义一个QButtonGroup对象来容纳单选按钮,如下:

#include <QButtonGroup>

class MyWidget : public QWidget {

public slots:
    void onRadioModeClicked();
    void onChkAlternatingClicked(bool checked);

private:
    QButtonGroup *btnGroup;
};

然后,在mywidget.cpp中实现槽函数,并关联信号槽,如下:

MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {

    this->setWindowTitle("明王讲QT | 第二章 常用控件 | 2.11 列表控件QListWidget");

    // 显示模式
    btnGroup = new QButtonGroup(this);
    btnGroup->addButton(ui->radioListMode, 0);
    btnGroup->addButton(ui->radioIconMode, 1);
    connect(ui->radioListMode, &QRadioButton::clicked, this, &MyWidget::onRadioModeClicked);
    connect(ui->radioIconMode, &QRadioButton::clicked, this, &MyWidget::onRadioModeClicked);
    ui->radioListMode->setChecked(true);

    // 交替背景色
    connect(ui->chkAlternating, &QCheckBox::clicked, this, &MyWidget::onChkAlternatingClicked);
}

// 切换显示模式:列表模式、图标模式
void MyWidget::onRadioModeClicked() {
    int checkedId = btnGroup->checkedId();
    if ( checkedId == 0 ) {
        ui->listProvince->setViewMode(QListView::ListMode);
    } else if ( checkedId == 1 ) {
        ui->listProvince->setViewMode(QListView::IconMode);
    }
}

// 交替背景色
void MyWidget::onChkAlternatingClicked(bool checked) {
    ui->listProvince->setAlternatingRowColors(checked);
}

3.3.3 单击回显、双击编辑

首先,在mywidget.h中声明槽函数,如下:

#include <QListWidgetItem>

class MyWidget : public QWidget {

public slots:
    void onItemClicked(QListWidgetItem* item);
    void onItemDoubleClicked(QListWidgetItem* item);
};

然后,在mywidget.cpp中实现槽函数,并关联信号槽,如下:

// 条目单击时,显示到文本框
void MyWidget::onItemClicked(QListWidgetItem* item) {
    ui->lineEditSelected->setText(item->text());
}

// 双击条目时,变为可编辑模式
void MyWidget::onItemDoubleClicked(QListWidgetItem* item) {
    item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
}

最后,在mywidget.cpp中构造函数中关联信号槽,如下:

MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {

    // 条目单击和双击的信号槽
    connect(ui->listProvince, &QListWidget::itemClicked, this, &MyWidget::onItemClicked);
    connect(ui->listProvince, &QListWidget::itemDoubleClicked, this, &MyWidget::onItemDoubleClicked);
}

4. 点赞、获取源码

看到这里的小伙伴,去B站给明王一个【免费的点赞】吧,你的支持,是我持续更新优质内容的动力,感谢~

源码下载地址
链接: https://pan.baidu.com/s/1qXOUmXuip8eLIFsxun_Z5A
提取码: ming