无法单击鼠标区域下方的按钮

Posted

技术标签:

【中文标题】无法单击鼠标区域下方的按钮【英文标题】:Can't click button below a MouseArea 【发布时间】:2021-09-23 20:51:11 【问题描述】:

这里我有一个矩形,它是父矩形和子矩形。子矩形有一个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
          
      
  

如何在不滑动子矩形的情况下单击按钮?

【问题讨论】:

将propogateComposedEvents 添加到 MouseArea 有帮助吗? @JarMan 将其作为属性添加到 MouseArea 似乎由于某种原因不起作用。我仍然无法点击按钮。 这是因为propagateComposedEvents 属性仅适用于其他MouseAreas 而不适用于快速控制按钮。一种解决方案是使用 Rectangle + Text + MouseArea 实现您自己的 Button 并使用propagateComposedEvents。但是,只有单击(释放)事件有效,您无法传播按下事件,并且在按下信号处理程序中将 mouse.accepted 设置为 false 会中断拖放(通过拖动移动面板)。 【参考方案1】:

首先你需要在 mouseArea 中检测拖动是否处于活动状态,如果拖动未处于活动状态,则检测触发鼠标按下事件的点是否也在 button1 em> 在面板下方。您可以使用Item 的mapToItem 方法来做到这一点。如果是这种情况,那么您可以手动设置 button1 pressed 可视化。

然后,当released 事件被触发时,您会检测您是否仍在 button1 内并发出特殊信号,例如buttonBelowClicked。该信号需要通过信号链连接到 button1 clicked 信号。

请注意,您需要始终在 mouseArea onReleased 中重置 button1 按下的可视化,因为您可能已经启动了 panelbutton1 顶部拖动,按钮显示按下的可视化效果,但随后启用拖动...

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.buttonBelowClicked.connect(clicked)【参考方案2】:

最简单的解决方案是将 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")
  

【讨论】:

我无法将按钮放在其他地方。有多个按钮需要保持在原位。

以上是关于无法单击鼠标区域下方的按钮的主要内容,如果未能解决你的问题,请参考以下文章

易语言中!模拟鼠标点击无效

让flash完全透明化,不响应鼠标点击呢?

MFC中如何在指定的区域响应鼠标单击事件

如何使用 Python 图像库裁剪通过鼠标单击选择的区域?

鼠标悬停事件的JS问题以显示额外的按钮

在裁剪区域外禁用鼠标单击