Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qml more advanced shapes



  • Hi everyone,

    I want to create the material component fab center cut.
    4f393780-efe0-42e7-8d4f-6a79a3b90557-image.png

    I'm having problems with creating the underlying toolbar with the hole for the button.
    I thought about different ways:

    • Add a semi circle on top of the toolbar (for example with a rectangle and clip property)
      -> Problem: The rectangle will have it's own color ... that would be solvable, but I'm wondering if it's not possible to actually cut that semi circle part out of the toolbar instead of overlaying
    • Add an underlying circle for the button, or a border for the button
      -> Same problem as above + additionally there is also white space above the button then which is not optimal
    • Use Qt Shape and create a custom shape
      -> Difficult to make -> I haven't figured out how to use a toolbar with my custom shape
      -> The hole doesn't look great ( I have tried different anti alising things, but none worked)
      -> Probably ineffizient?

    And additionally with all solutions I was not able to create rounded edges for the hole (that's probably the least important aspect, but still it would intrerest me how to do that).

    • Perhaps I could also use an svg, but then I'm not so flexible with color, sizes anymore
      -> It seems like the solution if there is really no better option
        Shape {
            id: shape 
    
            property real btnRadius: 25
    
            y: 10
            width: parent.width; height: 40
    
            ShapePath {
                fillColor: "blue"
                strokeColor: "transparent"
                startX: shape.x; startY: shape.y
                PathLine { x: shape.x + shape.width/2 - shape.btnRadius; y: shape.y }
                
                PathArc {
                    x: shape.x + shape.width/2 + shape.btnRadius; y: shape.y
                    radiusX: shape.btnRadius; radiusY: shape.btnRadius
                    direction: PathArc.Counterclockwise
                }
    
                PathLine { x: shape.x + shape.width ; y: shape.y}
                PathLine { x: shape.x + shape.width ; y: shape.y + shape.height}
                PathLine { x: shape.x ; y: shape.y + shape.height}
            }
        }
    

    here is my shape try

    I would be really interested in a solution for this problem, but also some general advice. How to do custom shapes, what do I have to know performance wise etc.?

    Thanks a lot!

    Leon

    Edit: Another possible way would probably a custom C++ Type? I suppose that could be more effizient then.


  • Moderators

    @Leon_2001
    you can also use a Canvas element and draw the background yourself. shouldn't be too difficult for such a simple shape. then place a round button anchored centered on top of it



  • @raven-worx What is the difference to qml shape? What is better?

    I found one possible solution, even though I don't know if it's the best.

    ToolBar {
            id: bottomToolbar 
            layer.enabled: true 
            layer.effect: OpacityMask {
                maskSource: ToolbarShape {
                    width: bottomToolbar .width; height: bottomToolbar .height
                    radius: 30
                }
            }
    }
    

    And as the maskSource I used the Shape posted above


  • Qt Champions 2018

    I tried to do it by using QQuickPaintedItem, it looks better because you can make antialiasing actually work.
    QQuickPaintedItem has a similar API to Canvas but is in c++.

    I ended being a little carried away and implemented some animation as a proof-of-concept, but the important part is in the paint method of the NotchedRectantle class. I had to do some trigonometry to add the corner radius.

    Since the code is somewhat long I put it in a gist : https://gist.github.com/oKcerG/b9527a638b01523c3c9c06647d373338

    Here you can see it in action :
    QML NotchedRectangle



  • Hi @GrecKo ,

    thanks for that amazing input! It really lookes awsome :)

    I have just one further question: How is such an approach combinable with actually using a Toolbar from Qt Quick Controls 2?
    I know that the toolbar as it is (and on the picture) is not really special, but the normal toolbar provides theming and might change it look depending on the theme used. So I would like to still use the Qt Quick Controls 2 components.

    Above I have mentioned one way I came up with: Using a toolbar and setting the custom shape as an oppacity mask. I just tried this with your code as well and it works like a charm!
    I do wonder though, if this is the right way to do it?


Log in to reply