Qt实现类似QQ好友列表

思路

做个类似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

你可能感兴趣的:(QT)