Pull to refresh

Comments 15

А почему, собственно, не отлаживать чисто QML код на десктопе, вообще без заливки куда-либо?
Есть ряд задач, решать которые можно только на устройстве:
— позиционирование и масштабирование элементов на нескольких устройствах с разными разрешениями и размерами экранов;
— прототипирование пользовательского интерфейса в нескольких вариантах для сравнения юзабилити на реальных устройствах;
— вызов платформозависимого кода, недоступного в Windows. Например то, что раньше называлось Qt Mobility — доступ к местоположению, сенсорам (гироскоп, акселерометр и другие), блютуз, NFC.
— тестирование своих библиотек. Например я сейчас пилю новую версию своей библиотеки AdCtl (https://github.com/kafeg/adctl) где будет возможность авторизации через GPlay и привязка к рейтингам игроков и ачивкам.

Это то что вспомнилось сразу. Наверняка у каждого девелопера есть ещё куча причин тестировать функционал на конечном устройстве.
— позиционирование и масштабирование элементов на нескольких устройствах с разными разрешениями и размерами экранов;
Доступно на десктопе
— вызов платформозависимого кода, недоступного в Windows
Отлаживаем платформозависимый код — значит нужна перекомпиляция. Если он уже отлажен, значит интерфейс пишем на десктопе.

2 пункт спорный, 4 схож с третьим.

Но, тем не менее, статья полезная, наверняка кому-нибудь пригодится.
— позиционирование и масштабирование элементов на нескольких устройствах с разными разрешениями и размерами экранов;

К сожалениею не всё так хорошо в Qt с масштабированием, чтобы не заморачиваться тестированием UI на конечном устройстве. К тому же я например не знаю как на десктопе симулировать различные dpi/ppi.

— вызов платформозависимого кода, недоступного в Windows

Пример — библиотека использующая платформозависимый код уже готова и представлена QML-плагином. В этом случае перекомпиляция не нужна, но чтобы настроить связку с библиотекой может потребоваться несколько перезапусков приложения.
К тому же я например не знаю как на десктопе симулировать различные dpi/ppi.

Симулировать нельзя, зато можно обеспечить одинаковый размер элементов на всех девайсах вне зависимости от dpi/ppi — хоть в миллиметрах, хоть в пикселах.
Научите как правильно, перепробовал кучу способов =)
Если детально, то читать вот по этой ссылке статьи снизу-вверх.

Если кратко, то вот код:
#ifdef Q_OS_ANDROID
    //  BUG with dpi on some androids: https://bugreports.qt-project.org/browse/QTBUG-35701
    //  Workaround:
    QAndroidJniObject qtActivity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
    QAndroidJniObject resources = qtActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
    QAndroidJniObject displayMetrics = resources.callObjectMethod("getDisplayMetrics", "()Landroid/util/DisplayMetrics;");
    int density = displayMetrics.getField<int>("densityDpi");
#else
    QScreen *screen = qApp->primaryScreen();
    float density = screen->physicalDotsPerInch();
#endif

    engine.rootContext()->setContextProperty("mm",density / 25.4);
    engine.rootContext()->setContextProperty("pt", 1);

    double scale = density < 180 ? 1 :
                   density < 270 ? 1.5 :
                   density < 360 ? 2 : 3;
    engine.rootContext()->setContextProperty("dp", scale);

Тут размер в миллиметрах полностью надежен, в девайсонезависимых пикселах приблизителен, как и на Android (но надо бы потестить на соответствующих девайсах), pt для единообразия при указании размеров шрифта.

Использвать очень просто — умножаем размеры в любом месте QML кода:
Rectangle {
    height: 20*mm;
    width: 40*dp;
}

Все собираюсь написать статью по таким базовым вещам, но руки пока не доходят :/
разве screen->physicalDotsPerInch() не дает PPI на андроиде?
Зачем лезть в java вызовы?
Заодно это выявит все места неправильного использования createComponent (где не учитывается что объект может быть не доступен сразу после вызова).
Единственное — полные имена файлов лучше заменить на относительные чтобы не носиться с assetsLoadPrefix+ по всему проекту
Вот кстати да, что касается createComponent, вместо неправильного использования
if (myComponent.status == Component.Ready) { ... } 

сразу после создания компонента, точно придётся переписывать эту логику на использование асинхронного вызова
myComponent.statusChanged.connect(function() { ... })

Также выяснится, что вызвать этот метод можно лишь один раз, а дальше от него нужно дёргать createObject необходимое количество раз.
Хм, вроде всё-таки правильное использование это

var myComponent = Qt.createComponent(url);
if ( myComponent.status == Component.Ready) {
callback();
} else {
myComponent.statusChanged.connect(callback);
}
If you are certain the QML file to be loaded is a local file, you could omit the finishCreation() function and call createObject() immediately
Так что использование вполне себе правильное.
Согласен, здесь не прав я, а делать нужно так как в комментарии выше.
Sign up to leave a comment.

Articles