我正在尝试发送 QMouseEvent
到当前显示的 QML 对象。QApplication::sendEvent()
总是返回 false
意味着我的事件没有得到处理;但我不明白为什么。
也许我将事件发送到错误的对象?我应该把它寄到哪里?
我也玩过 QGraphicsSceneMouseEvent
而不是 QMouseEvent
但也没有运气。
我尝试使用调试器单步执行事件代码,但它太复杂了,我看不出它为什么不起作用。
背景
我正在开发一款可以通过简单触摸屏进行控制的软件。我通过以太网获取触摸事件,我想从中合成鼠标点击事件。
这样,软件将在目标设备上以与在开发人员 PC 上相同的方式进行控制。
更新
QApplication::Exec()
之前执行的,所以我把它移到一个定时器处理程序中,该处理程序将在 exec()
时被触发。在跑。 sendEvent()
返回 true
或 false
. 到目前为止,我有这个:
主程序
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include "clicksimulator.h"
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/qmlClickSimulator/main.qml"));
viewer.showMaximized();
ClickSimulator sim(&viewer);
QTimer timer;
sim.connect(&timer, SIGNAL(timeout()), SLOT(click()));
timer.start(100);
return app.exec();
}
点击模拟器.h
#ifndef CLICKSIMULATOR_H
#define CLICKSIMULATOR_H
#include <QObject>
class QmlApplicationViewer;
class ClickSimulator : public QObject
{
Q_OBJECT
QmlApplicationViewer* m_viewer;
public:
explicit ClickSimulator(QmlApplicationViewer* viewer, QObject *parent = 0);
public slots:
void click();
};
#endif // CLICKSIMULATOR_H
点击模拟器.cpp
#include "clicksimulator.h"
#include "qmlapplicationviewer.h"
#include <QMouseEvent>
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include <QApplication>
#include <QGraphicsScene>
#include <QTest>
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include "Windows.h"
ClickSimulator::ClickSimulator(QmlApplicationViewer* viewer, QObject *parent) :
QObject(parent)
, m_viewer(viewer)
{
}
void ClickSimulator::click()
{
if (NULL != m_viewer)
{
const int x = qrand() % 500 + 100, y = qrand() % 500 + 100;
{
QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(x, y), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
// QMouseEvent pressEvent(
// QEvent::MouseButtonPress,
// QPoint(x, y),
// Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
const bool isSent = QApplication::sendEvent(m_viewer->scene(), &pressEvent);
qDebug() << "'Press' at (" << x << "," << y << ") successful? " << isSent;
}
{
QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
pressEvent.setScenePos(QPointF(x, y));
pressEvent.setButton(Qt::LeftButton);
pressEvent.setButtons(Qt::LeftButton);
QGraphicsItem* item = m_viewer->itemAt(x, y);
const bool isSent = m_viewer->scene()->sendEvent(item, &pressEvent);
//const bool isSent = QApplication::sendEvent(m_viewer->scene(), &pressEvent);
qDebug() << "'Press' at (" << x << "," << y << ") successful? " << isSent;
}
// This platform specific code works...
{
const double fScreenWidth = ::GetSystemMetrics( SM_CXSCREEN )-1;
const double fScreenHeight = ::GetSystemMetrics( SM_CYSCREEN )-1;
const double fx = x*(65535.0f/fScreenWidth);
const double fy = y*(65535.0f/fScreenHeight);
INPUT inp[3];
inp[0].type = INPUT_MOUSE;
MOUSEINPUT & mi = inp[0].mi;
mi.dx = fx;
mi.dy = fy;
mi.mouseData = 0;
mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
mi.time = 0;
mi.dwExtraInfo = 0;
inp[1] = inp[0];
inp[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
inp[2] = inp[0];
inp[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(3, inp, sizeof(INPUT));
}
}
}
主文件
import QtQuick 1.0
Rectangle {
width: 360
height: 360
Text {
id: text1
text: qsTr("This text is placed at the click coordinates")
}
MouseArea {
id: mousearea1
anchors.fill: parent
onClicked: {
console.log("click at " + mouse.x + ", " + mouse.y);
text1.pos.x = mouse.x;
text1.pos.y = mouse.y;
}
}
}
输出
'Press' at ( 147 , 244 ) successful? false
'Press' at ( 147 , 244 ) successful? true
最佳答案
由于您在 app.exec() 之前发送事件,我认为主事件循环尚未启动。你可以试试 postEvent相反,如果 exec() 在开始之前清除事件队列,这也可能会失败。在这种情况下,也许您可以在 exec() 之后的某个地方发布它?
更新:通过查看 QDeclarativeMouseArea autotests 现在可以正常工作了.缺少的是发布事件。这对我有用:
QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
pressEvent.setScenePos(QPointF(x, y));
pressEvent.setButton(Qt::LeftButton);
pressEvent.setButtons(Qt::LeftButton);
QApplication::sendEvent(m_viewer->scene(), &pressEvent);
QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
releaseEvent.setScenePos(QPointF(x, y));
releaseEvent.setButton(Qt::LeftButton);
releaseEvent.setButtons(Qt::LeftButton);
QApplication::sendEvent(m_viewer->scene(), &releaseEvent);
有点奇怪的是 QML 文件中的 onPressed 在新闻事件之后没有被调用 - 只有在发布事件被发送之后。
关于qt - 如何在 QML 中模拟鼠标点击?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7517700/