实现TextListWidget控件(带删除按钮)

一、运行效果

实现文本列表框控件,先看效果,不耽误大家时间,有需要自取。
在这里插入图片描述

二、实现思路

继承QListWidget,然后使用setItemWidget方法,为每个item指定一个widget。

void setItemWidget(QListWidgetItem *item, QWidget *widget);

并在每个widget中添加一个删除按钮,信号连接到删除item处理逻辑。

三、控件代码

我们先实现item对应的widget类TextItemWidget

TextItemWidget.h

#ifndef TEXTITEMWIDGET_H
#define TEXTITEMWIDGET_H

#include <QWidget>

class QPushButton;
class QLabel;

class TextItemWidget : public QWidget
{
    Q_OBJECT
public:
    TextItemWidget(QWidget* parent = nullptr);

    QString getText() const;
    void setText(const QString &value);

signals:
    void deleteBtnClicked();

private:
    QLabel* label;
    QPushButton* btn;
};

#endif // TEXTITEMWIDGET_H

TextItemWidget.cpp

#include "TextItemWidget.h"
#include <QHBoxLayout>
#include <QPushButton>
#include <QLabel>

const QString BTN_QSS = "QPushButton{"
                            "border-image: url(:/res/close_normal.png);"
                        "}"
                        "QPushButton::hover{"
                           "border-image: url(:/res/close_hover.png);"
                        "}"
                        "QPushButton::pressed{"
                            "border-image: url(:/res/close_hover.png);"
                        "}";

TextItemWidget::TextItemWidget(QWidget *parent)
    : QWidget(parent)
{
    label = new QLabel();
    btn = new QPushButton(this);
    btn->setFixedSize(48, 48);
    btn->setStyleSheet(BTN_QSS);

    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->addWidget(label);
    layout->addWidget(btn);

    connect(btn, &QPushButton::clicked, this, &TextItemWidget::deleteBtnClicked);
}

QString TextItemWidget::getText() const
{
    return label->text();
}

void TextItemWidget::setText(const QString &value)
{
    label->setText(value);
}

然后,实现TextListWidget类

TextListWidget.h

#ifndef TEXTLISTWIDGET_H
#define TEXTLISTWIDGET_H

#include <QListWidget>
#include <QMap>

class TextListWidget : public QListWidget
{
    Q_OBJECT
public:
    TextListWidget(QWidget *parent = nullptr);

    void addItem(const QString &text, const QVariant& userData = QVariant());

    QVariant userData(int row);

private slots:
    void onBtnClicked();

private:
    QMap<QObject*, QListWidgetItem*> widgetItemMap;
};

#endif // TEXTLISTWIDGET_H

TextListWidget.cpp

#include "TextListWidget.h"
#include "TextItemWidget.h"

#define LIST_ITEM_USER_ROLE   (Qt::UserRole + 0x01)

TextListWidget::TextListWidget(QWidget *parent)
    :QListWidget (parent)
{

}

void TextListWidget::addItem(const QString &text, const QVariant &userData)
{
    TextItemWidget* widget = new TextItemWidget();
    widget->setText(text);
    connect(widget, &TextItemWidget::deleteBtnClicked, this, &TextListWidget::onBtnClicked);

    QListWidgetItem* item = new QListWidgetItem();
    item->setData(LIST_ITEM_USER_ROLE, userData);
    QListWidget::addItem(item);
    QListWidget::setItemWidget(item, widget); // 必须先addItem,后才能setItemWidget
    item->setSizeHint(widget->size());

    widgetItemMap[widget] = item;
}

QVariant TextListWidget::userData(int row)
{
    return item(row)->data(LIST_ITEM_USER_ROLE);
}

void TextListWidget::onBtnClicked()
{
    QObject* widget = sender();
    QListWidgetItem* item = widgetItemMap[widget];
    delete item;
    delete widget;
    widgetItemMap.remove(widget);
}

四、测试代码

mainwindow.cpp

const QString str = QStringLiteral("静夜思\n \
                                   ----------------------------\n \
                                   床前明月光,疑是地上霜。 \n \
                                   举头望明月,低头思故乡。");

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    listWidget = new TextListWidget(ui->widget);
    QHBoxLayout* layout = new QHBoxLayout(ui->widget);
    layout->addWidget(listWidget);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    listWidget->addItem(str);
}



若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:41QListWidget,即可下载。

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值