Qt之列表的使用(QListView、QListWidget)

QListView

将存储在模型中的项显示为简单的非层次列表或图标集合

常用方法:
void setModel(QAbstractItemModel *model) //设置模型
void setMovement(Movement movement) //设置数据是否可以任意拖动 QListView::Static:用户无法移动项目 QListView::Free //用户可以自由移动项目 QListView::Snap 用户可以自由移动项目,移动时项目会捕捉到指定的网格
void setSpacing(int space) //设置数据间距
自定义QListView:
继承QAbstractListModel,自定义model
继承QStyledItemDelegate,自定义Delegate

QListWidget

是“简易版”的 QListView,创建和使用列表的方式更简单、门槛更低,只能创建结构简单的列表,如果要制作复杂的列表,应优先考虑 QListView
在数据多的时候,QListWidget性能会降低
QListWidgetItem的子类,用于实现自定义的item
常用方法:
void addItem(const QString &label);//添加项
void addItem(QListWidgetItem *item);
QListWidgetItem *currentItem() const;//当前项
QListWidgetItem *takeItem(int row);//获取后删除该项
void insertItem(int row, QListWidgetItem *item);
void insertItem(int row, const QString &label);

自定义QListWidget:
继承widget,自定义widget
通过setItemWidget设置

代码

widgetlist.h


#ifndef WIDGETLIST_H
#define WIDGETLIST_H

#include 
#include 
#include "customlistview.h"

namespace Ui {
class WidgetList;
}

class WidgetList : public QWidget
{
    Q_OBJECT

public:
    explicit WidgetList(QWidget *parent = nullptr);
    ~WidgetList();

    //ListView
    void initListView();
    //自定义ListView
    void initCustomListView();

    //ListWidget
    void initListWidget();
    //自定义ListWidget
    void initCustomListWidget();
    void addCustomListWidgetItem(const QString& sName, const QString& sDes, const QString& sPic);

protected:
    void changeEvent(QEvent* event);

private slots:
    //ListView
    void on_btn_listview_get_clicked();
    void on_btn_listview_delete_clicked();
    void on_btn_listview_set_clicked();
    void on_btn_listview_add_clicked();

    //ListWidget
    void on_btn_listwidget_get_clicked();
    void on_btn_listwidget_delete_clicked();
    void on_btn_listwidget_set_clicked();
    void on_btn_listwidget_add_clicked();

private:
    void retranslateUi();

private:
    QStringListModel *m_pModel; //该数据模型,只能用于字符串

    //自定义ListView
    CustomListViewModel *m_pCustomModel;
    CustomListViewDelegate *m_pCusDelegate;
private:
    Ui::WidgetList *ui;
};

#endif // WidgetList_H



widgetlist.cpp

#include "widgetlist.h"
#include "ui_widgetlist.h"
#include "commondef.h"
#include 
#include 

#include "customlistwidgetitem.h"

WidgetList::WidgetList(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::WidgetList)
{
    ui->setupUi(this);
    retranslateUi();

    initListView();
    initListWidget();

    initCustomListView();
    initCustomListWidget();
}

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

/*************************
 * QListView-初始化
 * ***********************/
void WidgetList::initListView()
{
    //1.创建数据显示列表
    QStringList list;
    for(int i = 0; i < 5; ++i)
    {
        list.append(QString("Item_%1").arg(i+1));
    }

    //2.使用数据列表创建数据显示模型
    m_pModel = new QStringListModel(list);

    //3.设置模型
    ui->listView->setModel(m_pModel);
    ui->listView->setMovement(QListView::Free);//设置数据可以自由拖动
    ui->listView->setSpacing(2);//设置数据间隔
}

/*************************
 * QListView-插入函数
 * ***********************/
void WidgetList::on_btn_listview_add_clicked()
{
    QString str = ui->lineEdit->text();
    if(str.isEmpty())
    {
        MY_DEBUG << "The content of lineEdit is empty";
        return;
    }

    //1.获取行数
    int row = m_pModel->rowCount();
    //2.插入新行
    m_pModel->insertRow(row);
    //3.获取插入行的索引index
    QModelIndex index = m_pModel->index(row);
    //4.通过index设置数据
    m_pModel->setData(index, str);
    //5.设置到当前index
    ui->listView->setCurrentIndex(index);
}

/*************************
 * QListView-删除函数
 * ***********************/
