2013-08-08 37 views
18

Tôi muốn triển khai kịch bản sau đây trong QML.Làm thế nào để bao gồm các sự kiện di chuột con trong MouseArea cha mẹ bằng cách sử dụng QML?

Scenario


Đây là một mẫu/đơn giản hóa đại biểu cho ListView yếu tố:

Component { 
    Item { 
     id: container 
     MouseArea { 
     anchors.fill: parent 
     hoverEnabled: true 

     onClicked: { 
      container.ListView.view.currentIndex = index 
      container.forceActiveFocus(); 
     } 
     onEntered: { 
      actionList.state = "SHOW"; 
      myItem.state = "HOVER" 
     } 
     onExited: { 
      actionList.state = "HIDE"; 
      myItem.state = "NORMAL" 
     } 
     Rectangle { 
      id: myItem 
      color: "gray" 
      anchors.fill: parent 
      Row { 
       id: actionList 
       spacing: 5; anchors.fill: parent 
       Image { 
        id: helpAction 
        source: "" //Some image address 
        width: 16; height: 16; fillMode: Image.PreserveAspectFit 
        states: [ 
         State { 
          name: "NORMAL" 
          PropertyChanges { target: helpAction; opacity: 0.7 } 
         }, 
         State { 
          name: "HOVER" 
          PropertyChanges { target: helpAction; opacity: 1.0 } 
         } 
        ] 
        MouseArea { 
         hoverEnabled: true 
         anchors.fill: parent 

         onEntered: { 
          parent.state = "HOVER"; 
         } 
         onExited: { 
          parent.state = "NORMAL"; 
         } 
        } 
        states: [ 
         State { 
          name: "SHOW" 
          PropertyChanges { target: actionList; visible: false } 
         }, 
         State { 
          name: "HIDE" 
          PropertyChanges { target: actionList; visible: true } 
         } 
        ] 
       } 

       //Other action buttons... 

       states: [ 
        // `NORMAL` and `HOVER` states definition here... 
       ] 
      } 
     } 
    } 
} 

Nhưng tôi có một vấn đề với MouseArea.
Bên trong MouseArea (nút hành động) không hoạt động bình thường cho sự kiện entered. Khi chuột vào nút hành động, bên ngoài MouseArea cháy exited sự kiện.

Có lỗi trong mã của tôi không? Nói chung, làm thế nào tôi có thể thực hiện một kịch bản như vậy trong QML?

Trả lời

22

tôi đã phải đối mặt bởi sự cố này giống nhau, và tình cờ gặp câu trả lời trong QtQuick 5.0 documentation for MouseArea . Câu trả lời cho điều này thực sự khá đơn giản.

Nếu bạn muốn bao gồm các sự kiện chuột con di chuột trong cha mẹ của bạn MouseArea, làm cho bạn trẻ MouseArea một đứa trẻ của phụ huynh MouseArea:

MouseArea { 
    id: parent 

    MouseArea { 
     id: child 
    } 
} 

Kể từ khi tôi có một tùy chỉnh Widget kiểu đó sẽ được sử dụng như phụ huynh xem, tôi đã kết thúc với thuộc tính default là con của MouseArea:

Item { 
    default property alias children: mouseArea.data 

    MouseArea { 
     id: mouseArea 
    } 
} 
+5

Tôi không chắc chắn tại sao! Bạn có thể thấy rằng mã mẫu của tôi đã sử dụng mẫu này, nhưng không hoạt động !! Tuy nhiên nó hoạt động ngay bây giờ bằng cách sử dụng Qt5.2.0 :) Đối với người dùng quan tâm khác, chỉ cần giữ bên trong 'MouseArea' bên trong một bên ngoài. Kiểm tra kỹ cho 'hoverEnabled: true' và nó sẽ hoạt động. –

+0

Tôi không hiểu một phần câu trả lời đầy đủ. Phần đầu tiên: ý của bạn là gì? Nếu bạn muốn bao gồm các sự kiện di chuột con chuột trong tổ tiên MouseArea của bạn, làm cho bạn con MouseArea là một con trực tiếp của cha mẹ MouseArea'? Và nếu vậy, ví dụ thứ hai của bạn hoạt động như thế nào, xem xét nó chỉ chứa * một * MouseArea? –

