QT C++ CLion ListView 使用教程

本文介绍了如何使用QStyledItemDelegate来定制QListView的显示效果,包括编写Delegate的步骤,如设置模型数据类型、重写paint和sizeHint方法,以及如何处理悬停、选中等状态下的背景色变化。同时,文中提供了关于滑动条隐藏、禁用,以及整体下滑动效果的实现方法。
摘要由CSDN通过智能技术生成

目录

255.效果展示

00.废话

01.Delegate怎么写

1、不可或缺的事情

2、写.h文件(名称可以自定义,但是必须是继承QStyledItemDelegate)

3、写.cpp文件

02.这个鬼玩意怎么使用

1、如果你是UI生成

2、如果你是代码生成,New完按照上面的配置即可。然后添加到子视图

3、特殊需求的实现 

1、改绘制的颜色

2、为啥我悬停在item上没有变色,是不是BUG?

3、为啥我的QListview旁边出现了滑动条??如何隐藏滑动条,如何禁用滑动条?

4、我不想出现进度条,我就想完整显示!自动适应高度!

5、我想像网易云那样,上面的组件和QListView,整体可以下滑。

  (你在说啥?看例子)


255.效果展示

 事实上,这个是用QListView实现的,用QTableView更好。

00.废话

一般情况下QListView中的元素可以用

QStandardItemModel *pModel = new QStandardItemModel();
QStandardItem *pItem = new QStandardItem;

这两个方法搞OK。

但是如果要使用比较特殊一点的Custom 显示效果,就需要设置ListView的

QStyledItemDelegate  //就是这个鬼玩意,新建一个C艹 Class具体的内容下面有。

其中 QStyledItemDelegate类主要用在model-view的编辑上,调用

paint  方法 方法啥样,看下面

 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;

进行渲染。因此可以通过重写paint函数就可以实现自定义数据。

01.Delegate怎么写

1.不可或缺的事情

定义 Model 例如:

typedef struct {
    QString name;
    QString type ;
    QString package;
    QString positionString;
    QString lc_code ;
    QString serial ;
    QString pic_url ;
    QString created_at ;
    QString updated_at ;
} MuItemData;

Q_DECLARE_METATYPE(MuItemData)  //必不可少(少了完犊子)

可以放在Delegate.h的前面,当然也可以单独放置

2.写.h文件(名称可以自定义,但是必须是继承QStyledItemDelegate)

class MyItemDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
    MyItemDelegate(QListView *parent = nullptr);

    virtual ~MyItemDelegate();
    //paint函数就是绘制用耳朵
    void paint(QPainter *painter,
               const QStyleOptionViewItem &option,
               const QModelIndex &index) const override;
    //sizeHint 可以改变item的大小
    QSize sizeHint(const QStyleOptionViewItem &option,
                   const QModelIndex &index) const override;
};

以下方法也都可以用哦。具体使用参考QT官网:戳我看文档 

virtual QWidget *	createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
virtual void	paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
virtual void	setEditorData(QWidget *editor, const QModelIndex &index) const override
virtual void	setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
virtual QSize	sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
virtual void	updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override

 3.写.cpp文件

paint在这里,sizeHint在下面

void ResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.isValid()) {
        QStyleOptionViewItem  viewOption(option);

     
        if (viewOption.state & QStyle::State_HasFocus) {
            viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
        }
        painter->save();
        QVariant var = index.data(Qt::UserRole+1);
        MuItemData itemData = var.value<MuItemData>();

        //这里是绘制item 矩形区域
        QRectF rect;
        rect.setX(option.rect.x()); //根据option的大小绘制
        rect.setY(option.rect.y());
        rect.setWidth(option.rect.width()-1);
        rect.setHeight(option.rect.height()-1);

        QPainterPath path;
        path.moveTo(rect.topRight());
        path.lineTo(rect.topLeft());
        path.quadTo(rect.topLeft(), rect.topLeft());
        path.lineTo(rect.bottomLeft());
        path.quadTo(rect.bottomLeft(), rect.bottomLeft());
        path.lineTo(rect.bottomRight());
        path.quadTo(rect.bottomRight(), rect.bottomRight());
        path.lineTo(rect.topRight());
        path.quadTo(rect.topRight(), rect.topRight());

        // 鼠标悬停、选中、单双行改变背景色
        if (option.state.testFlag(QStyle::State_MouseOver)) {
            painter->setPen(QPen(QColor::fromRgb(229,229,229,255)));
            painter->setBrush(QColor::fromRgb(229,229,229,255));
            painter->drawRoundedRect(rect,border_radius,border_radius);
        }else if (option.state.testFlag(QStyle::State_Selected)) {
            painter->setPen(QPen(QColor("#e4f0ff")));
            painter->setBrush(QColor("#e4f0ff"));
            painter->drawRoundedRect(rect,border_radius,border_radius);
        }else if (index.row()%2 ==0){
            painter->setPen(QPen(QColor::fromRgb(242,242,242,255)));
            painter->setBrush(QColor::fromRgb(242,242,242,255));
            painter->drawRoundedRect(rect,border_radius,border_radius);
        }else{
            painter->setPen(QPen(QColor::fromRgb(250,250,250,255)));
            painter->setBrush(QColor::fromRgb(250,250,250,255));
            painter->drawRoundedRect(rect,border_radius,border_radius);
        }

        //各项数据的放置区域区域、明显可以看出是一项跟着一项
        QRectF id = QRect(rect.left() + 5, rect.top() + 5, 40, 40);
        QRectF LCCode = QRect(id.right() + 10, id.top(), rect.width() /7, 20);
        QRectF Name = QRect(LCCode.right() + 10, id.top(), rect.width() /7, 20);
        QRectF package = QRect(Name.right() + 50, id.top(), rect.width() /7-40, 20);
        QRectF type = QRect(package.right() + 10, id.top(), rect.width() /7, 20);
        QRectF serial = QRect(type.right() + 10, id.top(), rect.width() /7, 20);
        QRectF positionString = QRect(serial.right() + 20, id.top(), rect.width() /7, 20);


        painter->setPen(QPen(QColor::fromRgb(204,204,204,255)));
        painter->setFont(QFont("丁卯点阵体 9px", 10));
        painter->drawText(id, QString::number(index.row() + 1));


        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("丁卯点阵体 9px", 10));
        painter->drawText(Name, itemData.name);

        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("丁卯点阵体 9px", 10));
        painter->drawText(LCCode, itemData.lc_code);

        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("丁卯点阵体 9px", 10));
        painter->drawText(package, itemData.package);

        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("丁卯点阵体 9px", 10));
        painter->drawText(type, itemData.type);

        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("丁卯点阵体 9px", 10));
        painter->drawText(serial, itemData.serial);

        painter->setPen(QPen(Qt::black));
        painter->setFont(QFont("丁卯点阵体 9px", 10));
        painter->drawText(positionString, itemData.positionString);
        painter->restore();
    }

}

