[Share Experiences] 参考当年王勇做的DTK列表搞了个新的~
Tofloor
poster avatar
Maicss
deepin
2021-12-24 06:34
Author

首先是王勇老师写的博客:https://www.jianshu.com/p/7cae18e66c70

在这篇博客中,我理解了DTK的列表实现的思路以及解决的问题,简而言之就是自己控制列表项的绘制,从而实现随心所欲的在列表项中显示任何东西。

为什么要再再重新造一个ListView控件?

虽然DTK这个方案已经非常好了,但若想要实现的列表非常简单,且还要想使用这个方案,还要通过继承的方式定义两个类(View和Item),多少有点麻烦,因此我希望能实现一种可以直接使用的列表控件,但也要保留自由绘制的优势。

思路

定义两个类,分别是View和Item,Item用于存储数据和指导绘制,View用于控制Item的尺寸,并将其以列表的形式实际绘制出来。

设计Item类

Item首先需要让其存储数据,由于数据的类型可能是多样的,因此我使用了C++的模板机制来将其定义为一个模板类。然后设置一个模板数据类型的成员变量,用作存储。

另外Item还需要指导绘制,这个我使用了函数指针去实现,可以通过设置该函数指针来设置绘制函数,然后再由View类对其调用,这样我们就可以控制绘制事件了。

设计View类

该类中需要存储一个Item类对象的列表,这部分使用QList实现。

然后在该函数的绘制函数中去逐个调用所有Item函数指针指向的绘制函数,这样就将列表显示出来了。

然后作为列表它还应该具有最基本的如滚动、选择的功能,这不是重点因此不多赘述。

调用

根据上述思路实现后,给大家展示最简单的使用:


#include "MainWindow.h"
#include "MListView.h"
#include "MListViewItem.h"

MainWindow::MainWindow() {
    //创建一个变量
    auto *listView = new MListView;
    //设置列表项的高度为50
    listView->setItemHeight(50);
    //将列表添加到主窗口中显示
    setCentralWidget(listView);
    //在列表中添加40个列表项
    for(int i =0 ;i <40;i++){
        //创建列表项的对象,内部存储的数据类型选用QString,这里必须使用指针
        auto *item = new MListViewItem;
        //用于存储数据的指针
        auto *data = new QString (QString("列表项 %1").arg(i));
        item->setData(data);
        //绑定绘制函数,用于定义列表项是如何绘制的
        item->setHowToPaint([](MListViewItemData::PaintFrontEvent event,QString* data){
            //根据列表项号绘制斑马线的底色
            if(event.number%2 == 0)
                event.painter->fillRect(event.rect,QColor("#FFFFFF"));
            else
                event.painter->fillRect(event.rect,QColor("#DDDDDD"));
            //垂直居中绘制文本
            event.painter->setPen(QColor(0,0,0));
            QFont font;
            font.setPointSize(20);
            event.painter->setFont(font);
            event.painter->drawText(event.rect.left()+10,event.rect.top()+event.rect.height()/2+font.pointSize()/2,*data);
        });
        //将列表项添加到列表中
        listView->addItem((ITEM_DATA_PTR)item);
        //这里的 ITEM_DATA_PTR 宏为MListViewItem*,void*用于存储任意类型的指针,并在需要时强转。
    }
}

效果:

image.png

wolai链接:https://www.wolai.com/3GnuxKHAGXr7hrDEoxESNG

Reply Favorite View the author
All Replies
Rubbish
deepin
2021-12-24 07:01
#1

tail

C++写UI好复杂,还是qml简单,qml的listview按照文档可以直接拿任意component作为列表元素显示

Reply View the author
BG7ZAG
deepin
2021-12-24 17:39
#2

👍

Reply View the author
盘灶车站
deepin
2021-12-24 17:42
#3

2016年,在上海华师大和王勇见了一面,当时有五十多人的现场,王勇当众说他的偶像是唐凤。

万没想到,老王也有翻车的时候,现在这个东方不败,在国际上上蹿下跳,已经比臭虫还臭了。

估计老王也得后悔吧。

Reply View the author
element
deepin
2021-12-24 23:14
#4

有机会可以尝试一下老王以前的Dtalk?

Reply View the author