如何从Touch中接收MouseArea中输入的Qt信号?

时间:2016-09-14 10:36:43

标签: qt touch qml

我在我的QT应用程序中使用MouseArea按钮,当用户用手指轻触按钮时,我需要知道。在使用鼠标的W7上,我使用来自MouseArea的onEntered获取此信息。

问题:在带有触摸屏的目标平台上,输入信号仅在我按下MouseArea(第一次触摸MouseArea内),然后将我的手指移出(退出信号),然后将手指移回(输入信号)。但是当第一次触摸在区域之外并且我输入它时,输入信号不会被触发。 我还尝试使用onTouchUpdated和onUpdated的MultiPointTouchArea,行为相同。

我在嵌入式Linux上使用Qt 5.5.1。

我能做些什么来让MouseArea始终触发输入信号?或者我应该使用MouseArea或MultiPointTouchArea之外的其他东西吗?

作为一种解决方法,我可以在整个窗口中看到一个MouseArea,其中包含所有按钮的信息并检查每个positionChanged,如果输入了一个按钮,但我确定必须有更好的解决方案。

编辑:在目标平台上使用鼠标时,将鼠标移动到该区域时会触发输入信号。

这是我的(简化)代码:

的main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtQml>

#include "uart_terminal.h"

int main(int argc, char *argv[])
{
    system("mount /dev/mmcblk0p1 /mnt/sdcard/");
    setenv("QT_QPA_EGLFS_PHYSICAL_WIDTH", "376", 1);
    setenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT", "301", 1);

    QApplication app(argc, argv);
    qmlRegisterType<UART_terminal>("com.uart", 1, 0, "UARTTerminal");

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("applicationDirPath", QGuiApplication::applicationDirPath());
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

main.qml:

    Window
    {
        id: rootWindow
        visible: true

        width: 1280
        height: 1024

        Rectangle
        {
            id: test
            color: "red"
            width: 300
            height: 300

            MouseArea
            {
                anchors.fill: parent

                hoverEnabled: true
                acceptedButtons: Qt.AllButtons

                onEntered:
                {
                    console.log("entered")
                    test.color = "blue"
                }
                onExited: test.color = "red"
                onCanceled: console.log("canceled")
                onPositionChanged:
                {
                    console.log("pos changed, containsMouse", containsMouse)
                }
            }

            /*MultiPointTouchArea
            {
                anchors.fill: parent
                onTouchUpdated: console.log("touch updated")
                onUpdated: console.log("touchlist updated")
            }*/
        }
    }

1 个答案:

答案 0 :(得分:0)

因为我没有找到任何其他解决方案,所以我必须实施上述工作。我把一个MouseArea&#34; buttonContainer&#34;在整个屏幕上,在所有其他MouseAreas后面。请注意,我必须传播来自每个MouseArea的positionChanged信号,否则当我在一个按钮中开始触摸然后输入另一个按钮时,它不会创建我的按钮输入信号。

onPositionChanged:
{
    // propagate event to buttonContainer with absolute mouse position
    var position = roundMouseArea.mapToItem(root)
    buttonContainer.xOffsetMouse = position.x
    buttonContainer.yOffsetMouse = position.y
    buttonContainer.positionChanged(mouse)
}

然后在buttonContainer的onPositionChanged中,我必须检查输入时当前可见的所有按钮。不要忘记用btn.mapToItem(buttonContainer)再次映射每个按钮位置,并在buttonContainer的onPressed中重置x-和yOffsetMouse。

在我的情况下,我不得不做更多的事情,比如

  • 检查按钮是否已被禁用,尽管可见
  • 记得enteredBtn
  • 为每个按钮设置bool,如果它已经从我的容器中输入,那么我不会在每个位置输入信号改变而我留在那个按钮
  • 还要检查退出按钮
  • 相应地设置btnPressed true或false,例如。也可以在buttonContainer上发布
  • 将enteredBtn重置为undefined并在引用enteredBtn的任何方法或属性之前检查它(例如,在buttonContainer&lt; s; onReleased)

我认为就是这样。不想在这里复制我的整个代码,只要提一下在遇到同样问题时可能需要考虑的一些方面。