Qt 单击\flick浏览与另一个Flickable部分重叠的Flickable的空白区域
我在底部有一个场景“编辑器”flickable,并停靠在其右侧,在其顶部有一个场景“大纲视图”(outliner)flickable,它显示了场景结构的树Qt 单击\flick浏览与另一个Flickable部分重叠的Flickable的空白区域,qt,qml,qtquick2,overlap,flickable,Qt,Qml,Qtquick2,Overlap,Flickable,我在底部有一个场景“编辑器”flickable,并停靠在其右侧,在其顶部有一个场景“大纲视图”(outliner)flickable,它显示了场景结构的树 Flickable { id: editor anchors.fill: parent contentWidth: 5000 contentHeight: 5000 Repeater { model: 500 delegate: Rectangle { wid
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将简单地阻止编辑器flickable,即使我从大纲视图项不占据的位置进行flick。我不想这样,我只想在大纲视图项顶部进行翻转时,才对大纲视图进行翻转,否则我想跳转到编辑器,这样我就可以单击并将其从区域向右翻转
由于Flickable
的工作方式,我一直无法做到这一点。它将首先检查是否有拖动,只有当单击没有超过拖动阈值时,它才会让单击下降到底层元素。所以,我想不出一种方法,只有当有一个物体在那个位置时,才能进行轻弹
有什么方法可以让事件处理执行我希望它执行的操作吗?您可以通过检查场景中的每个按钮来执行此操作,前提是该按钮下方是否有大纲视图的代理。如果不是,请将
大纲视图标记为非交互式。当编辑器中出现移动时,立即重新启用它
像这样:
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
}
}
}
编辑:您实际上不需要在移动开始时重新启用大纲视图,也可以在鼠标eareaonPressed
中重新启用大纲视图
像
是的,我想我做到了,关键是禁用大纲视图的交互性,然后通过代理中的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()
}
}
}
}
}
}
//编辑器代码与OP中的相同
轻快的{
id:大纲视图
.right:editor.right
宽度:contentWidth
高度:parent.height
contentWidth:contentItem.childrenRect.width
contentHeight:contentItem.childrenRect.height
交互:错误
属性:0
不动产lt:0
属性:0
功能go(yy){
dy=contentY-(contentY-=yy-ly)
ly=yy
lt=日期。现在()
}
计时器{
id:触发器
间隔时间:1
onTriggered:outliner.flick(0,outliner.dy*150)
}
纵队{
中继器{
型号:500
代表:矩形{
宽度:Math.random()*200+50
x:outliner.contentWidth-宽度
身高:50
颜色:Qt.rgba(Math.random(),Math.random(),Math.random(),1)
border.color:“黑色”
鼠耳{
锚定。填充:父级
Drag.active:Drag.active
drag.target:Item{id:dummy}
按下按钮:{
dummy.y=0
if(outliner.flicking)outliner.cancelFlick()
}
onWheel:outliner.flick(0,wheel.angleDelta.y*10)
已更改的位置:{
if(drag.active)大纲视图.go(dummy.y)
}
发布日期:{
if(Date.now()-outliner.lt<50)trigger.start()
outliner.ly=0
大纲视图。returnToBounds()
}
}
}
}
}
}
它在这里工作,还是你的意思是在大纲视图中没有代理的区域中轻弹时不应该轻弹?这就是我的意思。不仅它不应该闪烁,底部的flickable也应该闪烁。不幸的是,在我的产品代码中,大纲视图不仅仅是一个列,它是一个嵌套的树,而且是一个非常深且任意的结构,因此简单地检查点是否为空并不容易或非常适用,遗憾的是,我想不出另外一个解决办法,就是检查你按下的地方是否有叶节点。我也有点为我的解决方案感到自豪:(它对示例代码有效,但对问题所指定的内容无效:)我可能对某些人仍然有用,同时我认为我正在着手解决一些问题。我明白了,我希望能在不同的平台上进行测试,看看是否有任何问题。
// 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()
}
}
}
}
}
}