1,简介
前面一些文章介绍了QTreeView的常规用法,接下来介绍一些高级的用法和改造技巧。
本文介绍delegate,即委托,对QTreeView的item进行改造,以实现特殊的输入方式。
2,其他参考资料
Qt官方提供的委托示例:SpinBoxDelegate
(在QtCreator的欢迎里搜delegate,其中spin box delegate example)
关于委托的详细介绍,可以参考豆子的博客:
Qt学习之路(48): 自定义委托
各种类型的委托控制输入的例子:
QT:在QTableView中使用各种自定义委托
3,效果
这里演示一个让某列使用QComboBox进行编辑的效果:
4,实现
继承QStyledItemDelegate,写一个MyDelegate类:
实现里面的以下方法:
createEditor: 当item激活编辑状态时,显示的内容。这里创建一个QComboBox
setEditorData:用以初始化createEditor里创建的控件内容。这里直接把当前item的text设置为QComboBox选中项。
setModelData:应用编辑后,修改model的data。这里把QComboBox的当前选中项文本设置为item的显示文本。
updateEditorGeometry:更新控件位置状态。
MyDelegate.h:
#ifndef MYDELEGATE_H
#define MYDELEGATE_H
#include <QStyledItemDelegate>
class MyDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MyDelegate(QObject *parent = 0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
#endif
MyDelegate.cpp:
#include "mydelegate.h"
#include <QSpinBox>
#include <QComboBox>
MyDelegate::MyDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *MyDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex & index ) const
{
if(index.column() == 3) //只对第4列采用此方法编辑
{
QComboBox* box = new QComboBox(parent);
box->addItems(QStringList()<<"优"<<"良"<<"差");
return box;
}
return NULL;
}
void MyDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QComboBox* box = static_cast<QComboBox*>(editor);
box->setCurrentText(value);
}
void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox* box = static_cast<QComboBox*>(editor);
model->setData(index, box->currentText(), Qt::EditRole);
}
void MyDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
在初始化QTreeView时,新建一个MyDelegate,设itemDelegate:
注意:要设置单元格编辑属性为可编辑(setEditTriggers),否则点击单元格不会有反应。
QTreeView* t = ui->treeView;
// t->setEditTriggers(QTreeView::NoEditTriggers); //单元格不能编辑
t->setSelectionBehavior(QTreeView::SelectRows); //一次选中整行
t->setSelectionMode(QTreeView::SingleSelection); //单选,配合上面的整行就是一次选单行
// t->setAlternatingRowColors(true); //每间隔一行颜色不一样,当有qss时该属性无效
t->setFocusPolicy(Qt::NoFocus); //去掉鼠标移到单元格上时的虚线框
MyDelegate* delegate = new MyDelegate;
t->setItemDelegate(delegate);