由于QListWidget的子项都是单列的.所以能显示的不太多,但是如果使用listWidget->setItemWidget();方法的话,内存的开销又有点大.所以有一些信息可以用画的方式绘图出来,先看下简单的效果:
像QListWidget,QTableWidget这些都属于视图类.默认都带有基础的Delegate.当我们想要给视图的子项更多种的显示方式的话,子类化QStyledItemDelegate或QItemDelegate都可以,下面以子类化QStyledItemDelegate做例子:
#ifndef MYITEMDELEGATE_H
#define MYITEMDELEGATE_H
#include
#include
//子类化的委托类.
class MyItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MyItemDelegate(QWidget *parent);
~MyItemDelegate();
protected:
//重写这两个虚函数.注意: const不要忘,否则不属于虚函数的重写.
virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const;
virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
private:
};
#endif // MYITEMDELEGATE_H
#include "MyItemDelegate.h"
MyItemDelegate::MyItemDelegate(QWidget *parent)
: QStyledItemDelegate(parent)
{
}
MyItemDelegate::~MyItemDelegate()
{
}
//需要重写调整的尺寸的方法.注意:调整的是子项的尺寸.
QSize MyItemDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
//获得原来的视图参数.
QSize size = QStyledItemDelegate::sizeHint(option, index);
size.setHeight(80);
return size;
}
void MyItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
//返回项的矩形边框.
QRect rect = option.rect;
//当项被选中时.
if (option.state & QStyle::State_Selected)
{
painter->setBrush(Qt::cyan);
painter->drawRect(rect);
}
//获取项的数据.
QString name = index.data(Qt::DisplayRole).toString();
QString phone = index.data(Qt::UserRole).toString();
QString address = index.data(Qt::UserRole + 1).toString();
//画名字.
painter->drawText(rect.topLeft() + QPoint(20, 20), QString::fromLocal8Bit("姓名:%1").arg(name));
//画电话.
painter->drawText(rect.topLeft() + QPoint(20, 40), QString::fromLocal8Bit("电话:%1").arg(phone));
//画地址.
painter->drawText(rect.topLeft() + QPoint(20, 60), QString::fromLocal8Bit("地址:%1").arg(address));
}
#include "c.h"
c::c(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_precRow = -1;
//先加入四个数据项.
addItem("test1", "100000000000",QString::fromLocal8Bit("北京"));
addItem("test2", "100000000001", QString::fromLocal8Bit("杭州"));
addItem("test3", "100000000002", QString::fromLocal8Bit("厦门"));
addItem("test4", "100000000003", QString::fromLocal8Bit("上海"));
//当项被点击时发出的信号.
connect(ui.listWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(detailDisplaySlot(QListWidgetItem*)));
}
c::~c()
{
}
void c::addItem(QString name, QString phone, QString address)
{
//创建项.
QListWidgetItem *item = new QListWidgetItem();
//设置项的数据.
item->setData(Qt::DisplayRole,name);
item->setData(Qt::UserRole, phone);
item->setData(Qt::UserRole + 1, address);
//设置项的尺寸.
item->setSizeHint(QSize(ui.listWidget->width(),40));
ui.listWidget->addItem(item);
}
void c::detailDisplaySlot(QListWidgetItem* item)
{
//当点击项改变时,之前的项的委托情况需要改变.还要改变尺寸.
if (m_precRow >= 0)
{
ui.listWidget->setItemDelegateForRow(m_precRow, new QStyledItemDelegate());
ui.listWidget->item(m_precRow)->setSizeHint(QSize(ui.listWidget->width(), 40));
}
//获取点击项的行数.
m_precRow = ui.listWidget->row(item);
//设置点击项的当前行使用自己定义的委托.
ui.listWidget->setItemDelegateForRow(ui.listWidget->row(item), new MyItemDelegate(ui.listWidget));
//重新设置大小.
ui.listWidget->item(m_precRow)->setSizeHint(QSize(ui.listWidget->size().width(),80));
}
#ifndef C_H
#define C_H
#include
#include "ui_c.h"
#include "MyItemDelegate.h"
class c : public QWidget
{
Q_OBJECT
public:
c(QWidget *parent = 0);
~c();
void addItem(QString,QString,QString);
private slots:
void detailDisplaySlot(QListWidgetItem*);
private:
Ui::cClass ui;
int m_precRow = -1;
};
#endif // C_H
这样一来就大功告成了,当然listWidget->setItemWidget();方法也可以实现这样的场景,但是如果子项的数目一旦非常的话,对内存的开销是很大的!