4

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()

            }



    }
Francis F
  • 3,157
  • 3
  • 41
  • 79
  • I don't know if it is possible in _Cascades_, but have you try [OpacityMask](http://doc.qt.io/qt-5/qml-qtgraphicaleffects-opacitymask.html)? – Jairo Dec 22 '14 at 07:37
  • 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 Dec 22 '14 at 10:23
  • Which version of Qt are you using? QtGraphicalEffects is only supported in Qt5.4. – sam Dec 23 '14 at 04:35
  • I'm doing this in blackberry cascades using momentics. It uses cpp and qml. – Francis F Dec 23 '14 at 05:50

2 Answers2

3

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.

Amit Tomar
  • 4,800
  • 6
  • 50
  • 83
  • Its a good idea, but as I mentioned earlier my background fills color randomly so a fixed background wouldnt do any good, so if there are 100 colors I will have to create 100 backgrounds like this one. Any other hakish way ? ;) – Francis F Dec 26 '14 at 11:41
1

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.

Jairo
  • 876
  • 7
  • 14
  • Thanks for the reply, but unfortunately cascades support Qt 4.8 and I can only import QtQuick 1.0 and not 2.0 which has the Canvas class. Is there any other library available that I can include it in cascades? – Francis F Dec 23 '14 at 08:56
  • Sorry, but I supposed that _Cascades_ support Qt 5.0 at least. I don't know any directly way to do it. May be you can use custom a class inherited from QDeclarativeImageProvider[http://qt-project.org/doc/qt-4.8/qdeclarativeimageprovider.html] to provide images to QML. When a image is requested you will return an image built with QPainter and the same steps described in my answer. – Jairo Dec 23 '14 at 09:18
  • The link you gave was broken. Do you have any other link for ref? – Francis F Dec 26 '14 at 11:50
  • Sorry, it ends with a bracket. [QDeclarativeImageProvider](http://qt-project.org/doc/qt-4.8/qdeclarativeimageprovider.html) – Jairo Dec 27 '14 at 12:21