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
(在本例中为InputText
和ListView
),无论单击什么,都应取消输入模式。鼠标事件被输入控件处理和吃掉的方式,但它们之外的事件由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 MouseArea - 检查 Qt.NoModifier