+0

Tôi đã có một trường hợp sử dụng mà một 'CheckBox' là trên một hàng của một danh sách, nơi hàng danh sách sẽ nổi bật trên di chuột. Lúc đầu, tôi có 'CheckBox' và' MouseArea' ở cùng một mức, nhưng khi 'CheckBox' được lồng trong' MouseArea' và 'hoverEnabled: true' được áp dụng cho' MouseArea' kèm theo, điều này cho phép các hiệu ứng di chuột cho 'CheckBox', câu trả lời này hoạt động với Qt5.9. – Kasheen

3

Iv'e đã ​​thử một vài điều nhưng có vẻ như không thể di chuột qua hai MouseArea cùng một lúc. preventStealingpropagateComposedEvents dường như chỉ hoạt động khi bạn có sự kiện nhấp chuột. Nhưng từ bên trong MouseArea bạn có thể kích hoạt tín hiệu entered() của tín hiệu kia. Một cái gì đó như thế này:

import QtQuick 2.1 

Rectangle { 
    width: 500 
    height: 500 

    Rectangle { 
     width:300 
     height: 300 
     color: "red" 

     MouseArea { 
      id: big 
      anchors.fill: parent 
      hoverEnabled:true 
      onEntered: { 
       console.log("ENTERED BIG mousearea"); 
      } 
      onExited: { 
       console.log("EXITED BIG mousearea"); 
      } 
     } 

     Rectangle { 
      anchors.centerIn: parent 
      height: 100 
      width: 100 
      color: "green" 

      MouseArea { 
       anchors.fill: parent 
       hoverEnabled:true 
       onEntered: { 
        console.log("ENTERED small mousearea"); 
        big.entered(); 
       } 
       onExited: { 
        console.log("EXITED small mousearea"); 
        big.exited(); 
       } 
      } 
     } 
    } 
} 

Vấn đề là các exited() tín hiệu từ chứa MouseArea sẽ được gọi trước khi gọi các entered() trở lại. Vì vậy, bạn có thể cần phải "trì hoãn" thay đổi trạng thái trong exited() chỉ để đảm bảo bạn thực sự muốn ẩn các nút tác vụ của mình. Một giải pháp khác là lưu vị trí chuột hiện tại và ẩn các nút CHỈ nếu exited() được gọi bằng chuột ở một trong các đường viền của nó.

+0

Tốt nhưng chưa hoàn thành. Làm thế nào tôi có thể thực hiện đề xuất thứ hai? Có thể không? –

+0

Trong 'onExited()', bạn có thể sử dụng 'mouseX' và' mouseY' để có vị trí chuột hiện tại và đoán nếu bạn đang ở trên biên giới của mousearea lớn của bạn (dựa trên 'x',' y', 'chiều cao của chính nó 'và' chiều rộng'). Tôi đã thử nó nhưng có một số vấn đề mà 'mouseX' là tắt khi bạn di chuyển chuột của bạn một cách nhanh chóng. Tuy nhiên đó là bước đầu tiên – koopajah

+0

Có tôi đã thử đề xuất của bạn. Nhưng khi di chuột nhanh, mouseX không chính xác (ví dụ 'onExited' được kích hoạt nhưng chuột positin là' (14,57) '). Cũng vấn đề tương tự bằng cách sử dụng 'onPositionChanged'. –

1

Hãy thử điều này:

  • thêm một tín hiệu tới khu vực bên trong đó là phát ra trên chuột nhập.
  • Kết nối tín hiệu với khu vực bên ngoài.
  • Tín hiệu làm cho khu vực bên ngoài vào trạng thái di chuột.

Thoát chuột trên cả hai vẫn sẽ hủy trạng thái di chuột. Khi bạn di chuyển chuột ra khỏi các điều khiển, nó sẽ hoạt động chính xác mà không cần thêm bất kỳ mã nào

+0

