我有一个场景“编辑器”在底部闪烁,并停靠在它的右侧,一个场景“大纲视图”在它的顶部闪烁,它显示了场景结构的树。
Flickable {
id: editor
anchors.fill: parent
contentWidth: 5000
contentHeight: 5000
Repeater {
model: 500
delegate: Rectangle {
width: Math.random() * 200 + 50
height: width
x: Math.random() * editor.contentWidth
y: Math.random() * editor.contentHeight
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
}
}
}
Flickable {
id: outliner
anchors.right: editor.right
width: contentWidth
height: parent.height
contentWidth: contentItem.childrenRect.width
contentHeight: contentItem.childrenRect.height
Column {
Repeater {
model: 500
delegate: Rectangle {
width: Math.random() * 200 + 50
x: outliner.contentWidth - width
height: 50
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
}
}
}
}当然,我希望能够轻弹两者来导航,因为它们都比可用屏幕空间大。
问题是,大纲视图可闪烁对象将简单地阻止编辑器可闪烁,即使我从大纲视图项目不占用的位置进行闪烁。我不希望发生这种情况,我想要的是仅当轻拍发生在大纲视图项的顶部时才轻拍大纲视图,否则我想跳过编辑器,这样我就可以单击并从该区域向右轻拍它。
由于Flickable的工作方式,我一直无法做到这一点。它将首先检查是否有拖拽,只有当点击没有超过拖拽阈值时,它才会让点击向下移动到底层元素。所以我想不出一种方法,只有在那个位置有物体的时候,才能轻拍。
有没有办法让事件处理做我想做的事情?
发布于 2017-08-04 19:59:02
好了,我想我做到了,关键是禁用大纲视图的交互性,然后通过代理中的MouseArea截取输入,然后仔细计时并测量手动拖动增量,如果足够快,计划在发布时手动轻拍。
让它在印刷机上停止正在进行的轻拍,然后在下一次拖动时启动另一次轻拍,这在刚刚取消轻拍之后被证明是有问题的,但通过将每次轻拍推迟到下一个事件循环周期,我让它工作了。
我还增加了轮子支撑之类的东西。
如果任何人在任何平台上遇到问题,请在评论中让我知道。
// the editor code is the same from the OP
Flickable {
id: outliner
anchors.right: editor.right
width: contentWidth
height: parent.height
contentWidth: contentItem.childrenRect.width
contentHeight: contentItem.childrenRect.height
interactive: false
property int ly: 0
property real lt: 0
property int dy: 0
function go(yy) {
dy = contentY - (contentY -= yy - ly)
ly = yy
lt = Date.now()
}
Timer {
id: trigger
interval: 1
onTriggered: outliner.flick(0, outliner.dy * 150)
}
Column {
Repeater {
model: 500
delegate: Rectangle {
width: Math.random() * 200 + 50
x: outliner.contentWidth - width
height: 50
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
MouseArea {
anchors.fill: parent
Drag.active: drag.active
drag.target: Item { id: dummy }
onPressed: {
dummy.y = 0
if (outliner.flicking) outliner.cancelFlick()
}
onWheel: outliner.flick(0, wheel.angleDelta.y * 10)
onPositionChanged: {
if (drag.active) outliner.go(dummy.y)
}
onReleased: {
if (Date.now() - outliner.lt < 50) trigger.start()
outliner.ly = 0
outliner.returnToBounds()
}
}
}
}
}
}发布于 2017-08-04 18:58:04
您可以通过检查场景中的每个媒体来实现这一点,如果在媒体下方有大纲视图的代理。如果没有,请将outliner标记为非交互式。当editor中有移动时,立即重新启用它。
如下所示:
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
ApplicationWindow {
id: app
visible: true
width: 600
height: 480
Item { // a common parent not containing the MouseArea to be able to call childAt on press
id: flickablesParent
anchors.fill: parent
Flickable {
id: editor
anchors.fill: parent
contentWidth: 5000
contentHeight: 5000
onMovementStarted: outliner.interactive = true //re-enable the outliner user interaction so it can be flicked again.
Repeater {
model: 500
delegate: Rectangle {
width: Math.random() * 200 + 50
height: width
x: Math.random() * editor.contentWidth
y: Math.random() * editor.contentHeight
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
}
}
}
Flickable {
id: outliner
anchors.right: editor.right
width: contentWidth
height: parent.height
contentWidth: contentItem.childrenRect.width
contentHeight: contentItem.childrenRect.height
Column {
id: column // set an id so it can be referenced in the MouseArea
Repeater {
model: 500
delegate: Rectangle {
width: Math.random() * 200 + 50
x: outliner.contentWidth - width
height: 50
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
}
}
}
}
}
MouseArea {
id: dispatcher
anchors.fill: parent
onPressed: {
var flickable = flickablesParent.childAt(mouse.x, mouse.y); //find out on what flickable we pressed (the check could be ommited but I guess it's more performant with)
if (flickable === outliner) {
var mappedPos = mapToItem(column, mouse.x, mouse.y);
var delegate = column.childAt(mappedPos.x, mappedPos.y);
if (!delegate)
outliner.interactive = false; //if there's no delegate where we pressed in the column, we disable the interactions of the outliner flickable.
}
mouse.accepted = false; // let the underlying Flickable deal with this event
}
}
}编辑:您实际上不需要在onMovementStarted中重新启用大纲视图,也可以在MouseArea onPressed中执行此操作。
喜欢
onPressed: {
var flickable = flickablesParent.childAt(mouse.x, mouse.y); //find out on what flickable we pressed (the check could be ommited but I guess it's more performant with)
if (flickable === outliner) {
var mappedPos = mapToItem(column, mouse.x, mouse.y);
var delegate = column.childAt(mappedPos.x, mappedPos.y);
outliner.interactive = delegate ? true : false;
}
mouse.accepted = false; // let the underlying Flickable deal with this event
}https://stackoverflow.com/questions/45503483
复制相似问题