4
votes

I have a listview that displays a list of userdetails on right and profile pic on left which I get from back end. For downloading and loading the image I'm using a webviewsample image class from github and it works fine. Now I'm need to make the image round. As I searched through web I understand nine slicing is used to do this but I'm not sure how. Each of my listitem has a different background which changes randomly. Below are the sample image of what I have done and what I actually want.

This is my current list view

enter image description here

This is how I need it to be

enter image description here

This is the code of my custom list item that displays this view

Container {
            horizontalAlignment: HorizontalAlignment.Center
            verticalAlignment: VerticalAlignment.Center
            layout: StackLayout {
                orientation: LayoutOrientation.LeftToRight
            }

            Container {
                id:profileSubContainer 
                horizontalAlignment: HorizontalAlignment.Center
                verticalAlignment: VerticalAlignment.Center
                layout: DockLayout {

                }  


            WebImageView {
                id: profilePic
                url: profilePicture

                horizontalAlignment: HorizontalAlignment.Center
                verticalAlignment: VerticalAlignment.Center
                scalingMethod: ScalingMethod.AspectFit
                visible: (profilePic.loading == 1.0)

            }


            ImageView {
                id: defaultPic
                horizontalAlignment: HorizontalAlignment.Center
                verticalAlignment: VerticalAlignment.Center
                scalingMethod: ScalingMethod.AspectFit
                imageSource:  "asset:///Images/defaultProfile.png"
                visible:!profilePic.visible

            }


            layoutProperties: StackLayoutProperties 
            {
                spaceQuota: 1
            }
        }



            CustomButtonTextArea {
                id: userName
                layoutProperties: StackLayoutProperties {
                    spaceQuota: 2
                }
                text: username
                textEditable: false
                textAreaStyle: getStyle()

            }



    }
2
I don't know if it is possible in Cascades, but have you try OpacityMask?Jairo
As I checked I will need to import QtGraphicalEffects 1.0 in my qml but it shows unknown library, do you know what library will I have to include in my pro file so that I can access this?Francis F
Which version of Qt are you using? QtGraphicalEffects is only supported in Qt5.4.sam
I'm doing this in blackberry cascades using momentics. It uses cpp and qml.Francis F

2 Answers

3
votes

If you have older version of Qt where this isn't supported directly, a rather hackish way to do is this :

  1. Cut out a circular hole from the background image (Using Photoshop/GIMP etc.) and save it as a PNG.

enter image description here

  1. Now all you need to do is to arrange all the elements in such a way that it appears as if the profile pic has been cut out. If you place your profile pic first and then the background image, background image cover the profile pic, leaving only circular part from it visible (Note that it SHOULD be PNG for this to work).

Correct order will be :

   a. Profile Image
   b. Background Image
   c. Text 

You can either write these elements in that order or use the z value of elements.

Image // Background Image 
{
    z = 2;  
}

Image // Profile Image 
{
    z = 1; 
}

Text  
{
    z = 3; 
}

P.S. This is pseudo code, I hope you get the idea. I did something like this with qt 4.8 long back, and it worked liked a charm.


Edit 1.

In case you want to have background of random color instead of images (as you have asked in the comment), you can try to do this using Qt.

  1. Create the custom background with using QPainter or some similar class and some clipping mask to carve out the circular part.
  2. Expose this class as a Qml element.
  3. Use it for your case by passing random colors while drawing.

They talk of something similar here : http://qt-project.org/forums/viewthread/2066

P.S. Haven't tried it myself, but looks like a good direction if you are stuck otherwise.

1
votes

If you can't use OpacityMask because your version of Qt doesn't support QtGraphicalEffects, you could do the same trick with Canvas, that is supported since Qt 5.0.

Rectangle{
  id: root
  width: 400
  height: 400

  color: "gray"

  property string imageUrl: "./rabbid.jpg"

  Canvas{
    anchors{
        fill: parent
        margins: 50
    }

    Component.onCompleted:{
        loadImage(imageUrl); // Ready to be used in onPaint handler
    }

    onPaint:{
        console.log("Painting...");
        var context = getContext("2d");
        context.save();

        context.fillStyle = "black";
        context.arc(width/2, height/2, width/2, height/2, width);
        context.fill();

        context.globalCompositeOperation = "source-in";
        context.drawImage(root.imageUrl, 0, 0, width, height);

        context.restore();
    }
  }
}

The result:

Round image with canvas

Since Context.globalCompositeOperation = "source-in" is set, context operations will be done inside previous drawings. Take a look to Context2D for more info, and here for a graphical explanation of composite operations.