我正在为Android开发应用程序。
我在ListView中放置了一些ChartView。 在ListView上方,我有一个Flickable可以在x轴上同步滚动ChartViews。
我需要在用户点击的图表上显示该点的坐标。
但是我不能,因为flickable会捕获鼠标单击事件,并且不会将其传播到下面的其他对象。
我需要鼠标事件到达用户点击的特定委托。
Rectangle {
color: "#ffffff"
Component {
id: chartDelegate
Rectangle {
id: rootDelegRect
anchors {left: parent.left; right: parent.right }
height: 350
ChartView {
anchors { fill: parent;}
x: -10
y: -10
width: parent.width + 20
height: parent.height + 20
legend.visible: false
LineSeries {
name: "LineSeries"
axisX: ValueAxis {
min: 0
max: 4
labelFormat: "%.0f"
}
axisY: ValueAxis {
min: 0
max: 6
labelFormat: "%.0f"
}
XYPoint { x: 0; y: 0.0 }
XYPoint { x: 1; y: 5.2 }
XYPoint { x: 2; y: 2.4 }
XYPoint { x: 3; y: 0.1 }
XYPoint { x: 4; y: 5.1 }
}
}
MouseArea {
anchors.fill: parent
hoverEnabled :true
onMouseXChanged: console.log(mouseX,mouseY);//does not work when clicked
}
}
}
ListView { id: listViewCharts; objectName: "chart";
clip: true
anchors.top: parent.top; anchors.bottom: parent.bottom;
width: 1500
contentX:baseFlick.contentX; contentY:baseFlick.contentY;
model: listViewIdsModel
cacheBuffer: 1500
delegate: chartDelegate
}
Flickable {
id: baseFlick
anchors.fill: parent
contentHeight: listViewCharts.contentHeight
contentWidth: listViewCharts.width
}
}
答案 0 :(得分:0)
显然,此问题只能使用c ++来解决
要捕获可滑动鼠标事件,请执行以下操作:
1)添加对象的名称为Flickable
objectName: "baseFlick"
2)创建qml场景后在c ++中。找到baseFlick对象,并在该对象上安装事件过滤器
auto rootObj = engine.rootObjects().at(0);
auto item = rootObj->findChild<QQuickItem *>("baseFlick");
if(item!=nullptr){
item->installEventFilter(this);
} else qDebug()<<"ERR baseFlick item=nullptr";
3)实现eventFilter虚拟函数
bool IDS2forUser::eventFilter(QObject *watched, QEvent *event)
{
...
return false;
}
为了将鼠标事件传播到ListView,就像它们来自用户一样。
在eventFilter函数中:
1)找到ListView(图表)对象
auto rootObj = engine.rootObjects().at(0);
auto item = rootObj->findChild<QQuickItem *>("chart");
2)找到他的所有孩子。
由于孩子的数量可能会发生变化,因此您每次都需要寻找孩子。
请注意,您应该使用QQuickItem :: childItems()函数而不是QObject :: children()
void IDS2forUser::getAllObjects(QQuickItem *parent, QList<QQuickItem *> &list) {
QList<QQuickItem *> children = parent->childItems();
foreach (QQuickItem *item, children) {
list.append(item);
getAllObjects(item,list);
}
}
3)将所有坐标转换为对象的局部坐标。并发送所有孩子事件。
整个功能如下所示。
bool IDS2forUser::eventFilter(QObject *watched, QEvent *event)
{
auto rootObj = engine.rootObjects().at(0);
auto item = rootObj->findChild<QQuickItem *>("chart");
QList<QQuickItem *> list;
getAllObjects(item, list);
QQuickItem *watchedIt = dynamic_cast<QQuickItem *>(watched);
if(!watchedIt)return false;
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
if(!mouseEvent)return false;
foreach (QQuickItem *item, list) {
QPointF point=item->mapFromItem(watchedIt,mouseEvent->localPos());
if(point.x()<0 || point.y()<0 || point.x()>=item->width() || point.y()>=item->height())continue;
QMouseEvent mouseEvent2(mouseEvent->type(),
point,
mouseEvent->button(),mouseEvent->buttons(),Qt::NoModifier);
QCoreApplication::sendEvent(item, &mouseEvent2);
}
return false;
}