gpt4 book ai didi

qt - 如何在 QML 中模拟鼠标点击?

转载 作者:行者123 更新时间:2023-12-03 22:33:57 29 4
gpt4 key购买 nike

我正在尝试发送 QMouseEvent到当前显示的 QML 对象。QApplication::sendEvent()总是返回 false意味着我的事件没有得到处理;但我不明白为什么。
也许我将事件发送到错误的对象?我应该把它寄到哪里?
我也玩过 QGraphicsSceneMouseEvent而不是 QMouseEvent但也没有运气。

我尝试使用调试器单步执行事件代码,但它太复杂了,我看不出它为什么不起作用。

背景

我正在开发一款可以通过简单触摸屏进行控制的软件。我通过以太网获取触摸事件,我想从中合成鼠标点击事件。
这样,软件将在目标设备上以与在开发人员 PC 上相同的方式进行控制。

更新

  • fejd 指出,点击代码是在 QApplication::Exec() 之前执行的,所以我把它移到一个定时器处理程序中,该处理程序将在 exec() 时被触发。在跑。
  • 添加了按预期工作的特定于 Windows 的代码。
  • 在 Qt 中添加了更多尝试,无论是否有效 sendEvent()返回 truefalse .

  • 到目前为止,我有这个:

    主程序
    #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/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com