如何并行运行多个Qt Quick测试?

5
看起来Qt Quick测试需要测试窗口获得焦点才能发送鼠标和键盘事件。当我只运行一个测试时,这没问题。但是当我尝试运行多个Qt Quick测试实例时,它们会争夺窗口焦点,导致测试失败。
如何在不聚焦测试窗口的情况下进行Qt Quick测试?是否有任何选项可以强制Qt Quick使用虚拟鼠标和键盘事件而不是与真实窗口系统交互?如何运行多个Qt Quick测试实例而不出现焦点问题?

无法向没有焦点的窗口发送鼠标和键盘输入,因此解决方案不太可能提供给同一会话。您想要运行多少个实例? - Jeff
我想要运行至少8个实例。 - ivaigult
1个回答

3

好的,我会开始翻译。

您可以使用C++事件发布来将单个事件重定向到多个QML窗口:

class Dispatcher : public QObject {
    Q_OBJECT
public slots:
    void click(qreal x, qreal y) {
        foreach (QObject * o, objects) {
            QMouseEvent * e1 = new QMouseEvent(QEvent::MouseButtonPress, QPointF(x, y), Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier);
            QCoreApplication::postEvent(o, e1);
            QMouseEvent * e2 = new QMouseEvent(QEvent::MouseButtonRelease, QPointF(x, y), Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier);
            QCoreApplication::postEvent(o, e2);
        }
    }
    void addTarget(QObject * obj) {
        objects.append(obj);
    }
private:
    QObjectList objects;
};

然后您需要创建一个调度程序并将其注册为上下文属性,或将其注册为QML类型并在QML中实例化它,然后使用它来注册所有应该接收事件的对象。

这是我编写的快速QML测试,用于测试它是否有效:

主窗口包含一个MouseArea,它只是将点击事件重定向到调度程序。每个额外的窗口都包含一个鼠标区域和文本以输出单击坐标,并在调度程序中注册自己。当在主窗口中单击鼠标区域时,调度程序会模拟两个窗口的单击事件,结果显示它们的文本确认事件确实已分派到窗口并由底层鼠标区域处理。

Window {
    id: main
    visible: true
    width: 300
    height: 300
    x: 100
    y: 100

    MouseArea {
        anchors.fill: parent
        onClicked:  Dispatcher.click(mouseX, mouseY)
    }

    Component {
        id: comp
        Item {
            anchors.fill: parent
            Text {
                id: txt
            }
            MouseArea {
                id: ma
                anchors.fill: parent
                onClicked: txt.text = "clicked at " + mouseX + ", " + mouseY
            }
        }
    }

    Window {
        id: w1
        visible: true
        width: 300
        height: 300
        x: 420
        y: 100
        Loader {
            anchors.fill: parent
            sourceComponent: comp
        }
        Component.onCompleted: Dispatcher.addTarget(w1)
    }

    Window {
        id: w2
        visible: true
        width: 300
        height: 300
        x: 740
        y: 100
        Loader {
            anchors.fill: parent
            sourceComponent: comp
        }
        Component.onCompleted: Dispatcher.addTarget(w2)
    }
}

您可以使用类似的方法将事件从一个窗口重定向到多个窗口,或者为每个窗口生成完全独立的事件序列,您还可以编写事件记录器,然后保存手动触发的事件,并以可变速度播放这些事件。您几乎可以做任何事情。相同的方法也适用于键盘事件。此外,当您发布事件时,您可以从C++端为每个窗口启用焦点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接