注:Model/View架构使用要继承QStyledItemDelegate 类,类型选择为Widget;
数据项中:Item;
每个Item可以关联多个数据,每个数据用一个role(角色,任务)来作为标识;
Qt:Display Role(0):一般对应一个字符串,用于显示。
Qt:User Role(32)自定义数据;
Model/View框架的核心思想是模型(数据)与视图(显示)相分离,模型对外提供标准接口存取数据,不关心数据如何显示,视图自定义数据的显示方式,不关心数据如何组织存储。
Model/View框架中数据与显示的分离,可以允许使用不同界面显示同一数据,也能够在不改变数据的情况下添加新的显示界面。为了处理用户输入,引入了委托(delegate)。引入委托的好处是可以自定义数据项的渲染和编辑。
头文件:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QListWidget>
#include <QListWidgetItem>
#include "myitemdrawer.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public:
void Additem(QString name,QString phone,bool male);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
myitemdrawer.h
(继承QStyledItemDelegate 类,类型选择为Widget)
#ifndef MYITEMDRAWER_H
#define MYITEMDRAWER_H
#include <QStyledItemDelegate>
#include <QRect>
#include <QPainter>
#include <QSize>
#include <QIcon>
#include <QPixmap>
class MyItemDrawer : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit MyItemDrawer(QObject *parent = 0);
public:
//单元格的大小设置
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const;
//绘图
void paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
signals:
public slots:
private:
QPixmap m_man,m_woman;
};
#endif // MYITEMDRAWER_H
源文件:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Additem("小芳","18390274819",false);
Additem("小薇","18789057193",false);
Additem("小强","137182904672",true);
Additem("小刚","17890367839",true);
//使用自定义的代理绘图
ui->listWidget->setItemDelegate(new MyItemDrawer(ui->listWidget));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Additem(QString name, QString phone, bool male)
{
QListWidgetItem *item = new QListWidgetItem;
item->setData(Qt::DisplayRole,name);
item->setData(Qt::UserRole,phone);
item->setData(Qt::UserRole+1,male);
ui->listWidget->addItem(item);
}
myitemdrawer.cpp
#include "myitemdrawer.h"
MyItemDrawer::MyItemDrawer(QObject *parent) :
QStyledItemDelegate(parent),
m_man("D:/QT_Library/Model_Vile_LianXi/icon/man.png"),
m_woman("D:/QT_Library/Model_Vile_LianXi/icon/woman.png")
{
}
QSize MyItemDrawer::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QSize size = QStyledItemDelegate::sizeHint(option,index);
size.setHeight(40);
return size;
}
void MyItemDrawer::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QRect rect = option.rect; //目标矩形
rect.adjust(2,2,-2,-2); //调整大小,留出空白区
// 取得代理项对应的数据
QString name = index.data(Qt::DisplayRole).toString();
QString phone = index.data(Qt::UserRole).toString();
bool male = index.data(Qt::UserRole+1).toBool();
// 该项被选中时的状态显示
if(option.state & QStyle::State_Selected)
{
painter->setBrush(QColor(0xCC,0xAA,0xAA));
painter->drawRoundedRect(rect,2,2);
}
//性别显示
if(1)
{
QRect dest = rect;
dest.setRight(rect.left()+40);
QRect area(0,0,24,24);
area.moveCenter(dest.center());
painter->drawPixmap(area,male?m_man:m_woman);
}
//名称显示
if(1)
{
QRect dest = rect;
dest.setLeft(rect.left()+40);
dest.setBottom(rect.top()+20);
painter->drawText(dest,Qt::AlignLeft | Qt::AlignVCenter,name);
}
//phone显示
if(1)
{
QRect dest = rect;
dest.setLeft(rect.left() +40);
dest.setTop(rect.top()+20);
painter->drawText(dest,Qt::AlignLeft | Qt::AlignVCenter,phone);
}
}
界面设计:(ListWidget)
运行效果: