QListView实现自定义的控件展示(可以根据选中与否置顶展示)
创始人
2024-11-16 05:04:32

文章目录

  • 0 问题引入
  • 1、方案1:使用QListwidget+自定义的widget
    • 1.1 效果
    • 1.1 思路
  • 2、方案2:使用QListView+自定义model+自定义delegate
    • 2.1.浅谈
    • 2.2.实现
  • 3、总结
  • 4、引用


在这里插入图片描述

0 问题引入

在这里插入图片描述

问题:有人问我如何实现上图的功能,当时我脑海里有了Qlistwidget+自定义litem不就搞定了吗,可是还有选中排序功能,还有可能该列表有上百项(性能问题),该如何解决?实际在探索中还是有点小困难。


1、方案1:使用QListwidget+自定义的widget

看效果:
在这里插入图片描述

1.1 效果

1、实现上图类似的每一行展示的数据
2、点击选中的某一行之后会跳转到最前端
3、未选中的直接放在最后面
基本上满足条件,但是还存在看不见的弊端
1、上述的选中展示到最前端实际上是无奈之举,把那一行删除,然后再最前端插入,这样会导致再实时刷新数据的时候可能会崩溃(虽然也没有)
2、再上百上千条数据的时候有一点慢(虽然也能接收)
3、我想达到的效果是只移动,不删除。

1.1 思路

1、插入一行代码

   QListWidgetItem *pItem = new QListWidgetItem("");     //新增加一个item    SWidget *sitem = new SlistItem(pItem,name,ischeck);   // SWidget 是自定义的控件,就是每一                                                                   //行的效果:一个checkbox+若干个label    listvew->addItem(pItem);    listvew->setItemWidget(pItem,sitem); 

2、实现选中之后到最前端,未选中到最后端:
思路是首先删除改行,然后获取改行的信息,重新new一个item和widget再插入到你想去的位置
引用1文章那样的思路是在删除item的widget保存一份,这个在我这里行不通,必须重新建立,可能是自定义的类型无法转换的问题。


2、方案2:使用QListView+自定义model+自定义delegate

2.1.浅谈

之前用过Qlisttabel的时候遇到过大量数据同时展示的时候,那时候就重新了model类,才勉强接住那个数据刷新,其实一般的速度,原生的就已经够用了。引用文章2里提出的是大致思路。

QListView *listview = new QListView(this);       //创建QListView对象 listview->setGeometry(50, 20, 100, 200);         //设置位置和大小  QStringList list;                                //创建数据显示列表 list.append("苹果"); list.append("香蕉"); list.append("桃子");  //使用数据列表创建数据显示模型 QStringListModel *listmodel = new QStringListModel(list); listview->setModel(listmodel);                   //设置模型到listview上  listview->setMovement(QListView::Free);          //设置数据可以自由拖动 listview->setSpacing(2);                         //设置数据的间距  

2.2.实现

listview使用自定义的model和delegat额也很简单。
伪代码如下(示例):

    listview = new QListView(this);     model = new CustomListModel();     delegate = new CustomDelegate();     listview ->setModel(model);     listview ->setItemDelegate(delegate); 

需要注意的是(根据官网,需要继承QAbstractListModel与以及实现必要的函数)

class CustomListModel : public QAbstractListModel {      ///必须实现的函数,可以看官方手册,很详细     int rowCount(const QModelIndex &parent) const;     QVariant data(const QModelIndex &index, int role) const;     bool setData(const QModelIndex &index, const QVariant &value, int role);  };  class CustomDelegate : public QStyledItemDelegate {     //描绘画面显示     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex                   &index) const;     //处理鼠标事件     bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem                       &option, const QModelIndex &index); }; 

具体代码不展示了,思路就是这样。代码可以参考引用中的3和4.


3、总结

上述两种方法都没有问题,在实际过程中第二种方法显得麻烦一点,主要是paint函数要把自定义控件给画出来(需要时间和耐心),然后可以根据自己苏旭去渲染,确实提高一些效率,所以酌情去使用,后来我还是使用第一种办法,优化了一些逻辑也是很好的实现效果。


4、引用

1、QListWidget添加自定义Widget后移动Item问题和方法
2、深入浅出 Qt 中 QListView 的设计思想,并掌握大规模、高性能列表的实现方法
3、QListView 自定义delegate和model, 添加checkbox、按钮、文本
4、QListView 使用Delegate定制


相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...