Qt QML - 在 QML 中识别超出鼠标区域范围

Posted

技术标签:

【中文标题】Qt QML - 在 QML 中识别超出鼠标区域范围【英文标题】:Qt QML - Recognize out of mousearea scope in QML 【发布时间】:2015-12-07 11:54:16 【问题描述】:

我创建了一个 qtquick 2.4 文件,在该文件中我使用了 TextInput 和 ListView。我想要的是当用户在 TextInput 中写一些东西时,ListView 出现在 TextInput 下方以向用户建议一些单词,当用户点击 ListView 或 TextInput 的 MouseArea 时,在 qtquick 文件的任何位置,ListView 被隐藏。但我的问题是我不知道当用户单击 ListView 或 TextInput 的 MouseArea 时应该如何隐藏列表视图?我尝试使用 Menu 组件而不是 ListView 但由于使用 Menu 组件时出现问题,我无法使用它。

Rectangle
    height: 400;
    width: 400;

Rectangle 
id: cbxRoot;
width: 150
height: 45;
color: "white";
border.color: "black";
radius: 5;
property bool cbxtriggered: false;

TextInput

    id: cbxTextBox;
    anchors.top: parent.top;
    width: 150
    height:45 ;
    verticalAlignment: Text.AlignVCenter;
    color: "black";
    horizontalAlignment: Text.AlignHCenter;
    clip: true;
    readOnly: false;

    MouseArea
    
        id: cbxMouseArea;
        anchors.fill: parent;
        enabled: true;

        onClicked:
        
            cbxTextBox.focus = true;
            if(cbxRoot.cbxtriggered)
            
                cbxRoot.cbxtriggered = false;
            
            else
            
                cbxRoot.cbxtriggered = true;
            
        
    

    selectByMouse: true;

    Keys.onPressed:
    
        cbxRoot.cbxtriggered = true;
    

    onTextChanged:
    
        var maxChar = 30;
        var txtInput = cbxTextBox;
        if(txtInput.text.length > maxChar)
        
            txtInput.text = txtInput.text.substring(0,maxChar);
            txtInput.cursorPosition = maxChar;
        
    


ListModel

    id: cbxListModel;
    ListElement  name: "Theme"; number: 0 
    ListElement  name: "Theme"; number: 1 
    ListElement  name: "Theme"; number: 2 
    ListElement  name: "Theme"; number: 3 
    ListElement  name: "Theme"; number: 4 


ListView

    id: cbxListView;
    anchors.top : cbxTextBox.bottom;
    visible: cbxRoot.cbxtriggered;
    focus: true;
    displayMarginBeginning: contentHeight;
    displayMarginEnd: contentHeight;
    spacing: 2;
    model: cbxListModel;
    delegate: Text 
          text: name + ", " + number
      

    clip: false;
    width: cbxRoot.width;
    height: 70;



【问题讨论】:

如果它是一个可重用的组件,您应该处理focus 状态并据此更改可见性。您可以使用forceActiveFocus() 强制对焦。如果它不是一个组件,您可以在TextInput 之外添加一个MouseArea 并使用它来取消焦点。你的情况是哪一种? 感谢您的快速回复。我使用了一个可重用的组件,但是我的 qml 文件中有多个组件,似乎很难主动关注我的 qml 文件中的每个组件。我想要一个更简单的方法来处理它。 Qt quick 中的焦点管理有时真的是一团糟。我同意你的看法。但是,在这种情况下,它应该不是一个大问题。我将在今天晚些时候提供一个示例,看看它是否能满足您的需求。 【参考方案1】:

尝试在输入控件下方创建一个MouseArea(在本例中为InputTextListView),无论单击什么,都应取消输入模式。鼠标事件被输入控件处理和吃掉的方式,但它们之外的事件由MouseArea处理。看看这段代码:

import QtQuick 2.2

Rectangle
    height: 400
    width: 400
    border.width: 5

    property alias inputFocused: inputTextBox.focus

    ListModel
        id: cbxListModel;
        ListElement  name: "Theme"; number: 0 
        ListElement  name: "Theme"; number: 1 
        ListElement  name: "Theme"; number: 2 
        ListElement  name: "Theme"; number: 3 
        ListElement  name: "Theme"; number: 4 
    

    MouseArea
        id: cancelArea
        anchors.fill: parent

        enabled: inputFocused
        visible: enabled
        z: inputGroup.z-1 // just beneath inputGroup

        onClicked: inputFocused = false
    

    Item
        id: inputGroup
        anchors
            top: parent.top
            topMargin: 56
            horizontalCenter: parent.horizontalCenter
        

        // if there are more controls, raise the z parameter
        // to raise cancelArea over them but beneath inputGroup
        z: inputFocused ? 99 : 0

        width: 200
        height: 200

        TextInput
            id: inputTextBox
            anchors
                top: parent.top
            
            width: parent.width
            height: 24
            Rectangle
                anchors.fill: parent
                anchors.margins: -3
                color: "transparent"
                border.width: 1
            
        

        ListView
            id: cbxListView;
            anchors
                top: inputTextBox.bottom
                topMargin: 12
            
            width: parent.width
            height: 70;

            visible: inputFocused;

            model: cbxListModel;
            spacing: 2;
            delegate: Text 
                  text: name + ", " + number
              

            clip: false;
        

    

我希望这个解决方案能满足您的需求。

【讨论】:

以上是关于Qt QML - 在 QML 中识别超出鼠标区域范围的主要内容,如果未能解决你的问题,请参考以下文章

QML:鼠标区域重叠的问题

通过在QT QML中单击鼠标重复矩形

QML MouseArea - 检查 Qt.NoModifier

QML Mac 全屏模式失去鼠标焦点

检测鼠标光标何时在 Qt5 和 QML 中的不规则形状图片上

QML MouseArea:如何将鼠标事件传播到其他鼠标区域?