选项卡组件的 QML 别名

Posted

技术标签:

【中文标题】选项卡组件的 QML 别名【英文标题】:QML Alias of tab components 【发布时间】:2018-04-09 08:45:51 【问题描述】:

我正在尝试为选项卡元素中包含的组件创建别名,但没有成功。即使这个小例子也不起作用:

Tab 

    id: tab1
    title:'tab1'

    property alias tab1Text: test.text

    Text 
        id:test
        text:'Test123'
        

我收到了这个错误:

property alias tab1Text: test.text

谁能告诉我问题出在哪里,我该如何解决?

【问题讨论】:

您的措辞是正确的:它是 Tab 元素内的 组件组件 不是真正的实例,它们类似于实例的原型/工厂。由于没有真实的实例,因此您不能将组件内的某些内容指定为别名的目标。 好的,如果我明白了。 (1) 我必须将我的选项卡数据包含在 Item 中以获取别名。 (2) 我必须使用 active=true 强制加载选项卡。这是正确的吗 ? (从单个测试来看,它似乎有效,但我希望有正确/最佳/首选的方法来做到这一点。 不,Item 内的封闭是没有用的。我的意思是 - 它会创建一个别名,但只在加载的对象内。它不会帮助您将数据发送到外部。使用active:true 足以通过tab1.item.text 访问文本。如果您在Tab 写入property string tab1Text: (item ? item.text : '') 中创建一个属性(只能用于从test 读取文本) - 这将在加载Text .. 后加载文本。 【参考方案1】:

您不能为Tab 的直接子级设置别名,因为默认情况下不加载其内容:

Tab 项继承自 Loader 并提供类似的 API。

标签被延迟加载;仅已变为当前的选项卡(对于 例如,通过单击它们)将具有有效的内容。

您可以做的是使用item 上的属性而不是别名:

Tab 
    id: tab1
    title: 'tab1'
    active: true
    property string tab1Text: tab1.item ? tab1.item.text : ""

    Text 
        id: test
        text: 'Test123'
    

但只有当内容被加载(当前选项卡或active: true)时,它才会绑定到实际文本。

您还可以在内容周围添加Item

Tab 
    id: tab1
    title: 'tab1'

    Item 
        property alias tab1Text: test.text

        Text 
            id: test
            text: 'Test123'
        
    

但别名在此项目之外仍然不可用(包括选项卡的根目录)。

【讨论】:

"因为它的内容默认不加载:"。我明白这一点,所以我使用 active:true 强制加载,但它不允许我提供别名。第一个解决方案对我来说不合适,因为我想将模型传递给根(示例很简单,但真正的应用程序是一个包含多个组合框的选项卡) 您可以在tab1.item.text 上使用属性而不是别名【参考方案2】:

由于您的别名声明的目标无效,因此发生错误。

在 QML 中,您需要区分 ObjectComponent,而您所拥有的并不总是对用户透明。

有时您可以在文档中找到类似sourceComponent 的属性

sourceComponent: Component

如果你给它分配一些东西,比如:

sourceComponent: Item 

Item 不会被实例化。而是为这个Item 创建了一个Component隐式,然后可以使用它来创建Items。但是由于还没有Item 的实例,因此您也无法访问这个不存在的Item 中的任何属性。

然后在 QML 中你有一个叫做 default property 的东西。 该属性是自动分配所有子对象的位置。

Tab 
    Item 

Tab 
    sourceComponent: Item 

是等价的。在大多数情况下,默认属性不是Component 类型,因此分配的事物是直接实例化的。


现在如何解决这个问题?您可以设置active: true 并使用绑定读取或写入theTab.item.theProperty,但您仍然不能为其设置别名,因为别名的语法只允许id.property 而不允许id.someProperty.someNestedProperty

但是设置active: true 意味着不仅会创建属性,还会创建所有可视项,这通常是不希望的。在我看来,最好的方法是保持数据和视觉表示相互分离: 您可以拥有一个 ViewModel,其中存储了所有数据,并使用可视化表示来绑定到它。因此,绑定由Tab 发起,以读取(并可能修改)text。并且您的其他对象对模型对象的相同属性执行相同的操作。

模型不一定是某种对象列表。它可能只是一个具有各种属性的对象供您的视图显示。

【讨论】:

非常有用的综合步行,感谢。【参考方案3】:

您可以在Tab 中创建一个字符串属性并将Text.text 绑定到它。在加载 Tab 的动态内容时创建绑定。无需强制加载带有active 属性的选项卡。

TabView 
    id: tabView

    function setTab2Text(txt) 
        tab2.tab2Text = txt
    

    Tab
    
        id: tab1
        title:'tab1'
        property string tab1Text: 'Test123'
        Text 
            id:test
            text: tab1.tab1Text
        
    
    Tab
    
        id: tab2
        title:'tab2'
        property string tab2Text
        Text 
            id:test2
            text: tab2.tab2Text
        
    
    Component.onCompleted: setTab2Text('Test456')

【讨论】:

问题是,如果 Text.text 文本从组件内更改,则此绑定将不起作用,但 alias 会。 基于 Loader 的 Quick Controls 1 Tab 不能使用别名。一种可能性是切换到 Quick Controls 2 并使用 TabButton 和 TabBar 我知道这是不可能的。但是你的属性绑定是不等价的。你应该指出这一点。

以上是关于选项卡组件的 QML 别名的主要内容,如果未能解决你的问题,请参考以下文章

QML:带有图标的 QtQuick.Controls 选项卡

Qt5.4mingwRC1 的 QtCreator 的 qml 文件和设计器选项卡出现问题

QML TabView动态添加tab和赋初值

setContextProperty() 不会在 qml 文件中创建类实例

在内部选项卡之前加载的选项卡会导致错误“提供给选项卡组件的值无效”

在材料ui选项卡组件中将选项卡设置为活动