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

iva*_*ult 5 c++ qt qt-quick

看起来Qt Quick测试要求测试窗口具有焦点,以便发送自己的鼠标和键盘事件.没关系,我只运行一次测试.但是当我尝试运行Qt Quick测试的多个实例时,他们争取窗口焦点,这会导致测试失败.

如何在不关注测试窗口的情况下执行Qt Quick测试?有没有选择强制Qt Quick使用假的鼠标和键盘事件而不是使用真正的窗口系统?如何在没有焦点问题的情况下运行多个Qt Quick测试实例?

dte*_*ech 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;
};
Run Code Online (Sandbox Code Playgroud)

然后,您创建一个调度程序并将其注册为上下文属性,或者将其注册为 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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