Tôi đã thử nghiệm nó, nhưng không phải bằng cách sử dụng tín hiệu. Tôi đã sử dụng tín hiệu 'onEntered' ở bên trong' MouseArea'. Nếu chuột đi vào bên trong 'MouseArea', con chuột bên ngoài sẽ được di chuột. NHƯNG, có một vấn đề khác! Tín hiệu 'onExited' sẽ kích hoạt sớm hơn tín hiệu' onEntered'! Đường viền 'onExited' nằm trong biên giới' onEnterited'. –

+0

Tôi cũng nghĩ về điều này và quyết định xem các tín hiệu có sai trật tự không. Có lẽ thêm mã vào mục bên ngoài để giám sát các mục con để di chuột? – Jay

+0

Thnks @Jay. Không thành công –

4

tạo trạng thái cho từng trạng thái của các phần tử trong dạng xem, sau đó bạn có thể sử dụng các câu lệnh như báo cáo hoặc trường hợp để thay đổi các thuộc tính này. Cố gắng không để thiết lập các yếu tố của bạn lên để làm việc trên MouseArea nhưng trên tài sản Và thiết lập các thuộc tính Elements để làm việc trên các thuộc tính thiết lập Tôi hy vọng rằng điều này sẽ giúp nếu không ở đây là ví dụ:

EDIT Tôi đã thêm màu sắc để minh bạch . nếu không có con chuột như vậy bao giờ hết. Nếu tôi đã sử dụng một hình ảnh tôi sẽ sử dụng opacity sau đó thêm một loạt các hành vi cũng Nhưng đây là một công tác

dụ

import QtQuick 2.0 
Rectangle { 
    width: 360 
    height: 360 
    property string state1:"OutMouse" 
    property string state2: "OutMouse" 
    property string state3: "OutMouse" 
    property string state4: "OutMouse" 
    Rectangle{ 
     id:blueRec 
     width: parent.width 
     height: parent.height/6 
     color: state1 === "InMouse" ? "blue" : "green" 
     MouseArea{ 
      anchors.fill: blueRec 
      hoverEnabled: true 
      onEntered: state1 = "InMouse" 
      onExited: { 
       if (state1 === state2 || state3 || state4){ 
        state1 = "InMouse" 
       } 
       if(state1 !== state2 || state3 || state4) 
       { 
        state1 = "OutMouse" 
       } 
      } 
     } 
     Text { 
      text: state1=== "InMouse"? qsTr("foo") :"bar" 
      anchors.centerIn: blueRec 
     } 
     Row{ 
      width: parent.width 
      height: parent.height/4 

      spacing: 2 
      anchors{ 
       left: parent.left 
       verticalCenter: blueRec.verticalCenter 
       leftMargin: blueRec.width/12 
      } 
      Rectangle{ 
       id: rec1 
       height: parent.height; 
       width: height 
       color: { 
        if (state3 === "InMouse") 
         return "gray" 
        if (state1 === "OutMouse") 
         return "transparent" 
        else 
         return "white"} 
       MouseArea{ 
        id: rec1M 
        anchors.fill: parent 
        hoverEnabled: true 
        onEntered:{ 
         state1 = "InMouse" 
         state2 = "InMouse" 
        } 
        onExited: state2 = "OutMouse" 
       } 
      } 

      Rectangle{ 
       id: rec2 
       height: parent.height ; 
       width: height 
       color: { 
        if (state3 === "InMouse") 
         return "gray" 
        if (state1 === "OutMouse") 
         return "transparent" 
        else 
         return "white" 
       } 
       MouseArea{ 
        id: rec2M 
        anchors.fill: parent 
        hoverEnabled: true 
        onEntered:{ 
         state1 = "InMouse" 
         state3 = "InMouse" 
        } 
        onExited: state3 = "OutMouse" 
       } 
      } 

      Rectangle{ 
       id: rec3 
       height: parent.height; 
       width: height 
       color:{ 
        if (state4 === "InMouse") 
         return "gray" 
        if (state1 === "OutMouse") 
         return "transparent" 
        else 
         return "white" 
       } 
       MouseArea{ 
        id: rec3M 
        anchors.fill: parent 
        hoverEnabled: true 
        onEntered:{ 
         state4 = "InMouse" 
         state1 = "InMouse" 
        } 
        onExited: state4 = "OutMouse" 
       } 
      } 
     } 
    } 
} 
Các vấn đề liên quan