Почему Qt3D QObjectPicker не работает на Android, если Qt3DWindow встроен в QWidget? - PullRequest
1 голос
/ 14 апреля 2019

У меня есть приложение Qt, содержащее Qt3DWindow, а также несколько QWidgets. Чтобы использовать оба, Qt3DWindow встроен через QMainWindow::createWindowContainer(), который отлично работает как на Windows, так и на Android. Это не относится к QObjectPicker, подключенному к QEntity, событие QObjectPicker::clicked возникает только в Windows, а не в Android. Однако, если я удаляю Qt3DWindow из QMainWindow и снова использую его «автономно», QObjectPicker работает как положено на обеих платформах.

Я протестировал этот сценарий использования с различными версиями Qt (5.10, 5.12, 5.13 beta) и различными цепями инструментов (NDK R14 с GCC, NDK R19 с Clang) без успеха. В некоторых редких случаях я получаю событие QObjectPicker :: clicked (), но из тарифа сенсорного события вдали от позиции объекта на экране.

Чтобы воспроизвести проблему, лучше всего перейти к «Qt 3D: Простой пример C ++». Добавьте следующие файлы в main.cpp:

#include <Qt3DRender/QObjectPicker>
#include <Qt3DRender/QPickEvent>
#include <QObject>
#include <QtWidgets/QApplication>
#include <QGuiApplication>
#include <QtWidgets/QMainWindow>

Добавьте следующий код в конец main.cpp / createScene () прямо перед оператором return:

    Qt3DRender::QObjectPicker* picker = new Qt3DRender::QObjectPicker();
    QObject::connect(picker, &Qt3DRender::QObjectPicker::clicked, material, [material](Qt3DRender::QPickEvent *pickEvent){
                qDebug() << "Sphere  clicked";
                static_cast<Qt3DExtras::QPhongMaterial*>(material)->setAmbient(QColor(rand()%255,rand()%255,rand()%255));
            });
    sphereEntity->addComponent(picker);

Чтобы скомпилировать и развернуть для Android, создайте AndroidManifest.xml и удалите флаг «плотности» из «android: configChanges». Запущенное приложение должно отображать тор и движущуюся сферу, а при касании сферы их цвет меняется случайным образом.

Затем замените QGuiApplication app(argc, argv); на QApplication app(argc, argv); в main.cpp / main () и добавьте следующий код прямо перед оператором возврата:

    QMainWindow* mainWindow = new QMainWindow();
    mainWindow->resize(800, 600);
    auto centralwidget = new QWidget(mainWindow);
    mainWindow->setCentralWidget(centralwidget);
    auto container = QMainWindow::createWindowContainer(&view,mainWindow->centralWidget());
    mainWindow->show();
    container->resize(mainWindow->centralWidget()->size());

Теперь приложение Android показывает ту же сцену внутри виджета, но касание сферы не меняет цвет. (В Windows работает наоборот)

Закомментируйте последние три строки, чтобы пример снова заработал:

    //auto container = QMainWindow::createWindowContainer(&view,mainWindow->centralWidget());
    //mainWindow->show();
    //container->resize(mainWindow->centralWidget()->size());

Есть идеи, что это неверная конфигурация или ошибка?

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Благодаря подсказке user3405291 я наконец заработал на Android, прикрепив фильтр событий к виджету контейнера, возвращенному QMainWindow::createWindowContainer, отфильтровав QEvent::MouseButtonRelease, вызвав QScreenRayCaster::trigger с позицией события в качестве аргумента и получив выбранные объекты через QScreenRayCaster::hitsChanged. В Windows эта процедура также работает, но только если фильтр событий присоединен к самому Qt3DWindow, а не к виджету контейнера. Я предполагаю, что в Windows события мыши перенаправляются из виджета контейнера в Qt3DWindow, а в Android они используются виджетом контейнера вместо этого. Поскольку QObjectPicker, кажется, прослушивает (только) события на Qt3DWindow, он не работает должным образом на Android, и нет возможности вручную пересылать на него события. Но это только поверхностное впечатление, и я был бы рад любым дальнейшим разъяснениям.

0 голосов
/ 16 апреля 2019

Выбор объектов работает только с щелчком мыши.Если вам нужны сенсорные жесты, вам нужно использовать QScreenRayCaster, как объяснено здесь

...