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. ListView as a radio button with radius on the border
Forum Updated to NodeBB v4.3 + New Features

ListView as a radio button with radius on the border

Scheduled Pinned Locked Moved Solved QML and Qt Quick
12 Posts 3 Posters 1.9k Views 2 Watching
  • 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.
  • Shrinidhi UpadhyayaS Shrinidhi Upadhyaya

    Hi @DavidM29 , you can acheive that using Opacity mask.

    Here is the sample code:-

     Rectangle {
        id: masking
    
        height: buttonGridLayout.height
        width: buttonGridLayout.width
        radius: 50
        visible: false
    }
    
    OpacityMask {
        height: buttonGridLayout.height
        width: buttonGridLayout.width
        source: buttonGridLayout
        maskSource: masking
    }
    
    RowLayout {
        id: buttonGridLayout
        anchors.fill: parent
        spacing: 0
        opacity: 0
    
        Repeater {
            model: 3
    
            Rectangle {
                id: rootRect
    
                Layout.fillHeight: true
                Layout.fillWidth: true
                color: activeFocus ? "black" : "red"
    
                Text {
                    text: index
                    anchors.centerIn: parent
                    color: "yellow"
                }
    
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        rootRect.forceActiveFocus()
                    }
                }
            }
        }
    }
    
    D Offline
    D Offline
    DavidM29
    wrote on last edited by
    #3

    Hi @Shrinidhi-Upadhyaya
    You should think that I'm annoying but unfortunatly I do have a limitation on the target device that makes any mask not working. I tried to use it to create a round gauge a few weeks ago and the device can't handle this kind masking. For some reasons it use a specific software that is bugged with my target device.

    Do you have any other ideas ?

    J.HilkJ 1 Reply Last reply
    0
    • D DavidM29

      Hi @Shrinidhi-Upadhyaya
      You should think that I'm annoying but unfortunatly I do have a limitation on the target device that makes any mask not working. I tried to use it to create a round gauge a few weeks ago and the device can't handle this kind masking. For some reasons it use a specific software that is bugged with my target device.

      Do you have any other ideas ?

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #4

      @DavidM29 than I would suggest remove the highlight part all together, and change your delegate with this:

      Rectangle{
                  id: inner
                  color: list.currentIndex == index ? "red" :"transparent"
                  ....
      }
      

      I think index is an automatic assigned property.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      D 1 Reply Last reply
      0
      • Shrinidhi UpadhyayaS Offline
        Shrinidhi UpadhyayaS Offline
        Shrinidhi Upadhyaya
        wrote on last edited by
        #5

        Hi @DavidM29 , ohhh that's bad. Are there only 3 buttons or is it dynamic?

        Shrinidhi Upadhyaya.
        Upvote the answer(s) that helped you to solve the issue.

        1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @DavidM29 than I would suggest remove the highlight part all together, and change your delegate with this:

          Rectangle{
                      id: inner
                      color: list.currentIndex == index ? "red" :"transparent"
                      ....
          }
          

          I think index is an automatic assigned property.

          D Offline
          D Offline
          DavidM29
          wrote on last edited by DavidM29
          #6

          @J.Hilk
          The issue is that the delegate is a Rectangle with no radius. The Radius in on the Rectangle that contains the ListView. If I do like you suggest the problem will be the same I believe.

          What I did is that :
          I do have a Rectangle with radius like that :
          0_1553679498796_794c55ea-4353-400b-9eef-6dd67d11eb00-image.png
          In that rectangle I put the ListView made of transparent rectangle without radius.
          Which means that if I put a color on that it will result in the same behaviour.

          @Shrinidhi-Upadhyaya
          It is Dynamic it will be between 2 to 4 buttons I think.

          J.HilkJ 1 Reply Last reply
          0
          • D DavidM29

            @J.Hilk
            The issue is that the delegate is a Rectangle with no radius. The Radius in on the Rectangle that contains the ListView. If I do like you suggest the problem will be the same I believe.

            What I did is that :
            I do have a Rectangle with radius like that :
            0_1553679498796_794c55ea-4353-400b-9eef-6dd67d11eb00-image.png
            In that rectangle I put the ListView made of transparent rectangle without radius.
            Which means that if I put a color on that it will result in the same behaviour.

            @Shrinidhi-Upadhyaya
            It is Dynamic it will be between 2 to 4 buttons I think.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by J.Hilk
            #7

            @DavidM29 oh in that case,
            inside the "FrameRectangle" set the clip property to true. That is more resource heavy but will do the trick


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            D 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @DavidM29 oh in that case,
              inside the "FrameRectangle" set the clip property to true. That is more resource heavy but will do the trick

              D Offline
              D Offline
              DavidM29
              wrote on last edited by DavidM29
              #8

              @J.Hilk
              It seems to be the same even with the

              clip:true
              

              It set that property to that rectangle :
              0_1553679916769_9a2ccebe-e1f0-4868-af3d-303201e35289-image.png

              But I still have the same result.

              Here is my complete component :

              import QtQuick 2.0
              
              Rectangle {
                  width: 200
                  height: 50
              
                  property var choix : []
              
                  id: out
                  color: "dimgrey"
                  radius: height/2
                  clip: true
              
                  ListView{
                      id : list
                      anchors.fill: parent
                      model: choix
                      orientation: ListView.Horizontal
                      delegate: radioDelegate
                      highlight: highlightComponent
                      highlightFollowsCurrentItem: false
                      interactive: false
                  }
              
                  Component {
                      id: highlightComponent
              
                      Rectangle{
                          anchors.fill: list.currentItem
                          color: "red"
                          anchors.centerIn: list.currentItem
                          y: list.currentItem.y
                          x: list.currentItem.x
                      }
                  }
              
              
                  Component{
                      id: radioDelegate
              
                      Rectangle{
                          property bool selected : false
              
                          id: inner
                          color: "transparent"
                          height: parent.height
                          width: out.width/choix.length
                          border.color: "black"
                          border.width: 1
              
                          Text {
                              id: text
                              text: choix[index]
                              anchors.centerIn: parent
                              font.pixelSize: 15
                          }
              
                          MouseArea{
                              anchors.fill: parent
                              onClicked: list.currentIndex = index
                          }
                      }
                  }
              }
              
              
              J.HilkJ 1 Reply Last reply
              0
              • Shrinidhi UpadhyayaS Offline
                Shrinidhi UpadhyayaS Offline
                Shrinidhi Upadhyaya
                wrote on last edited by Shrinidhi Upadhyaya
                #9

                Hi @DavidM29 ,

                here is the sample code,try to run it and tell me whether it works fine or not and then we can go for optimization part.

                  RowLayout {
                        id: buttonGridLayout
                        anchors.fill: parent
                        spacing: 5
                
                        Repeater {
                            id: buttonRepeater
                            model: 4
                
                            Item {
                                id: rootRect
                                Layout.fillHeight: true
                                Layout.fillWidth: true
                
                                Item {
                                    id: option1
                                    anchors.fill: parent
                                    visible: index === 0
                                    z: visible ? 1 : 0
                
                                    MouseArea {
                                        anchors.fill: parent
                                        onClicked: {
                                            option1.forceActiveFocus()
                                        }
                                    }
                
                                    Rectangle {
                                        id: rect1
                                        height: parent.height
                                        width: parent.width
                                        color: option1.activeFocus ? "red" : "black"
                                        radius: 50
                                    }
                
                                    Rectangle {
                                        id: rect2
                                        height: parent.height
                                        width: parent.width - 50
                                        color: option1.activeFocus ? "red" : "black"
                                        anchors.left: parent.left
                                        anchors.leftMargin: 50
                                    }
                                }
                
                                Rectangle {
                                    id: option2
                                    anchors.fill: parent
                                    visible: (index === 0 || index === buttonRepeater.model - 1)?false:true
                                    color: option2.activeFocus?"red":"black"
                                    z: visible?1:0
                
                                    MouseArea {
                                        anchors.fill: parent
                                        onClicked: {
                                            option2.forceActiveFocus()
                                        }
                                    }
                                }
                
                                Item {
                                    id: option3
                                    anchors.fill: parent
                                    visible: index === buttonRepeater.model - 1
                                    z: visible?1:0
                
                                    MouseArea {
                                        anchors.fill: parent
                                        onClicked: {
                                            option3.forceActiveFocus()
                                        }
                                    }
                
                                    Rectangle {
                                        id: rect21
                                        height: parent.height
                                        width: parent.width
                                        color: option3.activeFocus ? "red" : "black"
                                        radius: 50
                                        anchors.right: parent.right
                                    }
                
                                    Rectangle {
                                        id: rect22
                                        height: parent.height
                                        width: parent.width - 50
                                        color: option3.activeFocus ? "red" : "black"
                                    }
                                }
                
                                Text {
                                    text: index
                                    anchors.centerIn: parent
                                    color: "yellow"
                                    z: 2
                                }
                            }
                        }
                    }
                

                Shrinidhi Upadhyaya.
                Upvote the answer(s) that helped you to solve the issue.

                1 Reply Last reply
                2
                • D DavidM29

                  @J.Hilk
                  It seems to be the same even with the

                  clip:true
                  

                  It set that property to that rectangle :
                  0_1553679916769_9a2ccebe-e1f0-4868-af3d-303201e35289-image.png

                  But I still have the same result.

                  Here is my complete component :

                  import QtQuick 2.0
                  
                  Rectangle {
                      width: 200
                      height: 50
                  
                      property var choix : []
                  
                      id: out
                      color: "dimgrey"
                      radius: height/2
                      clip: true
                  
                      ListView{
                          id : list
                          anchors.fill: parent
                          model: choix
                          orientation: ListView.Horizontal
                          delegate: radioDelegate
                          highlight: highlightComponent
                          highlightFollowsCurrentItem: false
                          interactive: false
                      }
                  
                      Component {
                          id: highlightComponent
                  
                          Rectangle{
                              anchors.fill: list.currentItem
                              color: "red"
                              anchors.centerIn: list.currentItem
                              y: list.currentItem.y
                              x: list.currentItem.x
                          }
                      }
                  
                  
                      Component{
                          id: radioDelegate
                  
                          Rectangle{
                              property bool selected : false
                  
                              id: inner
                              color: "transparent"
                              height: parent.height
                              width: out.width/choix.length
                              border.color: "black"
                              border.width: 1
                  
                              Text {
                                  id: text
                                  text: choix[index]
                                  anchors.centerIn: parent
                                  font.pixelSize: 15
                              }
                  
                              MouseArea{
                                  anchors.fill: parent
                                  onClicked: list.currentIndex = index
                              }
                          }
                      }
                  }
                  
                  
                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by J.Hilk
                  #10

                  @DavidM29
                  ok, time to dig in my bag of tricks ;)
                  I present RoundedRectangle.qml

                  import QtQuick 2.11
                  
                  Item {
                      id:root
                  
                      property color color: "lightgrey"
                      onColorChanged: canVas.requestPaint()
                  
                      property int radius: root.height/3
                      onRadiusChanged: canVas.requestPaint()
                  
                      property bool topLeftCorner: true
                      property bool topRightCorner: false
                      property bool bottomRightCorner: true
                      property bool bottomLeftCorner: false
                  
                      onTopLeftCornerChanged: canVas.requestPaint()
                      onTopRightCornerChanged: canVas.requestPaint()
                      onBottomRightCornerChanged: canVas.requestPaint()
                      onBottomLeftCornerChanged: canVas.requestPaint()
                  
                      property color borderColor: "black"
                      onBorderColorChanged: canVas.requestPaint()
                  
                      property int borderWidth: 1
                  
                      Canvas {
                          id:canVas
                          anchors.fill: parent
                  
                          onPaint: {
                              var context = getContext("2d");
                              context.reset()
                              context.beginPath();
                  
                              //Start position
                              context.moveTo(0,height / 2)
                  
                              //topLeftCorner
                              if(topLeftCorner){
                                  context.lineTo(0,radius)
                                  context.arcTo(0,0,radius, 0, radius);
                              } else {
                                  context.lineTo(0,0)
                              }
                  
                              //topRightCorner
                              if(topRightCorner){
                                  context.lineTo(width - radius, 0)
                                  context.arcTo(width, 0, width, radius, radius)
                              } else {
                                  context.lineTo(width, 0)
                              }
                  
                              //bottomRightCorner
                              if(bottomRightCorner) {
                                  context.lineTo(width, height-radius)
                                  context.arcTo(width, height, width - radius, height, radius)
                              } else {
                                  context.lineTo(width, height)
                              }
                  
                              //bottomLeftCorner
                              if(bottomLeftCorner) {
                                  context.lineTo(radius, height)
                                  context.arcTo(0, height, 0, height - radius, radius)
                              } else {
                                  context.lineTo(0, height)
                              }
                  
                              //Close path
                              context.lineTo(height / 2)
                              context.closePath()
                  
                              //Draw border
                              context.lineWidth = borderWidth
                              context.strokeStyle = borderColor
                              context.stroke()
                  
                              //Draw background
                              context.fillStyle = color
                              context.fill();
                          }
                      }
                  }
                  

                  to be used as:

                  import QtQuick 2.9
                  import QtQuick.Window 2.2
                  
                  Window {
                      visible: true
                      width: 640
                      height: 200
                      title: qsTr("Hello World")
                  
                      Rectangle {
                          id: frame
                  
                          anchors.centerIn: parent
                          height: parent.height*2/3
                          width:  parent.width *2/3
                  
                          radius: height/2
                  
                          color: "lightgrey"
                  
                  
                          ListView{
                              id: lView
                  
                              anchors.fill: parent
                              model: [1,2,3]
                  
                              orientation: ListView.Horizontal
                  
                              clip:  true
                  
                              delegate: RoundedRectangle{
                                  width: lView.width/lView.count
                                  height: lView.height
                                  color: lView.currentIndex == index ? "red" : "transparent"
                  
                                  radius: frame.radius
                                  borderColor: "transparent"
                                  topLeftCorner: index == 0
                                  topRightCorner: index == 2
                                  bottomRightCorner: index ==2
                                  bottomLeftCorner: index == 0
                  
                                  Text {
                                      anchors.centerIn: parent
                                      text: modelData
                                  }
                  
                                  MouseArea{
                                      anchors.fill: parent
                                      onClicked:{
                                          lView.currentIndex = index
                                      }
                                  }
                              }
                          }
                      }
                  }
                  

                  0_1553681770302_83c19cf6-eec2-4f06-a3ad-6a8b7c217b81-image.png


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  D 2 Replies Last reply
                  3
                  • J.HilkJ J.Hilk

                    @DavidM29
                    ok, time to dig in my bag of tricks ;)
                    I present RoundedRectangle.qml

                    import QtQuick 2.11
                    
                    Item {
                        id:root
                    
                        property color color: "lightgrey"
                        onColorChanged: canVas.requestPaint()
                    
                        property int radius: root.height/3
                        onRadiusChanged: canVas.requestPaint()
                    
                        property bool topLeftCorner: true
                        property bool topRightCorner: false
                        property bool bottomRightCorner: true
                        property bool bottomLeftCorner: false
                    
                        onTopLeftCornerChanged: canVas.requestPaint()
                        onTopRightCornerChanged: canVas.requestPaint()
                        onBottomRightCornerChanged: canVas.requestPaint()
                        onBottomLeftCornerChanged: canVas.requestPaint()
                    
                        property color borderColor: "black"
                        onBorderColorChanged: canVas.requestPaint()
                    
                        property int borderWidth: 1
                    
                        Canvas {
                            id:canVas
                            anchors.fill: parent
                    
                            onPaint: {
                                var context = getContext("2d");
                                context.reset()
                                context.beginPath();
                    
                                //Start position
                                context.moveTo(0,height / 2)
                    
                                //topLeftCorner
                                if(topLeftCorner){
                                    context.lineTo(0,radius)
                                    context.arcTo(0,0,radius, 0, radius);
                                } else {
                                    context.lineTo(0,0)
                                }
                    
                                //topRightCorner
                                if(topRightCorner){
                                    context.lineTo(width - radius, 0)
                                    context.arcTo(width, 0, width, radius, radius)
                                } else {
                                    context.lineTo(width, 0)
                                }
                    
                                //bottomRightCorner
                                if(bottomRightCorner) {
                                    context.lineTo(width, height-radius)
                                    context.arcTo(width, height, width - radius, height, radius)
                                } else {
                                    context.lineTo(width, height)
                                }
                    
                                //bottomLeftCorner
                                if(bottomLeftCorner) {
                                    context.lineTo(radius, height)
                                    context.arcTo(0, height, 0, height - radius, radius)
                                } else {
                                    context.lineTo(0, height)
                                }
                    
                                //Close path
                                context.lineTo(height / 2)
                                context.closePath()
                    
                                //Draw border
                                context.lineWidth = borderWidth
                                context.strokeStyle = borderColor
                                context.stroke()
                    
                                //Draw background
                                context.fillStyle = color
                                context.fill();
                            }
                        }
                    }
                    

                    to be used as:

                    import QtQuick 2.9
                    import QtQuick.Window 2.2
                    
                    Window {
                        visible: true
                        width: 640
                        height: 200
                        title: qsTr("Hello World")
                    
                        Rectangle {
                            id: frame
                    
                            anchors.centerIn: parent
                            height: parent.height*2/3
                            width:  parent.width *2/3
                    
                            radius: height/2
                    
                            color: "lightgrey"
                    
                    
                            ListView{
                                id: lView
                    
                                anchors.fill: parent
                                model: [1,2,3]
                    
                                orientation: ListView.Horizontal
                    
                                clip:  true
                    
                                delegate: RoundedRectangle{
                                    width: lView.width/lView.count
                                    height: lView.height
                                    color: lView.currentIndex == index ? "red" : "transparent"
                    
                                    radius: frame.radius
                                    borderColor: "transparent"
                                    topLeftCorner: index == 0
                                    topRightCorner: index == 2
                                    bottomRightCorner: index ==2
                                    bottomLeftCorner: index == 0
                    
                                    Text {
                                        anchors.centerIn: parent
                                        text: modelData
                                    }
                    
                                    MouseArea{
                                        anchors.fill: parent
                                        onClicked:{
                                            lView.currentIndex = index
                                        }
                                    }
                                }
                            }
                        }
                    }
                    

                    0_1553681770302_83c19cf6-eec2-4f06-a3ad-6a8b7c217b81-image.png

                    D Offline
                    D Offline
                    DavidM29
                    wrote on last edited by
                    #11

                    @J.Hilk
                    Oh that is perfect !
                    I was trying to make this kind of component whit 2 rectangle on top of each others.
                    I'm trying to implement that and mak sure it works on my target device.

                    1 Reply Last reply
                    0
                    • J.HilkJ J.Hilk

                      @DavidM29
                      ok, time to dig in my bag of tricks ;)
                      I present RoundedRectangle.qml

                      import QtQuick 2.11
                      
                      Item {
                          id:root
                      
                          property color color: "lightgrey"
                          onColorChanged: canVas.requestPaint()
                      
                          property int radius: root.height/3
                          onRadiusChanged: canVas.requestPaint()
                      
                          property bool topLeftCorner: true
                          property bool topRightCorner: false
                          property bool bottomRightCorner: true
                          property bool bottomLeftCorner: false
                      
                          onTopLeftCornerChanged: canVas.requestPaint()
                          onTopRightCornerChanged: canVas.requestPaint()
                          onBottomRightCornerChanged: canVas.requestPaint()
                          onBottomLeftCornerChanged: canVas.requestPaint()
                      
                          property color borderColor: "black"
                          onBorderColorChanged: canVas.requestPaint()
                      
                          property int borderWidth: 1
                      
                          Canvas {
                              id:canVas
                              anchors.fill: parent
                      
                              onPaint: {
                                  var context = getContext("2d");
                                  context.reset()
                                  context.beginPath();
                      
                                  //Start position
                                  context.moveTo(0,height / 2)
                      
                                  //topLeftCorner
                                  if(topLeftCorner){
                                      context.lineTo(0,radius)
                                      context.arcTo(0,0,radius, 0, radius);
                                  } else {
                                      context.lineTo(0,0)
                                  }
                      
                                  //topRightCorner
                                  if(topRightCorner){
                                      context.lineTo(width - radius, 0)
                                      context.arcTo(width, 0, width, radius, radius)
                                  } else {
                                      context.lineTo(width, 0)
                                  }
                      
                                  //bottomRightCorner
                                  if(bottomRightCorner) {
                                      context.lineTo(width, height-radius)
                                      context.arcTo(width, height, width - radius, height, radius)
                                  } else {
                                      context.lineTo(width, height)
                                  }
                      
                                  //bottomLeftCorner
                                  if(bottomLeftCorner) {
                                      context.lineTo(radius, height)
                                      context.arcTo(0, height, 0, height - radius, radius)
                                  } else {
                                      context.lineTo(0, height)
                                  }
                      
                                  //Close path
                                  context.lineTo(height / 2)
                                  context.closePath()
                      
                                  //Draw border
                                  context.lineWidth = borderWidth
                                  context.strokeStyle = borderColor
                                  context.stroke()
                      
                                  //Draw background
                                  context.fillStyle = color
                                  context.fill();
                              }
                          }
                      }
                      

                      to be used as:

                      import QtQuick 2.9
                      import QtQuick.Window 2.2
                      
                      Window {
                          visible: true
                          width: 640
                          height: 200
                          title: qsTr("Hello World")
                      
                          Rectangle {
                              id: frame
                      
                              anchors.centerIn: parent
                              height: parent.height*2/3
                              width:  parent.width *2/3
                      
                              radius: height/2
                      
                              color: "lightgrey"
                      
                      
                              ListView{
                                  id: lView
                      
                                  anchors.fill: parent
                                  model: [1,2,3]
                      
                                  orientation: ListView.Horizontal
                      
                                  clip:  true
                      
                                  delegate: RoundedRectangle{
                                      width: lView.width/lView.count
                                      height: lView.height
                                      color: lView.currentIndex == index ? "red" : "transparent"
                      
                                      radius: frame.radius
                                      borderColor: "transparent"
                                      topLeftCorner: index == 0
                                      topRightCorner: index == 2
                                      bottomRightCorner: index ==2
                                      bottomLeftCorner: index == 0
                      
                                      Text {
                                          anchors.centerIn: parent
                                          text: modelData
                                      }
                      
                                      MouseArea{
                                          anchors.fill: parent
                                          onClicked:{
                                              lView.currentIndex = index
                                          }
                                      }
                                  }
                              }
                          }
                      }
                      

                      0_1553681770302_83c19cf6-eec2-4f06-a3ad-6a8b7c217b81-image.png

                      D Offline
                      D Offline
                      DavidM29
                      wrote on last edited by
                      #12

                      @J.Hilk
                      It works like a charm !
                      Thank you very much ! I never used any canvas I will have a look into it it seems to be a good tool.

                      1 Reply Last reply
                      2

                      • Login

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