Qt实现类似QQ好友列表

来源:互联网 发布:如何防范网络诈骗ppt 编辑:程序博客网 时间:2024/05/16 07:00

思路

做个类似QQ好友列表的控件。
网上查询到的思路:

  1. 利用一组一组的QToolButton的来实现。

  2. 采用QLisview和QTreeView实现。通过代理来设置每一个项的样子。

  3. 采用QListWidget,然后通过setItemWidget来实现。

考虑后才用第二种方式,第一种方式实现起来样式不好设置,第三种widget太多,对系统资源占用比较大。每一个组用一个QToolButton和一个QListView来表示,QListView用delegate来设置样子。列表的展开和收缩,通过QListView的hide函数来实现。

实现

listView

关于Model View delegate自定义列表的文章可以参考:如何使用Model View delegate自定义列表

一个只读的delegate

只需要实现继承QStyledItemDelegate的GroupListViewDelegate其中的paint和sizeHint就可以了。paint用来绘制item的样子,sizeHint用来设置行高。

void GroupListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{    const QPixmap &pixmap = qvariant_cast<QPixmap>(index.data(Qt::UserRole + 1));    QRect pixmapRect = QRect(option.rect.topLeft(), QSize(50, 50));    const QString &str = index.data(Qt::UserRole).toString();    QFontMetrics font(painter->fontMetrics());    QRect diplayRect = QRect(pixmapRect.topRight() + QPoint(20, 25), QSize(font.width(str), font.height()));    painter->drawPixmap(pixmapRect, pixmap);    painter->drawText(diplayRect, str);}QSize GroupListViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const{    return QSize(option.rect.width(), 50);}

更新后台数据的model

继承QAbstractListModel的GroupListViewModel中,我们实现一个rowCount的函数来返回Item的列数,实现一个data的函数来给listview或delegate来提供各种图片或数据。

int GroupListViewModel::rowCount(const QModelIndex &/*parent*/) const{    return m_patients.count();}  QVariant GroupListViewModel::data(const QModelIndex &index, int role) const{    if(!index.isValid() || (index.row() > m_patients.count())) {        return QVariant();    }    if(role == Qt::UserRole) {        return m_patients.at(index.row()).name();    } if(role == Qt::UserRole + 1) {        QString localPath = ":/mainface/default_head";        QString id = m_patients.at(index.row()).id();        if(m_pixmapMap.contains(id)) {            localPath = m_pixmapMap.value(id);        }        QPixmap pixmap;        pixmap.load(localPath);        return pixmap.scaled(QSize(50, 50), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);    } else if(role == Qt::UserRole + 2) {        return m_patients.at(index.row()).id();    }    return QVariant();}

model中用一个QList m_patients来保存主要的信息。通过对List的数据的操作来更新model的数据。

到此,ListView后面只需要实现一个删除联系人和移动联系人的事件。listView的大部分功能就实现。对于每组点击栏,我们可以用一个QToolButton来放箭头图片,用一个QPushButton来存放组名字,绑定二者的点击事件,并且通过点击事件后来设置图片切换箭头的样子,并发出信号控制ListView的隐藏或者显示。

代码实现:http://download.csdn.net/detail/lwei3600103/9584766

参考资料

1,http://blog.sina.com.cn/s/blog_a6fb6cc90102v7qb.html
2,http://blog.csdn.net/feiyangyangfei/article/details/8504043

0 0