qml delegate熟悉赋值原理

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();
}