我是不是遗漏了啥或者这是创建自定义控件/组件的方式

Posted

技术标签:

【中文标题】我是不是遗漏了啥或者这是创建自定义控件/组件的方式【英文标题】:Am I missing something or this is the way to create custom control/component我是否遗漏了什么或者这是创建自定义控件/组件的方式 【发布时间】:2020-10-20 05:59:59 【问题描述】:

在我的Card.qml,我有这些:

import QtQuick 2.9
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.3

Item 
    default property alias content: x.children /*contentItem.data*/
    property alias header: header.text

    Rectangle
        id: rect
        anchors.fill: parent
        ColumnLayout
            anchors.fill: parent
            Text
                id: header
                font.bold: true
                leftPadding: 10
                topPadding: 10
            
            Rectangle
                Layout.fillWidth: true
                Layout.leftMargin: 5
                Layout.rightMargin: 5
                height: 2
                border.color: "black"
            
            Item 
                id: x
                Layout.margins: 10
                Layout.topMargin: 0
                Layout.fillHeight: true
                Layout.fillWidth: true
            
        
    
    DropShadow
        anchors.fill: rect
        source: rect
        radius: 10
        samples: 15
        color: "black"
    

Field.qml 这些:

import QtQuick 2.9
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3

Item 
    id: root
    property alias label: label.text
    property alias placeholder: field.placeholderText

    RowLayout
        anchors.fill: root
        Label
            id: label
            Layout.minimumWidth: 50
        
        TextField
            id: field
        
    

main.qml 这些:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3

Window 
    visible: true
    width: 640
    height: 480
    title: "Test Window"

    GridLayout
        anchors.fill: parent
        columns: 2
        rows: 2
        Card      
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.margins: 10
            header: "H1"
            Texttext: "text 1"
        
        Card
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.margins: 10
            header: "H2"
            Texttext: "text 2"
        
        Card
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.margins: 10
            header: "H3"
            Texttext: "text 3"
        
        Card
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.margins: 10
            header: "H4"
            ColumnLayout
                Field
                    label: "Name"
                    placeholder: "name"
                
                Field
                    label: "Age"
                    placeholder: "age"
                
                /*
                TextField
                TextField
                */
            
        
    

当我运行应用程序时,它看起来像这样:

第一个问题是最后一个Field在第四个Card在第一个Field之上,为什么?其次,在每个Card 中,我都必须拥有这些才能正确渲染:

Layout.fillHeight: true
Layout.fillWidth: true
Layout.margins: 10

我可以将这 3 行放在 Card.qml 中,但在这种情况下,我可能总是不得不在某些 Layout 中使用它,对吧?

第三个Card.qml,第一个Rectangle虽然我有anchors.fill: parent,但我又必须在ColumnLayout里面有anchors.fill: parent,为什么?

我在 QML 中找不到 Separator 控件,因此我将在其中使用另一个 Rectangleheight: 2。我想让Rectangle 更薄,所以我把height: 1 放在了Windowheight: 1 上!

虽然我已经在根RectangleColumnLayout 中提到了两次anchors.fill: parent,但我还是必须在Layout.fillWidth: true 中使用Layout.fillWidth: true 来分隔Rectangle 和内容Item

我是在 QML 中正确地布置东西还是有更简单的方法?

【问题讨论】:

【参考方案1】:

Field的新定义:

import QtQuick 2.9
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3

RowLayout
    property alias label: label.text
    property alias placeholder: field.placeholderText

    Label
        id: label
        Layout.minimumWidth: 50
    
    TextField
        id: field
        Layout.fillWidth: true
    

解决了重叠问题,这实际上是有道理的:Label 告诉RowLayout 至少给它 50 pt/px/whatever 并且TextField 命令它分配剩余的宽度。

我带来了这些台词

Layout.fillHeight: true
Layout.fillWidth: true
Layout.margins: 10

Card 定义中:

import QtQuick 2.9
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.3

Item 
    default property alias content: content.children /*content.data*/
    property alias header: header.text
    property double margin: 10
    property double separatorMargin: 5

    Layout.fillHeight: true
    Layout.fillWidth: true
    Layout.margins: 10

    Rectangle
        id: rect
        anchors.fill: parent
        ColumnLayout
            anchors.fill: parent
            Text
                id: header
                font.bold: true
                leftPadding: margin
                topPadding: margin
                //Layout.alignment: Qt.AlignTop
            
            Rectangle
                id: separator
                Layout.fillWidth: true
                Layout.leftMargin: separatorMargin
                Layout.rightMargin: separatorMargin
                height: 2
                border.color: "black"
                //anchors.top: header.bottom
            
            ColumnLayout 
                id: content
                Layout.leftMargin: margin
                Layout.rightMargin: margin
                Layout.fillHeight: true
                Layout.fillWidth: true
                //anchors.top: separator.bottom
            
        
    
    DropShadow
        anchors.fill: rect
        source: rect
        radius: 10
        samples: 15
        color: "black"
    

我仍然迷失在这之中。在第一个ColumnLayout 中,anchors.fill: parent 行告诉它占据rect 的整个区域,对吧? AND 不是第二个ColumnLayout (id: content)Layout.fillHeight: true 告诉content 填充第一个ColumnLayout 的剩余高度吗?这是它现在的样子:

虽然我在ColumnLayout (id: content) 中有Layout.fillHeight: true,但根ColumnLayout 不在乎!它在Text (header)Rectangle (separator)ColumnLayout (content) 之间均匀分布整个空间,为什么?我还缺少什么吗?

这是main.qml的内容:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3

Window 
    visible: true
    width: 640
    height: 480
    title: "Test Window"

    GridLayout
        anchors.fill: parent
        columns: 2
        rows: 2

        Card
            header: "H1"
            Texttext: "text 1"
        
        Card
            header: "H2"
            Texttext: "text 2"
        
        Card
            header: "H3"
            RowLayout
                Field
                    label: "Name"
                    placeholder: "name"
                
                Field
                    label: "Age"
                    placeholder: "age"
                
            
        
        Card
            header: "H4"
            ColumnLayout
                Field
                    label: "Name"
                    placeholder: "name"
                
                Field
                    label: "Age"
                    placeholder: "age"
                
                Field
                    label: "Address"
                    placeholder: "address"
                
                Field
                    label: "Age"
                    placeholder: "age"
                
                Field
                    label: "Address"
                    placeholder: "address"
                
            
        
    

编辑

我必须给 ColumnLayout (content) 一个精确或更大的高度来解决问题!这个定义:

ColumnLayout 
    id: content
    Layout.preferredHeight: parent.height
    Layout.leftMargin: margin
    Layout.rightMargin: margin
    //Layout.alignment: Qt.AlignTop

让它占据可用空间。现在的问题是它里面的内容是垂直居中的。

我已尝试使用另外两个容器 ItemFlow 但这些容器都没有在窗口大小更改时调整其内容。

GridLayoutColumLayOutRowLayout 是唯一响应窗口大小变化的布局吗?

编辑

StackLayout 代替ColumnLayoutcontent 解决了问题!

【讨论】:

以上是关于我是不是遗漏了啥或者这是创建自定义控件/组件的方式的主要内容,如果未能解决你的问题,请参考以下文章

pyqt5——自定义控件

如何为 Metro 开发制作自定义控件和组件?

这是一个可能的 Oracle 错误还是我遗漏了啥?

Oracle 新手,不确定我是不是“遗漏”了啥

关于在 Xcode 上导入 Alamofire,我是不是遗漏了啥?

(19)C# 创建自定义控件