Qml QTouchDevice

时间:2016-01-25 10:12:00

标签: qt qml touchscreen

我是Qt的新人。我正在使用Windows桌面应用程序并使用Qt和qml。在没有QTouchDevices的PC上,组件之间的分割器(允许您在窗口上调整组件大小的元素)与鼠标配合使用(屏幕截图"良好距离"),但如果屏幕是触摸屏我有下一个问题,请查看屏幕截图"错误的距离"。

我的应用程序不支持任何触控设备。那么如何禁用这个Qt功能呢?我需要像没有触摸屏的设备一样的行为。

错误的距离

Wrong distance

良好的距离

Good distance

我尝试使用下一个样本使用privet方法禁用触摸设备:

QWindowSystemInterface::unregisterTouchDevice(QTouchDevice::devices().first());

这样可行,但QWindowSystemInterface是私有类,它会禁用触摸屏。 QTCreator分离器中的另一个工作正常,完全符合我的需要。

2 个答案:

答案 0 :(得分:1)

如果你无法修补Qt,我能想到的唯一方法就是遍历孩子,搜索MouseArea。例如,假设你有这个QML:

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

ApplicationWindow {
    width: 600
    height: 400
    visible: true

    property alias splitView: splitView

    SplitView {
        id: splitView
        anchors.fill: parent

        Rectangle {
            width: 200
            Layout.maximumWidth: 400
            color: "lightblue"
            Text {
                text: "View 1"
                anchors.centerIn: parent
            }
        }

        Rectangle {
            id: centerItem
            Layout.minimumWidth: 50
            Layout.fillWidth: true
            color: "lightgray"
            Text {
                text: "View 2"
                anchors.centerIn: parent
            }
        }
    }
}

然后你可以像这样打印出SplitView的对象树:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QDebug>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    QObject *window = engine.rootObjects().first();
    QQuickItem *splitView = window->property("splitView").value<QQuickItem*>();
    splitView->dumpObjectTree();

    return app.exec();
}

这会给你:

SplitView_QMLTYPE_1:: 
    QQmlComponent:: 
    QQuickSystemPalette:: 
    QObject_QML_2:: 
    QQmlComponent:: 
    QQuickItem:: 
    QQuickItem:: 
    QQuickItem:: 
        QQuickLoader_QML_3:: 
            QObject_QML_4:: 
            QQuickMouseArea_QML_5:: 
            QQuickRectangle:: 
                QQmlContext:: 
    QQuickItem:: 
    QQmlComponentAttached:: 
    QQuickRectangle:: 
        QQuickText:: 
        QQuickLayoutAttached:: 
    QQuickRectangle:: 
        QQuickText:: 
        QQuickLayoutAttached:: 
    QQuickLayoutAttached:: 

QObject::dumpObjectTree() prints out metaObject->className(),因此我们知道要查找metaObjectclassName匹配的对象:

然后:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QScreen>
#include <QWindow>
#include <QDebug>

QQuickItem *findMouseArea(QQuickItem *item)
{
    foreach (QQuickItem *childItem, item->childItems()) {
        if (QString(childItem->metaObject()->className()).startsWith(QStringLiteral("QQuickMouseArea_QML"))) {
            return childItem;
        } else {
            QQuickItem *mouseArea = findMouseArea(childItem);
            if (mouseArea) {
                return mouseArea;
            }
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    QWindow *window = qobject_cast<QWindow*>(engine.rootObjects().first());
    QQuickItem *splitView = window->property("splitView").value<QQuickItem*>();
    QQuickItem *mouseArea = findMouseArea(splitView);
    mouseArea->setProperty("defaultMargin", QVariant(window->screen()->physicalDotsPerInch() / 25.4));

    return app.exec();
}

显然,Screen::pixelDensity is calculated使用屏幕每英寸的物理点数除以25.4,因此我们也会复制它。你可以在那里使用任何其他值。

例如,如果要引入第二个MouseArea,则需要调整代码。

它仍然在很大程度上依赖于私有API,但它至少不会触及Qt代码。

答案 1 :(得分:0)

快速和简单:启用/禁用鼠标和触摸合成

无需修补内容或进行任何疯狂的树查找just enable or disable mouse or touch synthesizing

  • Qt :: AA_SynthesizeTouchForUnhandledMouseEvents
  • Qt的:: AA_SynthesizeMouseForUnhandledTouchEvents

Just disable what you don't want,无论是鼠标还是触摸,只接受真实事件。