标签:qt quick android qt on android canvas qml
Android手机有个挺好的功能,它允许你往桌面上放窗口小部件(widget),有一个叫相框的小部件,可以让你选择一张相片,截取一部分,放在相框里。我桌面上就放了几个相框,里面是我女儿的照片,隔阵子换一换,挺喜欢。这次的实例受相框小部件启发而成,我称之为挖头像,先看看运行效果。
为了能够让PickThumb正常退出,我给QGuiApplication安装了事件过滤器,过滤BACK按键。下面是main.cpp文件:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QKeyEvent>
class KeyBackQuit: public QObject
{
public:
    KeyBackQuit(QObject *parent = 0)
        : QObject(parent)
    {}
    bool eventFilter(QObject *watched, QEvent * e)
    {
        switch(e->type())
        {
        case QEvent::KeyPress:
            if( ((QKeyEvent*)e)->key() == Qt::Key_Back )
            {
                e->accept();
                return true;
            }
            break;
        case QEvent::KeyRelease:
            if( ((QKeyEvent*)e)->key() == Qt::Key_Back )
            {
                e->accept();
                qApp->quit();
                return true;
            }
            break;
        default:
            break;
        }
        return QObject::eventFilter(watched, e);
    }
};
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    app.installEventFilter(new KeyBackQuit);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    return app.exec();
}
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.1
Window {
    visible: true
    width: 480;
    height: 320;
    minimumHeight: 320;
    minimumWidth: 480;
    color: "black";
    onWidthChanged: mask.recalc();
    onHeightChanged: mask.recalc();
    Image {
        id: source;
        anchors.fill: parent;
        fillMode: Image.PreserveAspectFit;
        visible: false;
        asynchronous: true;
        onStatusChanged: {
            if(status == Image.Ready){
                console.log("image loaded");
                mask.recalc();
            }
        }
    }
    FileDialog {
        id: fileDialog;
        title: "Please choose an Image File";
        nameFilters: ["Image Files (*.jpg *.png *.gif)"];
        onAccepted: {
            source.source = fileDialog.fileUrl;
        }
    }
    Canvas {
        id: forSaveCanvas;
        width: 128;
        height: 128;
        contextType: "2d";
        visible: false;
        z: 2;
        anchors.top: parent.top;
        anchors.right: parent.right;
        anchors.margins: 4;
        property var imageData: null;
        onPaint: {
            if(imageData != null){
                context.drawImage(imageData, 0, 0);
            }
        }
        function setImageData(data){
            imageData = data;
            requestPaint();
        }
    }
    Canvas {
        id: mask;
        anchors.fill: parent;
        z: 1;
        property real w: width;
        property real h: height;
        property real dx: 0;
        property real dy: 0;
        property real dw: 0;
        property real dh: 0;
        property real frameX: 66;
        property real frameY: 66;
        function calc(){
            var sw = source.sourceSize.width;
            var sh = source.sourceSize.height;
            if(sw > 0 && sh > 0){
                if(sw <= w && sh <=h){
                    dw = sw;
                    dh = sh;
                }else{
                    var sRatio = sw / sh;
                    dw = sRatio * h;
                    if(dw > w){
                        dh = w / sRatio;
                        dw = w;
                    }else{
                        dh = h;
                    }
                }
                dx = (w - dw)/2;
                dy = (h - dh)/2;
            }
        }
        function recalc(){
            calc();
            requestPaint();
        }
        function getImageData(){
            return context.getImageData(frameX - 64, frameY - 64,
 128, 128);
        }
        onPaint: {
            var ctx = getContext("2d");
            if(dw < 1 || dh < 1) {
                ctx.fillStyle = "#0000a0";
                ctx.font = "20pt sans-serif";
                ctx.textAlign = "center";
                ctx.fillText("Please Choose An Image File", 
width/2, height/2);
                return;
            }
            ctx.clearRect(0, 0, width, height);
            ctx.drawImage(source, dx, dy, dw, dh);
            var xStart = frameX - 66;
            var yStart = frameY - 66;
            ctx.save();
            ctx.fillStyle = "#a0000000";
            ctx.fillRect(0, 0, w, yStart);
            var yOffset = yStart + 132;
            ctx.fillRect(0, yOffset, w, h - yOffset);
            ctx.fillRect(0, yStart, xStart, 132);
            var xOffset = xStart + 132;
            ctx.fillRect(xOffset, yStart, w - xOffset, 132);
            //see through area
            ctx.strokeStyle = "red";
            ctx.fillStyle = "#00000000";
            ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.rect(xStart, yStart, 132, 132);
            ctx.fill();
            ctx.stroke();
            ctx.closePath ();
            ctx.restore();
        }
    }
    MultiPointTouchArea {
        anchors.fill: parent;
        minimumTouchPoints: 1;
        maximumTouchPoints: 1;
        touchPoints:[
            TouchPoint{
                id: point1;
            }
        ]
        onUpdated: {
            mask.frameX = point1.x;
            mask.frameY = point1.y;
            mask.requestPaint();
        }
        onReleased: {
            forSaveCanvas.setImageData(mask.getImageData());
            actionPanel.visible = true;
        }
        onPressed: {
            actionPanel.visible = false;
        }
    }
    Component {
        id: flatButton;
        ButtonStyle {
            background: Rectangle{
                implicitWidth: 70;
                implicitHeight: 30;
                border.width: control.hovered ? 2: 1;
                border.color: control.hovered ? "#c0c0c0" : "#909090";
                color: control.pressed ? "#a0a0a0" : "#707070";
            }
            label: Text {
                anchors.fill: parent;
                font.pointSize: 12;
                horizontalAlignment: Text.AlignHCenter;
                verticalAlignment: Text.AlignVCenter;
                text: control.text;
                color: (control.hovered && !control.pressed) ? 
"blue": "white";
            }
        }
    }
    Row {
        anchors.horizontalCenter: parent.horizontalCenter;
        anchors.bottom: parent.bottom;
        anchors.bottomMargin: 20;
        id: actionPanel;
        z: 5;
        spacing: 8;
        Button {
            style: flatButton;
            text: "Open";
            onClicked: fileDialog.open();
        }
        Button {
            style: flatButton;
            text: "Save";
            onClicked: {
                forSaveCanvas.save("selected.png");
                actionPanel.visible = false;
            }
        }
        Button {
            style: flatButton;
            text: "Cancel";
            onClicked: actionPanel.visible = false;
        }
    }
}
标签:qt quick android qt on android canvas qml
原文地址:http://blog.csdn.net/foruok/article/details/38778233