void WidgetList::on_btn_listview_delete_clicked()
{
    //1.获取当前的index
    QModelIndex index = ui->listView->currentIndex();
    if(-1 == index.row())
    {
        MY_DEBUG << "No Select One Item";
        return;
    }

    //2.根据index删除行
    m_pModel->removeRow(index.row());
}

/*************************
 * QListView-修改函数
 * ***********************/
void WidgetList::on_btn_listview_set_clicked()
{
    QString str = ui->lineEdit->text();
    if(str.isEmpty())
    {
        MY_DEBUG << "The content of lineEdit is empty";
        return;
    }

    //1.获取当前的index
    QModelIndex index = ui->listView->currentIndex();
    if(-1 == index.row() || str.isEmpty())
    {
        return;
    }

    //2.通过index设置数据
    m_pModel->setData(index, str);
}

/*************************
 * QListView-获取函数
 * ***********************/
void WidgetList::on_btn_listview_get_clicked()
{
    //1.获取当前index
    QModelIndex index = ui->listView->currentIndex();
    if(-1 == index.row())
    {
        MY_DEBUG << "No Select One Item";
        return;
    }

    //2.获取当前index的值
    ui->lineEdit->setText(index.data(Qt::DisplayRole).toString());
}

/*************************
 * QListView自定义-初始化
 * ***********************/
void WidgetList::initCustomListView()
{
   m_pCustomModel = new CustomListViewModel();
   for (int i = 0; i < 5; ++i)
   {
       CUSTOM_DATA data;
       data.m_bCheck = (i%2==0);
       data.m_sDes = QString("Item_%1").arg(QString::number(i+1));
       m_pCustomModel->insertData(data);
   }

   m_pCusDelegate = new CustomListViewDelegate();
   ui->listView_2->setModel(m_pCustomModel);
   ui->listView_2->setItemDelegate(m_pCusDelegate);
   ui->listView_2->setMouseTracking(true);
}
/
/*************************
 * QListWidget-初始化
 * ***********************/
void WidgetList::initListWidget()
{
    for(int i = 0; i <5; ++i)
    {
        //1.使用addItem添加数据
        ui->listWidget->addItem(tr("Item_") + QString::number(i+1));
    }
}

/*************************
 * QListWidget-添加函数
 * ***********************/
void WidgetList::on_btn_listwidget_add_clicked()
{
    QString str = ui->lineEdit_2->text();
    if(str.isEmpty())
    {
        MY_DEBUG << "The content of lineEdit is empty";
        return;
    }

    ui->listWidget->addItem(str);
}

/*************************
 * QListWidget-删除函数
 * ***********************/
void WidgetList::on_btn_listwidget_delete_clicked()
{
    //1.判断当前项currentItem()
    if(ui->listWidget->currentItem() != Q_NULLPTR)
    {
        //2.使用takeItem删除当前行
        QListWidgetItem* Item = ui->listWidget->takeItem(ui->listWidget->currentRow());
        delete Item;
    }
}

/*************************
 * QListWidget-修改函数
 * ***********************/
void WidgetList::on_btn_listwidget_set_clicked()
{
    QString str = ui->lineEdit_2->text();
    if(str.isEmpty())
    {
        MY_DEBUG << "The content of lineEdit is empty";
        return;
    }

    //1.判断当前项currentItem()
    if(ui->listWidget->currentItem() != Q_NULLPTR)
    {
        //2.设置当前项内容
        ui->listWidget->currentItem()->setText(str);
    }
}


/*************************
 * QListWidget-获取函数
 * ***********************/
void WidgetList::on_btn_listwidget_get_clicked()
{
    //1.判断当前项currentItem()
    if(ui->listWidget->currentItem() != Q_NULLPTR)
    {
        //2.获取当前项数据
        QListWidgetItem* Item = ui->listWidget->currentItem();
        ui->lineEdit_2->setText(Item->data(Qt::DisplayRole).toString());
    }
}

/*************************
 * QListWidget自定义-初始化
 * ***********************/
void WidgetList::initCustomListWidget()
{
    ui->listWidget_2->setResizeMode(QListView::Adjust);
    ui->listWidget_2->setViewMode(QListView::IconMode);

    for(int i = 0; i < 5; ++i)
    {
        addCustomListWidgetItem(QString("Item_%1").arg(i+1),
                                QString("Item_Des_%1").arg(i+1),
                                QString(":/Resource/Image/WidgetList/person.jpg"));

    }
}

