QListWidget自定義item的兩種方式(一)——使用Delegate

一. 效果

使用Delegate自定義QListWidget的Item,測試程序效果如下(下面內容包含測試程序源代碼):

二. 步驟

使用Delegate自定義QListWidget的Item的步驟如下:

1. 派生QStyledIemDelegete得到一個子類

class CMyListWidgetDelegate : public QStyledItemDelegate

 

2. 爲QListWidget指定一個delegate

ui->listWidget->setItemDelegate(new CMyListWidgetDelegate(ui->listWidget));

 

3. QStyledIemDelegete派生得到的子類,重寫paint和sizehint兩個函數

重寫這兩個函數,來自定義Item的顯示。

//決定如何繪圖
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

//決定單元格的推薦大小
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;

備註:如果沒有給QListWidget設置delegate,QlistWidget也會給自己創建一個默認的delegate。

 

三. 測試程序及效果

MyListWidgetDelegate.h

#ifndef MYLISTWIDGETDELEGATE_H
#define MYLISTWIDGETDELEGATE_H

#include <QStyledItemDelegate>

class CMyListWidgetDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    CMyListWidgetDelegate(QObject* pParent);
    virtual ~CMyListWidgetDelegate();

private:
    //決定如何繪圖
    virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    //決定單元格的推薦大小
    virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;

};

#endif // MYLISTWIDGETDELEGATE_H

MyListWidgetDelegate.cpp

#include "MyListWidgetDelegate.h"
#include <QPainter>

CMyListWidgetDelegate::CMyListWidgetDelegate(QObject *pParent)
    :QStyledItemDelegate(pParent)
{

}

CMyListWidgetDelegate::~CMyListWidgetDelegate()
{

}

void CMyListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //QStyledItemDelegate::paint(painter, option, index);

    QRect rect = option.rect; // 目標矩形
    rect.adjust(2,2,-2,-2); // 縮小一圈,留出空白間隔

    // 取得該項對應的數據
    QString qstrFileName = index.data(Qt::DisplayRole).toString();
    QString qstrRecordPic = index.data(Qt::UserRole+1).toString();
    int iFileSize = index.data(Qt::UserRole+2).toInt();

    // 狀態顯示: 若該項被選中
    if(option.state & QStyle::State_Selected)
    {
        painter->setBrush(QColor(0xCC, 0xAA, 0xAA));
        painter->drawRoundedRect(rect, 2, 2);
        painter->setBrush(Qt::NoBrush);
    }

    // 圖片顯示
    {
        QRect dst = rect;
        dst.setRight(rect.left() + 40);
        QRect area(0,0,24,24);
        area.moveCenter(dst.center());

        QPixmap pixmapPic(qstrRecordPic);
        painter->drawPixmap(area, pixmapPic);

    }

    // 文件名顯示
    {
        QRect dst = rect;
        dst.setLeft(rect.left() + 40);
        dst.setBottom(rect.top() + 20);
        painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, qstrFileName);
    }

    // 文件大小
    {
        QRect dst = rect;
        dst.setLeft(rect.left() + 40);
        dst.setTop(rect.top() + 20);
        painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, QString::number(iFileSize));
    }

}

QSize CMyListWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    //return QStyledItemDelegate::sizeHint(option, index);

    QSize size = QStyledItemDelegate::sizeHint(option, index);
    size.setHeight(40);
    return size;
}

MainWidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>

namespace Ui {
class CMainWidget;
}

class CMainWidget : public QWidget
{
    Q_OBJECT

public:
    explicit CMainWidget(QWidget *parent = 0);
    ~CMainWidget();

private:
    Ui::CMainWidget *ui;

    void AddItem(const QString& qstrDownloadFileName, const QString& qstrRecordPic, int iFileSize);
};

#endif // MAINWIDGET_H

MainWidget.cpp

#include "MainWidget.h"
#include "ui_MainWidget.h"
#include "MyListWidgetDelegate.h"

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

    //添加數據
    AddItem("Video1", ":/images/video_1.png", 1024);
    AddItem("Video2", ":/images/video_2.png", 2048);
    AddItem("Video3", ":/images/video_3.png", 3072);
    AddItem("Video4", ":/images/video_4.png", 4096);
    AddItem("Video5", ":/images/video_1.png", 5120);

    //使用自定義繪圖
    ui->listWidget->setItemDelegate(new CMyListWidgetDelegate(ui->listWidget));

}

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

void CMainWidget::AddItem(const QString& qstrDownloadFileName, const QString& qstrRecordPic, int iFileSize)
{
    QListWidgetItem* pItem = new QListWidgetItem();
    if(nullptr != pItem)
    {
        pItem->setData(Qt::DisplayRole, qstrDownloadFileName);
        pItem->setData(Qt::UserRole + 1, qstrRecordPic);
        pItem->setData(Qt::UserRole + 2, iFileSize);
        ui->listWidget->addItem(pItem);
    }
}

main.cpp

#include "MainWidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CMainWidget w;
    w.show();

    return a.exec();
}

程序運行效果如下:

該測試程序,如果沒有給QListWidget設置delegate(即註釋掉MainWidget.cpp中的ui->listWidget->setItemDelegate(new CMyListWidgetDelegate(ui->listWidget));)

則只會顯示Qt::DisplayRole的數據,效果如下:

 

相關資料:

QListWidget自定義item的兩種方式(二)——使用QWidget作爲item

自定義QWidget作爲QListWidget的Item時偶爾出現位置偏移問題的解決方法和原理

 

 

 

 

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