网站首页 > 技术文章 正文
在表格中嵌入各种不同控件,可通过控件对编辑的内容进行限定。在本文实例中,利用Delegate的方式嵌入控件,且控件只在需要编辑数据项时才出现,如下图所示(为简洁起见三图合成)。
表格中有3种不同的控件,分别是用于生日输入的日历编辑框QDateLineEdit、下拉列表框QComboBox和一个QSpinBox,因此需实现3个Delegate对象:DateDelegate、ComboDelegate和SpinDelegate,这3个Delegate都是Widget类型的控件,因此都采用继承QltemDelegate的方式实现。下面分别对3个Delegate的实现进行介绍。
一、DateDelegate的实现
class DateDelegate : public QItemDelegate
{
Q_OBJECT
public:
DateDelegate(QObject *parent=0);
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
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;
};
DateDelegate继承自QltemDelegate类,实现一个自定义的Delegate,一般需要重定义声明中的几个虚函数。createEditor()函数完成创建控件的工作,创建由参数中QModellndex对象指定的表项数据的编辑控件,并对控件的内容进行限定;setEditorData()函数设置控件显示的数据,把Model中的数据更新至Delegate中,相当于一个初始化的工作;setModelData()函数把Delegate中对数据的改变更新至Model中。updateEditor()函数更新控件区的显示。
QWidget *DateDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QDateTimeEdit *editor=new QDateTimeEdit(parent); // (a)
editor->setDisplayFormat("yyyy-MM-dd"); // (b)
editor->setCalendarPopup(true); // (c)
editor->installEventFilter(const_cast<DateDelegate*>(this)); // (d)
return editor;
}
其中:
- (a):新建一个QDateTimeEdit对象作为编辑时的输入控件。
- (b):设置此QDateTimeEdit对象的显示格式为yyyy-MM-dd,此显示方式为ISO方式。日期显示的格式可以有很多种,以QString的方式设置,可根据需要进行设定,如:
yy.MM.dd 08.01.01
d.MM.yyyy 1.01.2008
其中,y表示年,M表示月份,d表示日,需要注意的是表示月的M一定要大写。
- (c):设置日历选择的显示以Popup的方式,即下拉显示的方式。
- (d):调用QObject类的installEventFilter()函数安装事件过滤器,使DateDelegate能捕获QDateTimeEdit对象的事件。
void DateDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString dateStr=index.model()->data(index).toString(); // (e)
QDate date=QDate::fromString(dateStr,Qt::ISODate); // (f)
QDateTimeEdit *edit=static_cast<QDateTimeEdit*>(editor); // (g)
edit->setDate(date); // 设置控件的显示数据
}
其中:
- (e):获取指定index数据项的数据,调用QModellndex的model()可获得提供此index的Model对象,data()函数返回的是一个QVariant对象,把它转换成一个QString类型数据。
- (f):通过QDate的fromString()函数把以QString类型表示的日期数据转换成QDate类型,Qt::ISODate表示QString类型的日期是以ISO格式保存的,这样最终转换获得的QDate数据也是ISO格式,使控件显示与表格显示保持一致。
- (g):把参数中的editor转换成QDateTimeEdit对象,以获得编辑控件的对象指针。
void DateDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model, const QModelIndex &index) const
{
QDateTimeEdit *edit=static_cast<QDateTimeEdit*>(editor); // 获得编辑控件的对象指针
QDate date=edit->date(); // 获得编辑控件中的数据更新
model->setData(index,QVariant(date.toString(Qt::ISODate))); // (h)
}
其中:
- (h):调用setData()把数据修改更新到Model中。
二、ComboDelegate 的实现
ComboDelegate的类声明与DateDelegate的类似,需要重定义的函数也一样,此处只列出了重定义的函数。
在createEditor()函数中创建一个QComboBox控件,并插入可显示的条目,并安装事件过滤器。
QWidget* ComboDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *editor=new QComboBox(parent);
editor->addItem(tr("工人"));
editor->addItem(tr("农民"));
editor->addItem(tr("医生"));
editor->addItem(tr("律师"));
editor->addItem(tr("军人"));
editor->installEventFilter(const_cast<ComboDelegate*>(this));
return editor;
}
更新Delegate控件的数据显示:
void ComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QString str=index.model()->data(index).toString();
QComboBox *box=static_cast<QComboBox*>(editor);
int i=box->findText(str);
box->setCurrentIndex(i);
}
更新Model中的数据:
void ComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *box=static_cast<QComboBox*>(editor);
QString str=box->currentText();
model->setData(index,str);
}
三、SpinDelegate的实现
与ComboDelegate的实现类似,此处不再赞述,仅给出代码函数。
QWidget* SpinDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSpinBox *editor=new QSpinBox(parent);
editor->setRange(1000,10000);
editor->setSingleStep(500);
editor->installEventFilter(const_cast<SpinDelegate*>(this));
return editor;
}
void SpinDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
int val=index.model()->data(index).toInt();
QSpinBox *box=static_cast<QSpinBox*>(editor);
box->setValue(val);
}
void SpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QSpinBox *box=static_cast<QSpinBox*>(editor);
QString str=QString::number(box->value());
model->setData(index,str);
}
void SpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
四、Delegate的应用
在Model/View结构的显示中应用准备好的Delegate:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStandardItemModel model(4,4); //新建一个QStandardltemModel对象
QTableView tableView;
tableView.setModel(&model); // 用QTableView以表格的方式进行显示
DateDelegate dateDelegate;
ComboDelegate comboDelegate;
SpinDelegate spinDelegate; // (a)
tableView.setItemDelegateForColumn(1,&dateDelegate);
tableView.setItemDelegateForColumn(2,&comboDelegate);
tableView.setItemDelegateForColumn(3,&spinDelegate); // (a)
model.setHeaderData(0,Qt::Horizontal,"姓名");
model.setHeaderData(1,Qt::Horizontal,"生日");
model.setHeaderData(2,Qt::Horizontal,"工作");
model.setHeaderData(3,Qt::Horizontal,"收入"); // 对表格的表头显示进行设置
QFile file("./data.tab"); // (b)
if(file.open(QFile::ReadOnly | QFile::Text))
{
QTextStream stream(&file);
QString line;
model.removeRows(0,model.rowCount());
int row=0;
do{
line=stream.readLine();
if(!line.isEmpty()){
model.insertRow(row,QModelIndex());
QStringList pieces=line.split(",",QString::SkipEmptyParts);
model.setData(model.index(row,0),pieces.value(0));
model.setData(model.index(row,1),pieces.value(1));
model.setData(model.index(row,2),pieces.value(2));
model.setData(model.index(row,3),pieces.value(3)); // (c)
row++;
}
}while(!line.isEmpty());
file.close();
}
tableView.setWindowTitle("Delegate");
tableView.show(); // 显示
return a.exec();
}
其中:
- (a):分别新建3个Delegate,并调用View的setItemDelegateForColumn()函数为指定的列应用指定的Delegate。此处对第1列应用DateDelegate,第2列应用ComboDelegate,第3列应用SpinDelegate。
- (b):data.tab为事前准备好的文本数据文件,放置在项目目录下,内容如下:
Tom,1977-01-05,工人,1500
Jack,1978-12-23,医生,3000
Alice,1980-04-06,军人,2500
John,1983-09-25,律师,5000
- (c):从文件中读取数据作为数据源,并把文件中的数据按数据表项的方式进行管理。
——————————————————
对于本文实例完整代码有需要的朋友,可关注并在评论区留言!
猜你喜欢
- 2024-10-20 Qt 开发经验总结 qt软件开发
- 2024-10-20 Qt QTableWidget用法总结 qtablewidget qtableview
- 2024-10-20 实战PyQt5: 068-MV框架中的项视图部件
- 2024-10-20 Qt开发经验小技巧231-235 qt开发入门简介
- 2024-10-20 Python+PyQt5进阶(5) pyqt5 django
- 2024-10-20 Qt项目升级到Qt6经验总结 qt更新界面
- 2024-10-20 QTableWidget表格中增删数据 qtablewidget清空表格
- 2024-10-20 C/C++ Qt StatusBar 底部状态栏应用
- 2024-10-20 Qt的常用控件 qt控件详解
- 2024-10-20 Python PyQt5通过QTableWidget表格控件操作SQLite数据库
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)