无法单击 MouseArea 下面的按钮
Can't click button below a MouseArea
这里我有一个矩形,它是父矩形和子矩形。子矩形有一个 MouseArea
允许您滑动子矩形。现在,我想在父矩形上有一个按钮(在子矩形和 MouseArea
下方),即使子矩形覆盖了按钮,我也想单击该按钮。这是一个例子
import QtQuick 2.15
import QtQuick.Window 2.0
import QtQuick.Controls 2.15
Window {
visible: true
width: 800
height: 800
Rectangle {
id: root
anchors.fill: parent
color: "yellow"
Button {
id: button1
x: 314
y: 182
text: qsTr("Button")
onClicked: console.log("Hello")
}
Rectangle {
id: panel
width: parent.width
height: parent.height * 0.8
radius: 20
color: "orange"
opacity: 0.2
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: panel
drag.minimumY: 0
drag.maximumY: 0
drag.minimumX: -panel.width
drag.maximumX: 0
onReleased: {
//if the panel is swiped more than 30% it will hide
//else it will go back to the original position
//this makes a pretty nice effect :)
if (panel.x < -panel.width * 0.3) {
//we need to make sure that a state change happens to
//fire the transition animation
root.state = "show"
root.state = "hide"
}
else {
root.state = "hide"
root.state = "show"
}
}
}
}
Rectangle {
id: button
width: 45
height: width
radius: 5
color: "lightblue"
anchors.bottom: parent.bottom
anchors.left: parent.left
MouseArea {
anchors.fill: parent
onClicked: {
root.state = root.state === "show" ? "hide" : "show"
}
}
}
state: "show"
states: [
State {
name: "hide"
PropertyChanges { target: panel; x: -panel.width }
},
State {
name: "show"
PropertyChanges { target: panel; x: 0 }
}
]
transitions: Transition {
NumberAnimation {
target: panel
property: "x"
duration: 1000
easing.type: Easing.OutCubic
}
}
}
}
如何在不滑动子矩形的情况下单击按钮?
最简单的解决方案是将 button1 放在面板下方。像这样
Rectangle {
id: panel
width: parent.width
height: parent.height * 0.8
radius: 20
color: "orange"
opacity: 0.2
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: panel
drag.minimumY: 0
drag.maximumY: 0
drag.minimumX: -panel.width
drag.maximumX: 0
onReleased: {
//if the panel is swiped more than 30% it will hide
//else it will go back to the original position
//this makes a pretty nice effect :)
if (panel.x < -panel.width * 0.3) {
//we need to make sure that a state change happens to
//fire the transition animation
root.state = "show"
root.state = "hide"
}
else {
root.state = "hide"
root.state = "show"
}
}
}
}
Button {
id: button1
x: 314
y: 182
text: qsTr("Button")
onClicked: console.log("Hello")
}
首先你需要在mouseArea中检测拖动是否处于活动状态,如果拖动未处于活动状态则检测触发鼠标按下事件的点是否也在按钮 1 在 面板 下方。您可以使用 Item
的 mapToItem 方法来做到这一点。如果是这种情况,那么您可以手动设置 button1 pressed
可视化。
然后当 released
事件被触发时,你会检测你是否仍在 button1 内并发出特殊信号,例如buttonBelowClicked
。该信号需要通过信号链连接到 button1 clicked
信号。
请注意,您需要始终在 mouseArea onReleased 中重置 button1 按下的可视化,因为您可能已经开始 panel 从 button1 的顶部拖动并且按钮显示按下的可视化但是然后拖动被启用...
Window {
visible: true
width: 800
height: 800
Rectangle {
id: root
anchors.fill: parent
color: "yellow"
Button {
id: button1
x: 314
y: 182
text: qsTr("Button")
onClicked: console.log("Hello")
Component.onCompleted: mouseArea.buttonBelowClicked.connect(clicked)
}
Rectangle {
id: panel
width: parent.width
height: parent.height * 0.8
radius: 20
color: "orange"
opacity: 0.2
MouseArea {
id: mouseArea
signal buttonBelowClicked
anchors.fill: parent
drag.target: panel
drag.minimumY: 0
drag.maximumY: 0
drag.minimumX: -panel.width
drag.maximumX: 0
onPressed: {
if (!drag.active) {
if (isPointInsideButton1(mouse.x, mouse.y)) {
button1.down = true
}
}
}
onReleased: {
if (!drag.active) {
if (isPointInsideButton1(mouse.x, mouse.y)) {
buttonBelowClicked()
}
} else {
if (panel.x < -panel.width * 0.3) {
root.state = "show"
root.state = "hide"
}
else {
root.state = "hide"
root.state = "show"
}
}
button1.down = undefined
}
function isPointInsideButton1(x, y) {
const mapped = panel.mapToItem(button1, x, y)
if (button1.contains(Qt.point(mapped.x, mapped.y))) {
return true
}
return false
}
}
}
Rectangle {
id: button
width: 45
height: width
radius: 5
color: "lightblue"
anchors.bottom: parent.bottom
anchors.left: parent.left
MouseArea {
anchors.fill: parent
onClicked: {
root.state = root.state === "show" ? "hide" : "show"
}
}
}
state: "show"
states: [
State {
name: "hide"
PropertyChanges { target: panel; x: -panel.width }
},
State {
name: "show"
PropertyChanges { target: panel; x: 0 }
}
]
transitions: Transition {
NumberAnimation {
target: panel
property: "x"
duration: 1000
easing.type: Easing.OutCubic
}
}
}
}
这里我有一个矩形,它是父矩形和子矩形。子矩形有一个 MouseArea
允许您滑动子矩形。现在,我想在父矩形上有一个按钮(在子矩形和 MouseArea
下方),即使子矩形覆盖了按钮,我也想单击该按钮。这是一个例子
import QtQuick 2.15
import QtQuick.Window 2.0
import QtQuick.Controls 2.15
Window {
visible: true
width: 800
height: 800
Rectangle {
id: root
anchors.fill: parent
color: "yellow"
Button {
id: button1
x: 314
y: 182
text: qsTr("Button")
onClicked: console.log("Hello")
}
Rectangle {
id: panel
width: parent.width
height: parent.height * 0.8
radius: 20
color: "orange"
opacity: 0.2
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: panel
drag.minimumY: 0
drag.maximumY: 0
drag.minimumX: -panel.width
drag.maximumX: 0
onReleased: {
//if the panel is swiped more than 30% it will hide
//else it will go back to the original position
//this makes a pretty nice effect :)
if (panel.x < -panel.width * 0.3) {
//we need to make sure that a state change happens to
//fire the transition animation
root.state = "show"
root.state = "hide"
}
else {
root.state = "hide"
root.state = "show"
}
}
}
}
Rectangle {
id: button
width: 45
height: width
radius: 5
color: "lightblue"
anchors.bottom: parent.bottom
anchors.left: parent.left
MouseArea {
anchors.fill: parent
onClicked: {
root.state = root.state === "show" ? "hide" : "show"
}
}
}
state: "show"
states: [
State {
name: "hide"
PropertyChanges { target: panel; x: -panel.width }
},
State {
name: "show"
PropertyChanges { target: panel; x: 0 }
}
]
transitions: Transition {
NumberAnimation {
target: panel
property: "x"
duration: 1000
easing.type: Easing.OutCubic
}
}
}
}
如何在不滑动子矩形的情况下单击按钮?
最简单的解决方案是将 button1 放在面板下方。像这样
Rectangle {
id: panel
width: parent.width
height: parent.height * 0.8
radius: 20
color: "orange"
opacity: 0.2
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: panel
drag.minimumY: 0
drag.maximumY: 0
drag.minimumX: -panel.width
drag.maximumX: 0
onReleased: {
//if the panel is swiped more than 30% it will hide
//else it will go back to the original position
//this makes a pretty nice effect :)
if (panel.x < -panel.width * 0.3) {
//we need to make sure that a state change happens to
//fire the transition animation
root.state = "show"
root.state = "hide"
}
else {
root.state = "hide"
root.state = "show"
}
}
}
}
Button {
id: button1
x: 314
y: 182
text: qsTr("Button")
onClicked: console.log("Hello")
}
首先你需要在mouseArea中检测拖动是否处于活动状态,如果拖动未处于活动状态则检测触发鼠标按下事件的点是否也在按钮 1 在 面板 下方。您可以使用 Item
的 mapToItem 方法来做到这一点。如果是这种情况,那么您可以手动设置 button1 pressed
可视化。
然后当 released
事件被触发时,你会检测你是否仍在 button1 内并发出特殊信号,例如buttonBelowClicked
。该信号需要通过信号链连接到 button1 clicked
信号。
请注意,您需要始终在 mouseArea onReleased 中重置 button1 按下的可视化,因为您可能已经开始 panel 从 button1 的顶部拖动并且按钮显示按下的可视化但是然后拖动被启用...
Window {
visible: true
width: 800
height: 800
Rectangle {
id: root
anchors.fill: parent
color: "yellow"
Button {
id: button1
x: 314
y: 182
text: qsTr("Button")
onClicked: console.log("Hello")
Component.onCompleted: mouseArea.buttonBelowClicked.connect(clicked)
}
Rectangle {
id: panel
width: parent.width
height: parent.height * 0.8
radius: 20
color: "orange"
opacity: 0.2
MouseArea {
id: mouseArea
signal buttonBelowClicked
anchors.fill: parent
drag.target: panel
drag.minimumY: 0
drag.maximumY: 0
drag.minimumX: -panel.width
drag.maximumX: 0
onPressed: {
if (!drag.active) {
if (isPointInsideButton1(mouse.x, mouse.y)) {
button1.down = true
}
}
}
onReleased: {
if (!drag.active) {
if (isPointInsideButton1(mouse.x, mouse.y)) {
buttonBelowClicked()
}
} else {
if (panel.x < -panel.width * 0.3) {
root.state = "show"
root.state = "hide"
}
else {
root.state = "hide"
root.state = "show"
}
}
button1.down = undefined
}
function isPointInsideButton1(x, y) {
const mapped = panel.mapToItem(button1, x, y)
if (button1.contains(Qt.point(mapped.x, mapped.y))) {
return true
}
return false
}
}
}
Rectangle {
id: button
width: 45
height: width
radius: 5
color: "lightblue"
anchors.bottom: parent.bottom
anchors.left: parent.left
MouseArea {
anchors.fill: parent
onClicked: {
root.state = root.state === "show" ? "hide" : "show"
}
}
}
state: "show"
states: [
State {
name: "hide"
PropertyChanges { target: panel; x: -panel.width }
},
State {
name: "show"
PropertyChanges { target: panel; x: 0 }
}
]
transitions: Transition {
NumberAnimation {
target: panel
property: "x"
duration: 1000
easing.type: Easing.OutCubic
}
}
}
}