實現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);
}

代碼地址:

https://gitee.com/bailiyang/cdemo/tree/master/Qt/41QListWidget/CustomItem


===================================================

===================================================

業餘時間不定期更新一些想法、思考文章,歡迎關注,共同探討,沉澱技術!

            

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章