• 【Qt进阶之自定义控件】使用QListWidget实现自定义Item效果


    目的

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

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

    listItem

    主界面UI

    操作流程:

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

    实现需解决问题

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

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

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

    示例

    示例中用到的方法,多为控件的成员方法,如需了解更多,可选择某类按F1查阅帮助文档
    首先是主窗口代码
    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:
       // 项列表控件中添加Item
       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()
    {
       // 创建item
       QListWidgetItem* pItem = new QListWidgetItem("");
       ui->listWidget->addItem(pItem);
       // 创建自定义widget
       custemItem* pCustomItem = new custemItem(pItem);
       ui->listWidget->setItemWidget(pItem, pCustomItem);
       ui->listWidget->setCurrentItem(pItem);
       // 实现自定义信号和槽,当删除时,从列表中删除item
       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
    • 41

    其次是自定义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

    如果疑问,可留言讨论。

  • 相关阅读:
    EViT:借鉴鹰眼视觉结构,南开大学等提出ViT新骨干架构,在多个任务上涨点
    LeetCode刷题(python版)——Topic51N 皇后
    企业如何结合 SaaS 与 RADIUS 保障 WiFi 安全?
    解析华为OSPF协议
    VS Code + Remote-ssh插件实现远程开发
    Windows提权辅助工具WES-NG使用
    基于条形码的WMS仓储管理系统有什么优势
    java计算机毕业设计风情旅游网站源码+mysql数据库+系统+lw文档+部署
    bff层解决了什么痛点
    Feign实现文件上传下载
  • 原文地址:https://blog.csdn.net/MrHHHHHH/article/details/133963954