• Qt使用QListWidget实现自定义Item效果


    Q:如何在Qt库的基础上,实现自定义控件呢?
    A:根据官方文档回答,就是继承需实现的控件,然后实现自定义功能。

    以下是实现QListWidget控件的自定义item。
    先看下最终效果是如何:

    listItem

    主界面UI

    操作流程:

    • 主窗口中央控件是QListWidget,点击添加按钮,会随机向主窗口中央控件中添加自定义item;
    • 选中某条前的可选框,如果选中,点击右侧的删除图标,会弹出提示是否删除;如果不选中,右侧删除图标无法点击;
    • 点击,删除当前item,点击,不删除。
      在这里插入图片描述

    实现需解决问题

    • 1:如何在QListWidget中添加带有按钮、文本等其它控件的项?

    • 2:选中某项后如何响应?QListWidget自带的item响应为什么不生效?

    • 3:如何选中删除按钮后,通知QListWidget做出删除当前item的操作?

    示例

    首先是主窗口代码
    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
       Q_OBJECT
    
    public:
       explicit MainWindow(QWidget *parent = nullptr);
       ~MainWindow();
    
    private slots:
       // 添加项
       void on_btn_add_clicked();
    
    private:
       Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    
    • 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

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include 
    #include 
    
    #include 
    
    MainWindow::MainWindow(QWidget *parent) :
       QMainWindow(parent),
       ui(new Ui::MainWindow)
    {
       ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
       delete ui;
    }
    
    
    void MainWindow::on_btn_add_clicked()
    {
       QListWidgetItem* pItem = new QListWidgetItem("");
       ui->listWidget->addItem(pItem);
    
       custemItem* pCustomItem = new custemItem(pItem);
       ui->listWidget->setItemWidget(pItem, pCustomItem);
       ui->listWidget->setCurrentItem(pItem);
    
       connect(pCustomItem, &custemItem::emit_del, this, [&](QListWidgetItem* pItem){
           QMessageBox::StandardButton btn = QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("是否删除?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
           if(QMessageBox::No == btn)
               return;
           ui->listWidget->removeItemWidget(pItem);
           delete pItem;
           pItem = nullptr;
       });
    }
    
    
    • 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

    其次是自定义QWidget控件代码
    customitem.h

    #ifndef CUSTEMITEM_H
    #define CUSTEMITEM_H
    
    #include 
    #include 
    
    namespace Ui {
    class custemItem;
    }
    
    class custemItem : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit custemItem(QListWidgetItem* pItem, QWidget *parent = nullptr);
        ~custemItem();
    
    signals:
        void emit_del(QListWidgetItem* pItem);
    
    private slots:
        void on_pushButton_clicked();
    
    private:
        Ui::custemItem *ui;
        QListWidgetItem* m_pItem;
    };
    
    #endif // CUSTEMITEM_H
    
    
    • 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

    customitem.cpp

    #include "custemitem.h"
    #include "ui_custemitem.h"
    #include "defind.h"
    
    custemItem::custemItem(QListWidgetItem* pItem, QWidget *parent) :
        QWidget(parent),
        ui(new Ui::custemItem),
        m_pItem(pItem)
    {
        ui->setupUi(this);
        ui->pushButton->setEnabled(false);
    
        int nRand = qrand()%4;
        ui->checkBox->setText(slText.at(nRand));
        ui->checkBox->setIcon(QIcon(slIcon.at(nRand)));
    
    
        connect(ui->checkBox, &QCheckBox::clicked, this, [=](){
           ui->pushButton->setEnabled(ui->checkBox->isChecked());
        });
    }
    
    custemItem::~custemItem()
    {
        delete ui;
    }
    
    void custemItem::on_pushButton_clicked()
    {
        if(ui->checkBox->isChecked())
        {
            emit emit_del(m_pItem);
        }else{
    
        }
    }
    
    
    • 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

    增加一个随机显示图标和文本的类
    defind.h

    #ifndef DEFIND_H
    #define DEFIND_H
    
    
    #include 
    #include 
    #include 
    
    QStringList slText = {"12312312.mp3", "dfdafds.mp4", "zcvzcvzxv.txt", "asdfasdfafsafdf.avi"};
    QList<QString> slIcon = {":/res/mp3.png", ":/res/mp4.png", ":/res/TXT.png", ":/res/Video.png"};
    
    
    #endif // DEFIND_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    最后是main代码
    main.cpp

    #include "mainwindow.h"
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    如果疑问,可留言讨论。

  • 相关阅读:
    数据生产流程——采集、清洗、分析
    视频图像处理算法opencv模块硬件设计图像颜色识别模块
    【代码精读】ATF启动bl33程序
    数据库相关概念复习--个人复习使用
    热门API接口资源:从开发到上线,大大提速工作流程
    软考高级系统架构设计师系列之:信息系统综合知识常考知识点详细总结
    RT-DETR算法优化改进:Backbone改进 | EMO,结合 CNN 和 Transformer 的现代倒残差移动模块设计 | ICCV2023
    MCE | 靶向 cGAS-STING 通路或可治疗渐冻症
    10Gb每秒!SM4的单核“心”!海泰携手海量数据安全“闪”护
    Google Earth Engine ——利用where来合理划分NDVI阈值
  • 原文地址:https://blog.csdn.net/MrHHHHHH/article/details/133937289