/*************************
 * QListWidget自定义-添加
 * ***********************/
void WidgetList::addCustomListWidgetItem(const QString &sName, const QString &sDes, const QString &sPic)
{
    //1.设置CustomItem数据
    CustomListWidgetItem *pCustomItem = new CustomListWidgetItem(this);
    pCustomItem->SetData(sName, sDes, sPic);

    //2.添加QListWidgetItem
    QListWidgetItem* pItem = new QListWidgetItem();
    pItem->setSizeHint(QSize(350, 40));
    ui->listWidget_2->addItem(pItem);

    //3.通过setItemWidget设置Item
    ui->listWidget_2->setItemWidget(pItem, pCustomItem);
}
/

/*************************
 * 语言翻译处理
 * ***********************/
void WidgetList::changeEvent(QEvent *event)
{
    switch(event->type())
    {
        case QEvent::LanguageChange:
            retranslateUi();
            break;
        default:
            QWidget::changeEvent(event);
    }
}

void WidgetList::retranslateUi()
{
    ui->label->setText(tr("Use List View"));
    ui->label_2->setText(tr("Use List Widget"));
    ui->label_3->setText(tr("Use Custom List View"));
    ui->label_4->setText(tr("Use Custom List Widget"));

    ui->btn_listview_add->setText(tr("Add"));
    ui->btn_listview_set->setText(tr("Set"));
    ui->btn_listview_delete->setText(tr("Delete"));
    ui->btn_listview_get->setText(tr("Get"));

    ui->btn_listwidget_add->setText(tr("Add"));
    ui->btn_listwidget_set->setText(tr("Set"));
    ui->btn_listwidget_delete->setText(tr("Delete"));
    ui->btn_listwidget_get->setText(tr("Get"));
}



customlistview.h

#ifndef CUSTOMLISTVIEW_H
#define CUSTOMLISTVIEW_H

#include 
#include 
#include 
#include 
#include 

//自定义数据
typedef struct CUSTOM_DATA_T
{
    bool m_bCheck;
    QString m_sDes;
}CUSTOM_DATA;

Q_DECLARE_METATYPE(CUSTOM_DATA)


//自定义模型
class CustomListViewModel : public QAbstractListModel
{
    Q_OBJECT

public:
    CustomListViewModel();
    ~CustomListViewModel();

    //插入数据
    void insertData(CUSTOM_DATA data);
    //获取总行数
    int rowCount(const QModelIndex &parent) const;
    //获取当前行数据
    QVariant data(const QModelIndex &index, int role) const;
    //设置当前行数据
    bool setData(const QModelIndex &index, const QVariant &value, int role);

private:
    QList m_ListData;
};

//自定义模型视图-用于数据项目的显示和编辑
class CustomListViewDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    CustomListViewDelegate();
    ~CustomListViewDelegate();

    //描绘画面显示
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    //处理鼠标事件
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
};

#endif // CUSTOMLISTVIEW_H


customlistview.cpp

#include "customlistview.h"
#include "commondef.h"

CustomListViewModel::CustomListViewModel()
{
}

CustomListViewModel::~CustomListViewModel()
{
}

/*************************
 * CustomListViewModel-插入数据
 * ***********************/
void CustomListViewModel::insertData(CUSTOM_DATA data)
{
    m_ListData.push_back(data);
}

/*************************
 * CustomListViewModel-获取总行数
 * ***********************/
int CustomListViewModel::rowCount(const QModelIndex &parent) const
{
    return m_ListData.size();
}

/*************************
 * CustomListViewModel-获取当前行数据
 * ***********************/
QVariant CustomListViewModel::data(const QModelIndex &index, int role) const
{
    QVariant ret;
    int row = index.row();

    if(row >= m_ListData.size() || (!index.isValid()))
    {
        return QVariant();
    }

    CUSTOM_DATA tmpData = m_ListData.at(row);
    // 下面的role要和setData中的role一一对应;
    switch(role)
    {
        case Qt::UserRole+1:
            ret = tmpData.m_bCheck;
            break;
        case Qt::UserRole+2:
            ret = tmpData.m_sDes;
            break;
        default :
            break;
    }
    return ret;
}

/*************************
 * CustomListViewModel-设置当前行数据
 * ***********************/
