-
转载地址:http://www.2cto.com/kf/201412/362329.html
-
提要
最近想要完成的一个项目需要显示一个列表,可以动态增减,可编辑,有checkbox。类似于这样
或者这样
但网上的例子都是这样
和这样
...
最后实现的效果:
QListWidget解决方案
在Android实现这样的列表是非常简单的,首先定义布局XML,然后再定义一个Adapter就可以了。
Qt中类似的解决方案就是QListWidget。
自定义一个Widget类作为Item,比如
1234567891011121314151617181920class
UsersListItem :
public
QWidget
{
Q_OBJECT
public
:
explicit UsersListItem(QWidget *parent =
0
);
virtual QSize sizeHint()
const
{
return
QSize(
100
,
48
);
}
private
:
QLabel * m_labAddress;
QLabel * m_labHeaderPic;
QLabel * m_labUser;
signals:
public
slots:
};
然后用
void QListWidget::setItemWidget ( QListWidgetItem * item, QWidget * widget )
将widget作为item显示。
这种方法最为简单,但是仔细看下官网的函数说明....
This function should only be used to display static content in the place of a list widget item. If you want to display custom dynamic content or implement a custom editor widget, use QListView and subclass QItemDelegate instead.
只能用来显示静态数据,如果要显示动态数据,请使用QListView和QItemDelegate。
自定义Model自定义View 自定义Delegate
首先要明白这几个东西的概念和关系
与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件。一般来讲, view负责把数据展示给用户,也处理用户的输入。为了获得更多的灵性性,交互通过delegagte执行。它既提供输入功能又负责渲染view中的每个数据项。
使用Delegate的原因 Qt中当用到QTreeView和QTableView等用于显示item的视图时,你要编辑一个item用到的编辑工具可能是除了默认文字编辑lineEdit以外的工具,例如button,spinBox,甚至Slider,ProgressBar,也有可能是自定义的widget。所以Qt提供了一个委托类,用来处理View中的数据展示方式。Qt提供的标准views都使用QItemDelegate的实例来提供编辑功能。它以普通的风格来为每个标准view渲染数据项。这些标准的views包括:QListView,QTableView,QTreeView。所有标准的角色都通过标准views包含的缺省delegate进行处理。一个view使用的delegate可以用itemDelegate()函数取得,而setItemDelegate() 函数可以安装一个定制delegate。
简单的说就是需要自己实现的东西变多了,但是可以定制的地方也就多了。下面主要是贴代码,慎入!首先是model,
layertablemodel.h
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657#ifndef LAYERLISTMODEL_H
#define LAYERLISTMODEL_H
#include <qabstracttablemodel>
#include <qstringlist>
#include <qlist>
#include <qpixmap>
#include <qimage>
#include <qicon>
#include <qdebug>
#include <qitemselectionmodel>
class
LayerTableModel :
public
QAbstractTableModel
{
Q_OBJECT
public
:
LayerTableModel(QObject *parent =
0
);
~LayerTableModel();
int
rowCount(
const
QModelIndex &parent)
const
;
int
columnCount(
const
QModelIndex &parent)
const
;
QVariant data(
const
QModelIndex &index,
int
role)
const
;
QVariant headerData(
int
section,
Qt::Orientation orientation,
int
role = Qt::DisplayRole)
const
;
Qt::ItemFlags flags(
const
QModelIndex &index)
const
;
bool setData(
const
QModelIndex &index,
const
QVariant &value,
int
role);
void
deleteItem(
int
index);
void
addItem(QString &layerName, QImage &thumbnail, bool isShow =
true
);
void
refreshModel();
QModelIndex& selecttedIndex(
int
row);
void
setSelecttedRow(
int
row);
int
getSelecttedRow()
const
;
public
slots:
void
changeLayerVisibility(
const
QModelIndex&);
private
:
struct LayerItem
{
QString layerName;
QImage thumbnail;
float
transparence;
bool isShow;
};
QList<layeritem> layerList;
int
selectedRow;
};
#endif
// LAYERLISTMODEL_H
</layeritem></qitemselectionmodel></qdebug></qicon></qimage></qpixmap></qlist></qstringlist></qabstracttablemodel>
layertablemodel.cpp
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173#include layertablemodel.h
LayerTableModel::LayerTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
QImage image(images\sample.jpg);
layerList.reserve(
3
);
selectedRow =
0
;
for
(
int
i =
0
; i <
3
; i++)
{
addItem(QString(), image,
true
);
}
}
LayerTableModel::~LayerTableModel()
{
}
QVariant LayerTableModel::data(
const
QModelIndex &index,
int
role)
const
{
if
(!index.isValid())
return
QVariant();
int
column = index.column();
if
(column ==
0
)
{
if
(role == Qt::CheckStateRole)
{
return
layerList.at(index.row()).isShow ? Qt::Checked : Qt::Unchecked;
}
if
(role == Qt::SizeHintRole)
{
return
QSize(
20
,
50
);
}
}
else
{
if
(role == Qt::EditRole)
{
return
QVariant(layerList.at(index.row()).layerName);
}
if
(role == Qt::DisplayRole)
{
return
QVariant(layerList.at(index.row()).layerName);
}
if
(role == Qt::DecorationRole)
{
if
(layerList.at(index.row()).thumbnail.isNull())
{
return
layerList.at(index.row()).thumbnail;
}
else
{
return
layerList.at(index.row()).thumbnail.scaledToHeight(
40
);
}
}
if
(role == Qt::SizeHintRole)
{
return
QSize(
200
,
50
);
}
if
(role == Qt::TextAlignmentRole)
{
return
int
(Qt::AlignVCenter);
}
}
return
QVariant();
}
int
LayerTableModel::rowCount(
const
QModelIndex &parent)
const
{
return
(parent.isValid() && parent.column() !=
0
) ?
0
: layerList.size();
}
int
LayerTableModel::columnCount(
const
QModelIndex &parent)
const
{
Q_UNUSED(parent);
return
2
;
}
QVariant LayerTableModel::headerData(
int
section, Qt::Orientation orientation,
int
role)
const
{
if
(role == Qt::DisplayRole)
return
QString::number(section);
//if (role == Qt::DecorationRole)
//return QVariant::fromValue(services);
return
QAbstractItemModel::headerData(section, orientation, role);
}
Qt::ItemFlags LayerTableModel::flags(
const
QModelIndex &index)
const
{
if
(!index.isValid())
return
0
;
if
(index.column() ==
0
)
return
Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
return
Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}
bool LayerTableModel::setData(
const
QModelIndex &index,
const
QVariant &value,
int
role)
{
if
(!index.isValid())
{
return
false
;
}
if
(role == Qt::CheckStateRole && value.type() == QVariant::Bool)
{
layerList[index.row()].isShow = value.toBool();
emit(dataChanged(index, index));
return
true
;
}
if
(role == Qt::EditRole && index.column() ==
1
)
{
layerList[index.row()].layerName = value.toString();
emit(dataChanged(index, index));
return
true
;
}
return
false
;;
}
void
LayerTableModel::changeLayerVisibility(
const
QModelIndex& index)
{
if
(index.isValid()&&index.column() ==
0
)
{
setData(index, !(layerList.at(index.row()).isShow), Qt::CheckStateRole);
}
}
void
LayerTableModel::deleteItem(
int
index)
{
QList<layeritem>::iterator it = layerList.begin();
layerList.erase(it + index);
}
void
LayerTableModel::addItem(QString &name, QImage &thumb, bool show)
{
LayerItem item;
if
(name.size() ==
0
)
{
item.layerName = QString(Layer ) + QString::number(layerList.size());
}
else
{
item.layerName = name;
}
item.isShow = show;
item.thumbnail = thumb;
layerList.append(item);
//this->insertRow()
//emit(dataChanged(index, index));
qDebug()<<layerlist.size(); emit=
""
this
-=
""
void
=
""
>rowCount(QModelIndex()));
}
QModelIndex& LayerTableModel::selecttedIndex(
int
row)
{
return
this
->createIndex(row,
1
);
}
void
LayerTableModel::setSelecttedRow(
int
row)
{
selectedRow = row;
}
int
LayerTableModel::getSelecttedRow()
const
{
return
selectedRow;
}
</layerlist.size();></layeritem>
然后是delegate
layeritemdelegate.h
123456789101112131415161718192021222324252627282930313233343536#ifndef LAYERITEMDELEGATE_H
#define LAYERITEMDELEGATE_H
#include <qstyleditemdelegate>
#include <qlineedit>
#include <qdebug>
#include <qpainter>
class
LayerItemDelegate :
public
QStyledItemDelegate
{
Q_OBJECT
public
:
LayerItemDelegate(QObject *parent=
0
);
~LayerItemDelegate();
void
paint(QPainter * painter,
const
QStyleOptionViewItem & option,
const
QModelIndex & index)
const
;
QWidget *createEditor(QWidget *parent,
const
QStyleOptionViewItem &option,
const
QModelIndex &index)
const
;
bool editorEvent(QEvent * event,
QAbstractItemModel * model,
const
QStyleOptionViewItem & option,
const
QModelIndex & index);
void
setEditorData(QWidget *editor,
const
QModelIndex &index)
const
;
void
setModelData(QWidget *editor, QAbstractItemModel *model,
const
QModelIndex &index)
const
;
void
updateEditorGeometry(QWidget *editor,
const
QStyleOptionViewItem &option,
const
QModelIndex &index)
const
;
private
:
QPixmap m_gridPixmap;
};
#endif
// LAYERITEMDELEGATE_H
</qpainter></qdebug></qlineedit></qstyleditemdelegate>
layeritemdelegate.cpp
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117#include layeritemdelegate.h
LayerItemDelegate::LayerItemDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
QImage gridImage(
200
,
200
, QImage::Format_RGB32);
QRgb grey = QColor(
204
,
204
,
204
).rgb();
QRgb white = QColor(
255
,
255
,
255
).rgb();
for
(
int
i =
0
; i <
200
; i++)
for
(
int
j =
0
; j <
200
; j++)
{
int
tmpX = i %
10
;
int
tmpY = j %
10
;
if
(tmpX <
5
)
{
gridImage.setPixel(i, j, tmpY <
5
? grey : white);
}
else
{
gridImage.setPixel(i, j, tmpY <
5
? white : grey);
}
}
m_gridPixmap = QPixmap::fromImage(gridImage);
}
LayerItemDelegate::~LayerItemDelegate()
{
}
void
LayerItemDelegate::paint(QPainter * painter,
const
QStyleOptionViewItem & option,
const
QModelIndex & index)
const
{
if
(index.column() ==
1
)
// value column
{
if
(option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
QImage image = qvariant_cast<qimage>(index.data(Qt::DecorationRole));
//QImage image = index.model()->data(index, Qt::DecorationRole).toString();
QRect rect = option.rect;
int
x = rect.x() +
10
;
int
y = rect.y() +
5
;
QBrush brush;
//Draw grid background
brush.setTexture(m_gridPixmap);
painter->fillRect(x, y,
40
,
40
, brush);
//Draw image
painter->drawImage(x, y, image);
QRect textRect(rect.x() +
60
, rect.y(), rect.width() -
60
, rect.height());
QString layerName = index.model()->data(index, Qt::DisplayRole).toString();
QTextOption textOption = Qt::AlignLeft | Qt::AlignVCenter;
painter->drawText(textRect, layerName, textOption);
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
}
bool LayerItemDelegate::editorEvent(QEvent * event,
QAbstractItemModel * model,
const
QStyleOptionViewItem & option,
const
QModelIndex & index)
{
return
false
;
}
QWidget *LayerItemDelegate::createEditor(QWidget *parent,
const
QStyleOptionViewItem &option,
const
QModelIndex &index)
const
{
qDebug() << createEditor;
if
(index.column() ==
1
)
// value column
{
QLineEdit* edit =
new
QLineEdit(parent);
edit->setFixedHeight(
33
);
edit->setContentsMargins(
48
,
15
,
50
,
0
);
return
edit;
}
else
return
0
;
// no editor attached
}
void
LayerItemDelegate::setEditorData(QWidget *editor,
const
QModelIndex &index)
const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QLineEdit *edit = static_cast<qlineedit*>(editor);
edit->setText(value);
qDebug() << setEditorData;
}
void
LayerItemDelegate::updateEditorGeometry(QWidget *editor,
const
QStyleOptionViewItem &option,
const
QModelIndex & index )
const
{
editor->setGeometry(option.rect);
}
void
LayerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const
QModelIndex &index)
const
{
qDebug() << setModelData;
QLineEdit *edit = static_cast<qlineedit*>(editor);
model->setData(index, edit->text(), Qt::EditRole);
}
</qlineedit*></qlineedit*></qimage>
最后是view
layertableview.h
123456789101112131415161718192021222324252627282930313233343536373839404142#ifndef LAYERLISTVIEW_H
#define LAYERLISTVIEW_H
#include <qtableview>
#include <qmouseevent>
#include <qdebug>
#include <qheaderview>
#include <qstandarditemmodel>
#include <qcontextmenuevent>
#include <qmenu>
#include layertablemodel.h
#include layeritemdelegate.h
class
LayerTableView :
public
QTableView
{
Q_OBJECT
public
:
LayerTableView(QWidget *parent =
0
);
~LayerTableView();
void
setLayerSize(QSize s);
public
slots:
void
addNewLayer();
void
deleteLayer();
protected
:
void
mouseMoveEvent(QMouseEvent * event);
void
contextMenuEvent(QContextMenuEvent * event);
private
:
LayerItemDelegate *delegate;
LayerTableModel *model;
QSize layerSize;
private
slots:
void
itemClicked(
const
QModelIndex&);
};
#endif
// LAYERLISTVIEW_H
</qmenu></qcontextmenuevent></qstandarditemmodel></qheaderview></qdebug></qmouseevent></qtableview>
layertableview.cpp
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091#include layertableview.h
LayerTableView::LayerTableView(QWidget *parent)
: QTableView(parent)
{
delegate =
new
LayerItemDelegate();
model =
new
LayerTableModel();
this
->setContentsMargins(
0
,
0
,
0
,
0
);
this
->setModel(model);
this
->setItemDelegate(delegate);
this
->horizontalHeader()->setStretchLastSection(
true
);
this
->horizontalHeader()->setHighlightSections(
false
);
this
->setFrameShape(QFrame::NoFrame);
this
->setColumnWidth(
0
,
30
);
this
->setColumnWidth(
1
,
170
);
this
->verticalHeader()->setVisible(
false
);
this
->horizontalHeader()->setVisible(
false
);
this
->resizeColumnsToContents();
this
->resizeRowsToContents();
/*this->setEditTriggers(QAbstractItemView::NoEditTriggers);
this->setSelectionBehavior(QAbstractItemView::SelectRows);*/
this
->setMouseTracking(
true
);
//important
//When click on the checkbox it will emit signal twice.Click on the cell emit only once.
connect(
this
, SIGNAL(clicked(
const
QModelIndex&)),
this
, SLOT(itemClicked(
const
QModelIndex&)));
}
LayerTableView::~LayerTableView()
{
}
void
LayerTableView::mouseMoveEvent(QMouseEvent * event)
{
}
void
LayerTableView::contextMenuEvent(QContextMenuEvent * event)
{
QMenu *pMenu =
new
QMenu(
this
);
QAction *pAddGroupAct =
new
QAction(tr(Delete), pMenu);
pMenu->addAction(pAddGroupAct);
pMenu->popup(mapToGlobal(event->pos()));
}
void
LayerTableView::addNewLayer()
{
model->addItem(QString(), QImage(layerSize, QImage::Format_RGB32),
true
);
//model->addItem(QString(), QImage(images\sample.jpg), true);
model->refreshModel();
this
->resizeRowsToContents();
}
void
LayerTableView::itemClicked(
const
QModelIndex& index)
{
if
(index.isValid() )
{
//When click in column 0.
if
(index.column() ==
0
)
{
model->changeLayerVisibility(index);
QModelIndex tmp = model->selecttedIndex(model->getSelecttedRow());
this
->selectionModel()->select(tmp, QItemSelectionModel::Select);
}
//When click in column 1.
else
if
(index.column() ==
1
)
{
model->setSelecttedRow(index.row());
}
}
}
void
LayerTableView::deleteLayer()
{
model->deleteItem(model->getSelecttedRow());
model->refreshModel();
QModelIndex tmp = model->selecttedIndex(
0
);
this
->selectionModel()->select(tmp, QItemSelectionModel::Select);
}
void
LayerTableView::setLayerSize(QSize s)
{
layerSize = s;
}
Qt中显示复杂列表
最新推荐文章于 2024-04-25 15:22:25 发布