Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Component does not integrate into the flow of a ColumnLayout
QtWS25 Last Chance

Component does not integrate into the flow of a ColumnLayout

Scheduled Pinned Locked Moved Solved QML and Qt Quick
10 Posts 3 Posters 1.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rowild
    wrote on last edited by rowild
    #1

    Hi!

    I build a TextInputField Component, which I would like to be able to simply integrate in the flow of a ColumnLayout. But a regular "static" Text above it is covered by the component, while a Button following the TextFieldComponent appears properly according to the spacing rules.

    (EDIT: I just found out that the button only follows correctly, because it adjust itself in relation to the Text component, but not to my custom component!)

    Can anybody help me find out, what am I doing wrong here? Thank you!

    TextInputField Component:

    import QtQuick 2.9
    import QtQuick.Layouts 1.3
    
    Item {
    	id: rootItem
    
    	property int w: 0
    	property int h: 0
    	property int xPos: 0
    	property int yPos: 0
    	property int padding: 6
    	property string primaryColor: "midnightblue"
    	property string primaryColorInverse: "lightsteelblue"
    	property int rectBorderRadius: 2
    	property int rectBorderWidth: 1
    	property string placeholderText: "e.g. Tempo & Rehearsal Marks"
    
    	Rectangle {
    		id: rect
    
    		// x: rootItem.xPos
    		// y: parent.y + parent.height + parent.spacing + parent.spacing/2
    		width: rootItem.w
    		height: rootItem.h
    
    		color: rootItem.primaryColorInverse
    		radius: rootItem.rectBorderRadius
    		border {
    			width: rootItem.rectBorderWidth
    			color: rootItem.primaryColor
    		}
    		// antialiasing: false
    
    		TextInput {
    			id: txtInput
    			y: rect.y + 8
    			width: rect.w
    			height: rect.h
    			anchors {
    				fill: rect
    			}
    			horizontalAlignment: rect.AlignHCenter
    			// verticalAlignment: rect.AlignVCenter
    			color: rootItem.primaryColor
    			padding: rootItem.padding
    			selectByMouse: true
    			layer.enabled: true
    
    			Text {
    				text: rootItem.placeholderText
                                    color: "teal"
    				y: txtInput.y
    				anchors {
    					fill: txtInput
    				}
    				padding: txtInput.padding
                                    visible: !txtInput.text && !txtInput.activeFocus
    			}
    		}
    	}
    }
    
    

    Sample App (Musescore Plugin):

    import QtQuick 2.9
    import QtQuick.Layouts 1.3
    import QtQuick.Controls 2.2
    import MuseScore 3.0
    
    MuseScore {
    	menuPath: "Plugins.Staff List Creator"
    	description: "Descr"
    	version: "0.1.0"
    	id: root
    
    	pluginType: "dock"
    	dockArea: "right"
    	width: 300
    	height: 600
    	requiresScore: true
    
    	ColumnLayout {
    		id: sourceStaffSelector
    		anchors {
    			left: root.left
    			leftMargin: 5
    			top: root.top
    			topMargin: 5
    			rightMargin: 5
    		}
    		spacing: 14
    		width: 300
    
    		Text {
    			id: createStaffListSourceTitle
    			text: qsTr("Enter a title for the new Staff List:")
    			font {
    				//pixelSize: 20
    				pointSize: 14
    				bold: true
    			}
    			anchors {
    				fill: parent
    			}
    			color: "white"
    			height: 28
    		}
    
                    // My Custom Component that should appear UNDER the above TEXT component...
    		TextInputField {
    			id: staffListTitle
    			w: 300
    			h: 28
    		}
    
    		Button {
    			id: btnCreateStaffList
    			text: qsTr("Create Staff List")
                            [...]
    		}
    	}
    }
    

    Screenshot of the result (with remarks):
    component.jpg

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by sierdzio
      #2

      There are multiple issues here:

      1. You newer set any width or height for your component. Item has built-in width and height properties. So adding w and h is pointless (and since Layout does not know about them, it does not work), remove that or at least tie it to the concrete dimensions from Item.

      2. You are using anchors in your Text element, which is inside a Layout. This is an error - items inside layouts should not have any anchors. Qt warns about it in the console. If you want to modify positioning inside a layout, use the attached properties (Layout.fillWidth, Layout.margins, Layout.alignment, etc.).

      3. Components in Layout need to have some width or height set (anything other than 0). In some cases, that means setting height, in others implicitHeight properties. If you want a component to stretch and fill all available space, use Layout.fillWidth or Layout.fillHeight.

      (Z(:^

      1 Reply Last reply
      2
      • R Offline
        R Offline
        rowild
        wrote on last edited by
        #3

        @sierdzio

        Thank you very much for your quick response!

        First, I should mention that I cannot use Qt Creator, because there is currently no way to import Musescore. (If anybody does, that would be awesome!)
        So I use VScode and the integrated IDE of Musescore, which is very, very limited. Also, when it comes to external files, Musescore has to be restarted as soon as there have been changes, since Musescore does not recognise that a dependency was changed (and deleting the .qmlc won't work either).
        I am not sure, though, if this is the reason, why I do not see the errors in the console you are mentioning (about using anchors within Layouts). I have to investigate...

        You say that I do not set any width and height in my component. If I understood you well, then I have to explicitly set the "width" and "height" properties on "Item"? This is what I did and - voilà! - it works! (I also removed the anchors you mentioned.)

        Item {
          id: rootItem
          property int w: 0
          property int h: 0
          width: w
          height: h
          [...]
        

        However: what do you mean by "...or at least tie it to the concrete dimensions from Item"? What would that look like?

        Thank you again! Much appreciated! :-)

        sierdzioS 1 Reply Last reply
        0
        • R rowild

          @sierdzio

          Thank you very much for your quick response!

          First, I should mention that I cannot use Qt Creator, because there is currently no way to import Musescore. (If anybody does, that would be awesome!)
          So I use VScode and the integrated IDE of Musescore, which is very, very limited. Also, when it comes to external files, Musescore has to be restarted as soon as there have been changes, since Musescore does not recognise that a dependency was changed (and deleting the .qmlc won't work either).
          I am not sure, though, if this is the reason, why I do not see the errors in the console you are mentioning (about using anchors within Layouts). I have to investigate...

          You say that I do not set any width and height in my component. If I understood you well, then I have to explicitly set the "width" and "height" properties on "Item"? This is what I did and - voilà! - it works! (I also removed the anchors you mentioned.)

          Item {
            id: rootItem
            property int w: 0
            property int h: 0
            width: w
            height: h
            [...]
          

          However: what do you mean by "...or at least tie it to the concrete dimensions from Item"? What would that look like?

          Thank you again! Much appreciated! :-)

          sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          @rowild said in Component does not integrate into the flow of a ColumnLayout:

          @sierdzio
          You say that I do not set any width and height in my component. If I understood you well, then I have to explicitly set the "width" and "height" properties on "Item"? This is what I did and - voilà! - it works! (I also removed the anchors you mentioned.)

          Nice!

          Item {
            id: rootItem
            property int w: 0
            property int h: 0
            width: w
            height: h
            [...]
          

          That's OK. But looking at the code, I'd say you don't need property int w at all. Just use width.

          Then in child items (Rectangle, Text etc.) you don't need to do:

          width: rootItem.w
          height: rootItem.h
          

          It's enough to call anchors.fill: parent.

          However: what do you mean by "...or at least tie it to the concrete dimensions from Item"? What would that look like?

          Exactly what you did :-)

          Thank you again! Much appreciated! :-)

          Happy coding :-)

          (Z(:^

          R 1 Reply Last reply
          2
          • GrecKoG Offline
            GrecKoG Offline
            GrecKo
            Qt Champions 2018
            wrote on last edited by
            #5

            Your custom component look unnecessarily complicated.

            Why do you use a Item as the root object, and then fill it with a Rectangle?
            You could have just used a Rectangle as root.

            Building on top of a TextField looks to be easier (it seems you are just customizing the background and placeholder label)

            TextField {
                id: root
                property string primaryColor: "midnightblue"     
                property string primaryColorInverse: "lightsteelblue"     
                property int rectBorderRadius: 2     
                property int rectBorderWidth: 1
            
                background: Rectangle {
                    color: rootItem.primaryColorInverse
                    radius: rootItem.rectBorderRadius
                    border {
                        width: rootItem.rectBorderWidth
                        color: rootItem.primaryColor
                    }
                }
                Text {
                    text: root.placeholderText
                    // other stuff for your placeholder (see here for inspiration : https://github.com/qt/qtquickcontrols2/blob/dev/src/imports/controls/TextField.qml )
                 }
            }
            

            A lot of properties are missing from your handmade solution, for example you don't set any implicitWidth or implicitHeight (which are used by layouts). Even simple stuff like the text of the TextInput is not accessible from outside.

            An alternative from subclassing TextField would be to provide your own QtQuick Controls 2 style : https://doc.qt.io/archives/qt-5.11/qtquickcontrols2-customize.html#creating-a-custom-style

            1 Reply Last reply
            1
            • R Offline
              R Offline
              rowild
              wrote on last edited by rowild
              #6

              @GrecKo Thank you so much for your valuable feedback!

              I am totally new to QML and "learned" the creation of custom components from a Youtube tutorial. There a "MyTextField" and a "MyButton" component are created the same way, meaning that "Item" is used as the base. Therefore I thought custom components must all start with "Item". It seems I am wrong! So thank you for opening up my perspective!

              I also read about the "implicit" attributes and played around with them. So far I didn't grasp the concept, my tries didn't result in anything that gave me the "aha!" experience - they did simply nothing... I assume these values can be compared somewhat to CSS's flexbox features, where - in case there are more objects taking up the space of their parent - a given width or height won't shrink any further, if "flex-shrink: 0" is set?

              I will work through what you posted and will report back.

              Again, this is a lot of help and an excellent forum, so thanks to all of you for helping me out here!
              Have a good day!

              1 Reply Last reply
              0
              • sierdzioS sierdzio

                @rowild said in Component does not integrate into the flow of a ColumnLayout:

                @sierdzio
                You say that I do not set any width and height in my component. If I understood you well, then I have to explicitly set the "width" and "height" properties on "Item"? This is what I did and - voilà! - it works! (I also removed the anchors you mentioned.)

                Nice!

                Item {
                  id: rootItem
                  property int w: 0
                  property int h: 0
                  width: w
                  height: h
                  [...]
                

                That's OK. But looking at the code, I'd say you don't need property int w at all. Just use width.

                Then in child items (Rectangle, Text etc.) you don't need to do:

                width: rootItem.w
                height: rootItem.h
                

                It's enough to call anchors.fill: parent.

                However: what do you mean by "...or at least tie it to the concrete dimensions from Item"? What would that look like?

                Exactly what you did :-)

                Thank you again! Much appreciated! :-)

                Happy coding :-)

                R Offline
                R Offline
                rowild
                wrote on last edited by
                #7

                @sierdzio I have to ask something concerning the "anchors" attribute: In your second answer you say it is ok to "anchors.fill:parent" for the Rectangle, but in you first answer you mention that using "anchors" on a TextElement that lives within a Layout Component is a no-go. Do I understand you correctly on this or am I mixing up something? (I looked for docu talking about that, but haven't found anything yet - probably oversaw quite a bit. You don't happen to have a link to a place in the documentation that talks about that by any chance?)

                Thank you!

                sierdzioS 1 Reply Last reply
                0
                • R rowild

                  @sierdzio I have to ask something concerning the "anchors" attribute: In your second answer you say it is ok to "anchors.fill:parent" for the Rectangle, but in you first answer you mention that using "anchors" on a TextElement that lives within a Layout Component is a no-go. Do I understand you correctly on this or am I mixing up something? (I looked for docu talking about that, but haven't found anything yet - probably oversaw quite a bit. You don't happen to have a link to a place in the documentation that talks about that by any chance?)

                  Thank you!

                  sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #8

                  @rowild said in Component does not integrate into the flow of a ColumnLayout:

                  @sierdzio I have to ask something concerning the "anchors" attribute: In your second answer you say it is ok to "anchors.fill:parent" for the Rectangle, but in you first answer you mention that using "anchors" on a TextElement that lives within a Layout Component is a no-go. Do I understand you correctly on this or am I mixing up something? (I looked for docu talking about that, but haven't found anything yet - probably oversaw quite a bit. You don't happen to have a link to a place in the documentation that talks about that by any chance?)

                  Thank you!

                  It may be confusing but it's not a mixup.

                  In first post I was talking about components which are direct children of a Layout - there you cannot use anchors.

                  In second post I was speaking of elements which were children of other items (not Layout) - there you can use anchors as much as you like :-)

                  (Z(:^

                  R 1 Reply Last reply
                  1
                  • sierdzioS sierdzio

                    @rowild said in Component does not integrate into the flow of a ColumnLayout:

                    @sierdzio I have to ask something concerning the "anchors" attribute: In your second answer you say it is ok to "anchors.fill:parent" for the Rectangle, but in you first answer you mention that using "anchors" on a TextElement that lives within a Layout Component is a no-go. Do I understand you correctly on this or am I mixing up something? (I looked for docu talking about that, but haven't found anything yet - probably oversaw quite a bit. You don't happen to have a link to a place in the documentation that talks about that by any chance?)

                    Thank you!

                    It may be confusing but it's not a mixup.

                    In first post I was talking about components which are direct children of a Layout - there you cannot use anchors.

                    In second post I was speaking of elements which were children of other items (not Layout) - there you can use anchors as much as you like :-)

                    R Offline
                    R Offline
                    rowild
                    wrote on last edited by
                    #9

                    @sierdzio AHA!!! I think that turned on the lightbulb in my dark brain :-) Thank you very much!!

                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      rowild
                      wrote on last edited by
                      #10

                      When I define my custom Component, as suggested by @GrecKo, using "TextField {}" as root and not "Item {}", I get this error:

                      Creating component failed
                      line 47: Type CustomTextInputField unavailable

                      // "CustomTextInputfield.qml"

                      import QtQuick 2.9
                      import QtQuick.Layouts 1.3
                      import QtQuick.Controls 2.2
                      
                      TextField {
                      	id: txtInput
                      
                      	property int padding: 6
                      	property string primaryColor: "midnightblue"
                      	property string primaryColorInverse: "lightsteelblue"
                      	property int rectBorderRadius: 2
                      	property int rectBorderWidth: 1
                      	property string placeholderText: "e.g. Tempo & Rehearsal Marks"
                      
                      	// width: txtInput.width
                      	// height: txtInput.height
                      	color: txtInput.primaryColor
                      	padding: txtInput.padding
                      
                      	selectByMouse: true
                      	layer.enabled: true
                      
                      	background: Rectangle {
                      		color: txtInput.primaryColorInverse
                      		radius: txtInput.rectBorderRadius
                      		border {
                      				width: txtInput.rectBorderWidth
                      				color: txtInput.primaryColor
                      		}
                      	}
                      
                      	Text {
                      		text: txtInput.placeholderText
                      		color: "#eeeeee"
                      		y: txtInput.y
                      		width: txtInput.width
                      		height: txtInput.height
                      		padding: txtInput.padding
                      		visible: !txtInput.text && !txtInput.activeFocus
                      	}
                      
                      }
                      

                      It does work, though, when I use "Item" around everything (and move the properties and adjust ids, of course).

                      What am I misunderstanding here? Which mistake(s) do I make?

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved