Item の containmentMask にマスクオブジェクトを設定すると MouseArea のイベントをマスクできます。マスクオブジェクトとは以下を実装した QObject を継承したオブジェクトです。
Q_INVOKABLE QObject::contains(const QPoint& point)
QObject を継承したマスクオブジェクトは以下のようにして作成します。
main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QLineF>
class CircleMask : public QObject
{
Q_OBJECT
Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
public:
explicit CircleMask(QObject* parent = 0) : QObject(parent) {}
~CircleMask() {}
qreal radius() const {
return d.radius;
}
void setRadius(qreal radius)
{
if (d.radius == radius) {
return;
}
d.radius = radius;
emit radiusChanged();
}
Q_INVOKABLE bool contains(const QPointF& point) const
{
const QPointF center(d.radius, d.radius);
const QLineF line(center, point);
return line.length() <= d.radius;
}
signals:
void radiusChanged();
private:
struct {
qreal radius;
} d;
};
int main(int argc, char** argv)
{
QGuiApplication app(argc, argv);
qmlRegisterType("Mask", 1, 0, "CircleMask");
QQmlApplicationEngine engine;
engine.load(QUrl("qrc:/main.qml"));
return app.exec();
}
#include "main.moc"
contains() では point が半径 radius の円の内側かどうかを判定しています。
mail.qml:
import QtQuick 2.11
import QtQuick.Window 2.10
import Mask 1.0
Window {
id: window
visible: true
minimumWidth: 300
minimumHeight: 300
color: "white"
Rectangle {
id: circle
width: window.width/2; height: width
anchors.centerIn: parent
radius: width/2
color: "red"
border.width: circleMouseArea.containsMouse ? 4 : 0
border.color: "firebrick"
MouseArea {
id: circleMouseArea
anchors.fill: parent
hoverEnabled: true
containmentMask: CircleMask {
radius: circle.radius
}
onPressed: {
parent.color = "green";
}
onReleased: {
parent.color = "red";
}
}
}
}
MouseArea の containmentMask に半径を設定した CircleMask オブジェクトを設定すれば円の内側だけでマウスが反応するようになります。
|
円の内側だけでマウスが反応する |
Qt Quick Shapes の Shape をオブジェクトマスクに使えます。containsMode を Shape.FillContains に設定すると内側だけに反応するようになります。
shapedmousearea.qml:
import QtQuick 2.11
import QtQuick.Shapes 1.11
import QtQuick.Window 2.10
Window {
id: window
visible: true
minimumWidth: 300
minimumHeight: 300
color: "white"
Shape {
id: circle
readonly property real radius: 60
anchors.fill: parent
layer.enabled: true
layer.smooth: true
layer.textureSize: Qt.size(2*width, 2*height)
vendorExtensionsEnabled: false
containsMode: Shape.FillContains
ShapePath {
id: halfArch
strokeWidth: -1
fillColor: "green"
startX: circle.width/2 - circle.radius
startY: circle.height/2 - circle.radius
PathArc {
id: halfPathArc
x: circle.width/2 + circle.radius
y: circle.height/2 + circle.radius
radiusX: circle.radius
radiusY: circle.radius
}
}
}
MouseArea {
id: circleMouseArea
anchors.fill: circle
containmentMask: circle
onPressed: {
halfArch.fillColor = "red";
}
onReleased: {
halfArch.fillColor = "green";
}
}
}
こちらも MouseArea の containmentMask に Shape オブジェクトをマスクとして設定します。こうすると半円の内側だけでマウスに反応します。Qt Quick Shapes を使えば不定形図形の描画とマスクに同じ Shape オブジェクトを使えます。
|
半円の内側だけでマウスに反応する |
参考情報
containmentMask
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。