1 2 3 4 5 6 7 8 9 10 11 | QtQuick1_4.TableView { id: tableView CusTableDelegate { id: tableHeaderDelegate } CusListModel { id: tableModel } //Text { id: tableItemDelegate; text: styleData.value; } headerDelegate: tableHeaderDelegate model: tableModel itemDelegate: Text { id: tableItemDelegate; text: styleData.value; } //直接赋值 } |
这样写是可以的
1 2 3 4 5 6 7 8 9 10 11 | QtQuick1_4.TableView { id: tableView CusTableDelegate { id: tableHeaderDelegate } CusListModel { id: tableModel } Text { id: tableItemDelegate; text: styleData.value; } // 封装成对象再使用 headerDelegate: tableHeaderDelegate model: tableModel itemDelegate: tableItemDelegate//Text { id: tableItemDelegate; text: styleData.value; } //直接赋值 } |
这样写是会报错的:
Unable to assign QQuickText to QQmlComponent
所以可以知道Component本身是不支持Text转化为Component,这个是符合语法的,因为他们类之间没有直接的继承关系即:
不支持pComponnet = new QQuickText();//这样是正常的,不支持这样是符合语法的
所以itemDelegate: tableItemDelegate写会报错,
那么为什么这么写itemDelegate: Text { id: tableItemDelegate; text: styleData.value; } //直接赋值
qml就不报错呢?
照理说应该是pComponent = new new QQuickText(),这样的,不符合语法的,
但是原因在于itemDelegate:Text{...},重点是这个冒号:,也就是熟悉赋值操作过程,
因为是熟悉赋值操作过程,qml,会解析为itemDeletate:Component{Text{...}},
所以最终解析为C++,就变为了
pIDComponent_tableitemDelegate= new QQmlComponent();
pIDComponent_tableitemDelegate.addItem(Text{...});
pComponent = pIDComponent_tableitemDelegate
所以这样是符合语法的,所以是可以的,
所以如果要封装之后再用,可以这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | QtQuick1_4.TableView { id: tableView CusTableDelegate { id: tableHeaderDelegate } CusListModel { id: tableModel } Component{ // 封装成Component使用 id: textComponent Text { id: tableItemDelegate; text: styleData.value; } } headerDelegate: tableHeaderDelegate model: tableModel itemDelegate: textComponent // 使用用封装的Component } |
这样qml就会解析为:
pComponnet = new Component_id_textComponnet();
因为Component_id_textComponnet基类是QQmlComponnet,
这样是符合语法的,所以这样是可以的
qt相关源码原理如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void QQuickTableView::setDelegate(QQmlComponent *newDelegate) { Q_D(QQuickTableView); if (newDelegate == d->assignedDelegate) return; d->assignedDelegate = newDelegate; // 设置好了之后,系统内核就会将delegate和对应的model绑定 // 这样指针newDelegate就可以访问model中的styleData了,实现 // model和delegate数据交互了 // 所以只要newDelegate赋值正确, // 其子对象就可以访问父对象可以访问的styleData等数据了 d->scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All); emit delegateChanged(); } |