sizeHint在这里

QSize ResultDelegate::sizeHint(const QStyleOptionViewItem& option,
                               const QModelIndex& index) const {
    Q_UNUSED(index)
    return QSize(option.rect.width(), 30);
}

02.这个鬼玩意怎么使用

1.如果你是UI生成

1、首先在UI界面拖一个出来:

2、拖到你想要去的地方

3、撸代码

QStandardItemModel *pModel = new QStandardItemModel();
    for (int i=0; i<55; ++i) {
        QStandardItem *pItem = new QStandardItem;
        MuItemData itemData; //在这里是用你定义的模型
        itemData.name = "10nF ±10% 50V";
        itemData.package = "0603";
        itemData.lc_code = "C386151";
        itemData.positionString = "cab_A_16";
        itemData.serial = "UMK107B103KAHT";
        itemData.type = "贴片电容(MLCC)";
        itemData.pic_url ="https://alimg.szlcsc.com/upload/public/product/breviary/20230109/37C066B076EAB09E57A5A7BEB01242BA.jpg";
        pItem->setData(QVariant::fromValue(itemData), Qt::UserRole+1);
        pModel->appendRow(pItem);
    }
    ResultDelegate *pItemDelegate = new ResultDelegate(this);
    ui->listView->setItemDelegate(pItemDelegate);

 4、即可使用、特殊需求往下看、但是跳过下面一句话。

 2.如果你是代码生成,New完按照上面的配置即可。然后添加到子视图

3、特殊需求的实现 

1.改绘制的颜色

在paint函数中最后的没有IF的那个改颜色就是。

2.为啥我悬停在item上没有变色,是不是BUG?

不是,需要加入代码

ui->listView->viewport()->setAttribute(Qt::WA_Hover);

3.为啥我的QListview旁边出现了滑动条??如何隐藏滑动条,如何禁用滑动条?

因为你的数据量比较大,条数*item高度 > view的miniheight,所以出现了滑动条;

如果只是不想看到滑动条:

ui->listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

上述代码使用后只是看不见,但是!!里面一样可以通过鼠标中间滚轮滑动!!! 

如果想禁用滑动条:

ui->listView->verticalScrollBar()->setDisabled(true);

俩可以同时使用;

注意:禁用和不想看到不代表他会显示完整,一样会显示不完整。

4、我不想出现进度条,我就想完整显示!自动适应高度!

  ui->listView->setMinimumHeight(你item的高度 * (pModel->rowCount()+1));

使用此代码即可,但是,注意!可能会超出边际!

5、我想像网易云那样,上面的组件和QListView,整体可以下滑。

  (你在说啥?看例子)

举个栗子

         思路:

         底层scrollArea>自动嵌套scrollAreaWidgetContents>里面塞各种组件+ListView

        (scrollAreaWidgetContents里 切记使用布局,否则无法使用)

         关键代码:

ui->scrollAreaWidgetContents->setMinimumHeight(65 * pModel->rowCount() + 20);

 此代码作用就是把scrollAreaWidgetContents放大容得下第四点中的自适应高度的ListView。

记得和搭配第四点的一起食用,否则无效;

实现就是这样的
​​​​​​

 

后记:

Qt的资料太少、还需要多摸索。

环境:QT 5.15.2

推荐使用CLion

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值