JS / Ecmascript w QtQuick.

Od lat krążę wokół tematu ale trafiłem ostatnio na fajną książkę o ES6 (Learning JS z O’Reilly’ego) i sporo rzeczy w tej wersji standardu mi się podoba. Na tyle to fajne, że postanowiłem trochę poeksperymentować. Nieprzypadkowo akurat z ES6, bo Qt5.12 ma obsługiwać Ecmascript w wersji 6-tej. Fajne toto i szybkie, a z Qt nie musi być przywiązane do backendu, czy przeglądarki:

import QtQuick 2.11
import QtQuick.Window 2.11

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("JS fun 2")

    Rectangle {
        id: rect
        width: parent.width-100; height: parent.height-100
        border.color: 'red'
        border.width: 10
        anchors.centerIn: parent

        function get_fibo(n) {
            function fibo(n) {
                if (n < 1)
                    return 0;
                if (n <= 2)
                    return 1;
               return fibo(n-1) + fibo(n-2);
            }
            var ret = '';
            for (var i=0; i<n; i++)
                ret += fibo(i) + ' ';
            return ret;
        }

        Text {
            text: parent.get_fibo(15)
            anchors.centerIn: parent
        }
    }
}
fib_js
JS w QML nie wymaga magicznych sztuczek. Można go sobie ot tak używać, jak widać w powyższym przykładzie.
Nieco dziwny jest scoping w QML, bo jeśli obiekt który wywołujemy znajduje się w obiekcie nadrzędnym, trzeba się do niego dostać np. przez parent albo id. Jeśli nie, trzeba obiekt, np. funkcję wrzucić do obiektu najgłówniejszego ;). Może ma to jakieś głębsze uzasadnienie, a może to się zmieni w implementacji ES6.

Wywoływanie slotu w C++ z QML.

Moje eksperymenty z QtQuick2 spowodowały, że całkowicie zmieniłem zdanie na temat Qt5 i muszę przyznać, że minę mam coraz częściej taką 8-O.

cppslotfromqml
Po przemyśleniu możliwości model-view-controller, gdzie widok generowany jest z QML przez OpenGL, a dynamiczne z natury dzisiejszych urządzeń zmiany interfejsu zakodowane są w EcmaScript (JS) osadzonym w QML, oprócz tego łatwość wywoływania funkcji w C++ i Javie, dochodzę do wniosku, że Qt5 rządzi ;).

Hello World w QtQuick2.

QtQuick jest fascynujące:

Animacje to nawet nie kilka linijek kodu… a za ich wyświetlanie odpowiada OpenGL lub OpenGL ES 2.0.

QtQuick może być też osadzone w klasycznym oknie QWindow:

qmlAle póki co, nadal w Qt-5.5.1 nie działa to na Androidzie (QtQuick i QWidgets to dwie osobne powierzchnie wyświetlania w OpenGL, na Antku nie jest to póki co obsługiwane i może być albo QtQuick albo QWidgets).


ui->setupUi(this);

QQuickView *view = new QQuickView;
QWidget *container = QWidget::createWindowContainer(view, this);
view->setSource(QUrl::fromLocalFile("main.qml"));

ui->verticalLayout->addWidget(container);

OptionsDialog.

TreeView na Androidzie sprawdza się średnio, zastanawiałem się jak to można by zrobić w Qt5 i przyznam szczerze, łatwo nie jest. QScrollView ma jedną podstawową wadę: póki co nie obsługuje przewijania jednym palcem i trzeba mu zostawić włączony scrollbar, na szczęście udało się go poprawić za pomocą stylów:

O kwestię layoutów mam ochotę zapytać któregoś z developerów, bo niestety są bardzo nieprzewidywalne. Nigdy nie wiadomo gdzie i jak dany widget się wyświetli. Na powyższym zrzucie odległości między obiektami są różne, a powinny być względnie spójne, bo na samym dole kontenera dodałem expander, który powinien wszystko co powyżej niego ładnie do siebie dosunąć…

Mam nadzieję, że kiedyś pojawi się spójne scrollview z obsługą single finger pan. Póki co się nie zanosi. A przecież aplikacji w QtWidgets jest niewspółmiernie więcej na wolności, niż w QtQuick.

AspeQt na Kazam Tornado 348.

A oto żywy dowód na prawidłową obsługę usb-host przez Kazam Tornado:

Przy okazji powiększyłem trochę przyciski i jeśli ekran jest mniejszy od 5″ to log jest wyłączony (wyświetla się na pasku statusu), a hbox-y wypełniają cały ekran:

Screenshot_2015-09-06-02-59-05Z małych ważnych zmian: usunąłem orientację poziomą i dzięki temu można sobie wybrać plik do załadowania w Fileselektorze w pionie (więcej się mieści).

scr-orient