bool CustomListViewModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    bool bRet = false;
    int nRow = index.row();

    if(nRow >= m_ListData.size() || (!index.isValid()))
    {
        return false;
    }

    CUSTOM_DATA tmpData = m_ListData.at(nRow);

    switch(role)
    {
        case Qt::UserRole+1:
            tmpData.m_bCheck = value.toBool();
            bRet = true;
            break;
        case Qt::UserRole+2:
            tmpData.m_sDes = value.toString();
            bRet = true;
            break;
        default :
            break;
    }

    m_ListData.replace(nRow, tmpData);
    return bRet;
}



CustomListViewDelegate::CustomListViewDelegate()
{
}

CustomListViewDelegate::~CustomListViewDelegate()
{
}

/*************************
 * CustomListViewDelegate-绘制事件,用于显示
 * ***********************/
void CustomListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QRect rect = option.rect;

    //取数据
    bool bCheck = index.data(Qt::UserRole+1).toBool();
    QString sDes = index.data(Qt::UserRole+2).toString();

    QStyleOptionViewItem viewoption(option);
    initStyleOption(&viewoption, index);
    if(option.state.testFlag(QStyle::State_HasFocus))
    {
        viewoption.state = viewoption.state^QStyle::State_HasFocus;
    }
    QStyledItemDelegate::paint(painter, viewoption, index);


    //绘制checkbox
    {
        QRect checboxRec(rect.left() + 10, rect.top() + (rect.height()-14)/2, 14, 14);
        if(bCheck)
        {
            QPixmap pix(":/Resource/Image/MainForm/select.png");
            painter->drawPixmap(checboxRec, pix);
        }
        else
        {
            QPixmap pix(":/Resource/Image/MainForm/select_checked.png");
            painter->drawPixmap(checboxRec, pix);
        }
    }

    //绘制文本
    {
        painter->save();

        //设置字体,颜色
        QFont font;
        font.setFamily("Microsoft YaHei");
        font.setPixelSize(12);
        painter->setFont(font);

        QRect txtRec(rect.left() + 40, rect.top(), rect.width()-100, rect.height());
        painter->drawText(txtRec, Qt::AlignLeft, sDes);

        painter->restore();
    }
}

/*************************
 * CustomListViewDelegate-编辑事件
 * ***********************/
bool CustomListViewDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QRect rect = option.rect;

    //获取checkbox的rect
    QRect checboxRec(rect.left() + 10, rect.top() + (rect.height()-14)/2, 14, 14);

    //按钮点击事件,点击坐标是否在rect内
    QMouseEvent *mevent = static_cast(event);
    if(checboxRec.contains(mevent->pos()) && event->type() == QEvent::MouseButtonPress)
    {
        bool value = model->data(index, Qt::UserRole+1).toBool();
        model->setData(index, !value, Qt::UserRole+1);
        model->dataChanged(index, index);


        //此处可以添加自定义信号,即使checbox点击信号;
        MY_DEBUG << "Edit";
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}


customlistwidgetitem.h

#ifndef CUSTOMLISTWIDGETITEM_H
#define CUSTOMLISTWIDGETITEM_H

#include 

namespace Ui {
class CustomListWidgetItem;
}

//自定义ListWidgetItem
class CustomListWidgetItem : public QWidget
{
    Q_OBJECT

public:
    explicit CustomListWidgetItem(QWidget *parent = nullptr);
    ~CustomListWidgetItem();

    //设置数据
    void SetData(const QString& sName, const QString& sDes, const QString& sPic);

private:
    Ui::CustomListWidgetItem *ui;
};

#endif // CUSTOMLISTWIDGETITEM_H


customlistwidgetitem.cpp

#include "customlistwidgetitem.h"
#include "ui_customlistwidgetitem.h"

CustomListWidgetItem::CustomListWidgetItem(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CustomListWidgetItem)
{
    ui->setupUi(this);
}

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

void CustomListWidgetItem::SetData(const QString &sName, const QString &sDes, const QString &sPic)
{
    ui->label_name->setText(sName);
    ui->label_des->setText(sDes);

    QPixmap pic(sPic);
    int nWidth = ui->label_pic->width();
    int nHeight = ui->label_pic->height();

    //饱满填充
    QPixmap pic_fit = pic.scaled(nWidth, nHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->label_pic->setPixmap(pic_fit);
}



实现效果

Qt之列表的使用(QListView、QListWidget)_第1张图片

工程下载地址:

https://download.csdn.net/download/linyibin_123/86512679

你可能感兴趣的:(qt,qt,ui,开发语言)