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

时间:2015-06-05 10:58:19

标签: c++ qt qt-quick

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

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

1 个答案:

答案 0 :(得分: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,它只是将click事件重定向到调度程序。每个额外窗口都包含一个鼠标区域和输出点击坐标的文本,并在调度程序中注册自己。当单击主窗口中的鼠标区域时,调度程序将为两个窗口模拟单击事件,结果其中的文本确认事件确实已分派到窗口并由基础鼠标区域处理。

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 ++端一次为每个窗口启用焦点。