このページでは

C

Qt Quick Ultralite static_library の例

Qt Quick Ultralite スタティック・ライブラリの作成と使用方法を示します。

概要

この例では、Qt Quick Ultralite静的ライブラリを作成し、異なるアプリケーションと統合する方法を示します。静的ライブラリとしてコンパイルされたQt Quick Ultralite GUIと、静的ライブラリにリンクする実行可能アプリケーションです。アプリケーションはセンサーデータをシミュレートするためのシンプルなAPIも提供します。Qt Quick Ultralite GUI はこのインターフェースを使用してセンサーデータを受信し、画面に表示します。

Qt Quick Ultraliteを静的ライブラリとして構築する方法については、こちらをご覧ください。

注意: スタティック・ライブラリのセットアップはFreeRTOS では動作しません。

プロジェクトの構造

プロジェクトには2つのサブプロジェクトが含まれます:Qt Quick Ultralite GUI静的ライブラリと実行可能アプリケーションです。これらのプロジェクトはどちらも独自のCMakeLists.txt ファイルを持っており、対応するターゲットを作成し、依存ファイルを追加します。

静的ライブラリCMakeプロジェクト

スタティック・ライブラリのターゲットを作成するには、STATIC_LIBRARY オプションをqul_add_target関数の引数として指定する必要があります。

...
qul_add_target(Qt4MCU_GUI STATIC_LIBRARY QML_PROJECT qt4mcu.qmlproject GENERATE_ENTRYPOINT)
...

次に、ライブラリーのQmlProjectファイルのInterfaceFiles.filesを使用して、sensorData.h ヘッダーファイルをQt Quick Ultraliteインターフェースとして登録します。これにより、メインアプリケーションからセンサーデータを受信できるようになります。このインターフェースのメソッドは、QmlFiles.filesを使用してプロジェクトに追加されたmainGui.qml で使用されます。

        QmlFiles {
                files: ["mainGui.qml"]
        }

        InterfaceFiles {
                files: ["sensorData.h"]
        }

sensorAPI.h ヘッダーファイルを含むフォルダをインクルード・ ディレクトリ・リストに追加してください。

注: EXAMPLE_ROOT_DIR はアプリケーションの CMake ファイルから派生したものです。

...
target_include_directories(Qt4MCU_GUI
    PRIVATE
        ${EXAMPLE_ROOT_DIR}/include
)
...

mainGui.qmlQtQuick.Controls QML モジュールを使用しており、Qt4MCU_GUI ターゲットをQul::Controls ライブラリにリンクする必要があります。詳細については、Qt Quick Ultralite styling Exampleを参照してください。

        ModuleFiles {
                MCU.qulModules: ["Controls"]
        }

add_qul_target CMakeコマンドでGENERATE_ENTRYPOINT 、スタティック・ライブラリーのデフォルト・エントリーポイントを生成します。これは、qul_run() エントリポイント関数を含むqul_run.h ヘッダーファイルを生成します。アプリケーションは、Qt Quick Ultraliteエンジンを構成して起動するために、この関数を呼び出す必要があります。

...
qul_add_target(Qt4MCU_GUI STATIC_LIBRARY QML_PROJECT qt4mcu.qmlproject GENERATE_ENTRYPOINT)
...

注: initializeHardwarefalse に設定してqul_run() を呼び出した場合、Qul::initHardware() は呼び出されません。

アプリケーション CMake プロジェクト

Qt Quick Ultraliteアプリケーションを作成するには、add_executable CMake関数を呼び出します。また、main.cpp ファイルをターゲット・ソース・リストにインクルードしてください。

...
add_executable(static_library_example
        src/main.cpp
)
...

リリース構成のQt Quick Ultralite 静的ライブラリは、手続き間最適化(リンク時最適化)が有効になっています。これは、このようなライブラリにリンクするアプリケーションも同じ設定でなければならないことを意味します。次のスニペットは、Qt Quick Ultralite スタティック・ライブラリの IPO 設定チェックを行い、アプリケーションに同じ設定を適用する方法を示しています。

...
get_target_property(QUL_LIB_IPO_CONFIG Qt4MCU_GUI INTERPROCEDURAL_OPTIMIZATION)
set_target_properties(static_library_example PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${QUL_LIB_IPO_CONFIG})
...

アプリケーションには、Qt Quick Ultraliteルートディレクトリと、qul_run.h を含むフォルダへのパスを含める必要があります。しかしこの例では、sensorAPI.h が追加ヘッダーファイルとしてインクルードされています。

...
target_include_directories(static_library_example
    PRIVATE
        # Add include folder from QtForMCU installation folder
        ${Qul_DIR}/include
        # Add folder containing qul_run.h header file
        ${CMAKE_CURRENT_BINARY_DIR}/lib/Qt_for_MCU
        # Add folder containing sensorAPI.h header file
        ${CMAKE_CURRENT_SOURCE_DIR}/include
)
...

アプリケーションは、静的ライブラリがリンクするすべてのライブラリにもリンクする必要があります。

注: Qt Quick Ultraliteには、いくつかのライブラリ間の循環依存関係が含まれています。次の例のように、Qul::Core とリストの最後にある GUI lib にリンクすることで解決できます。

target_link_libraries(static_library_example
    PRIVATE
        # Static library containing UI and interfaces
        Qt4MCU_GUI

        # Depending on which features the Qt4MCU_GUI static library is using,
        # you need to link the proper static library to the executable.
        # In this example list of the libraries which are changing depending on
        # CMake variables configuration are described. Just uncomment those which
        # apply to your setup. Config which applies to this example is uncommented.

        #
        # Font engines:
        #   - If QUL_FONT_ENGINE == Spark
        #       If QUL_PLATFORM_REQUIRED_IMAGE_ALIGNMENT not set or 0 or 1
        #           Qul::MonotypeFontEngine
        #       else
        #           Qul::MonotypeFontEngineAligned
        #
        #       If QUL_COMPLEX_TEXT_RENDERING == ON
        #           Qul::MonotypeShaperEngine
        #           Qul::MonotypeUnicodeEngine
        #       else
        #           Qul::MonotypeUnicodeEngineShaperDisabled
        #
        #   - If QUL_FONT_ENGINE == Static
        #           Qul::MonotypeUnicodeEngineShaperDisabled
        #
        Qul::MonotypeUnicodeEngineShaperDisabled

        # PNG decoder (add when project uses PNG images):
        #   - QUL_RESOURCE_COMPRESSION == ON
        # Qul::PNGDecoderLodePNG
        #   - QUL_RESOURCE_COMPRESSION not set or OFF
        # Qul::PNGDecoderNull

        # Additional lib which needs to be linked along to Qt QuickUltralite Core
        $<$<BOOL:${CMAKE_CROSSCOMPILING}>:Qul::DeviceLink>

        # Static library with Qt QuickUltralite Core
        Qul::Core
        # Static library with Qt QuickUltralite Platform abstraction.
        # Should be replaced by custom implementation adapted to target board
        Qul::Platform
        # All additional Qul libraries used by QtForMCU GUI needs to be also
        # linked with application
        Qul::Controls
        # Satisfy cyclic dependency between Qt4MCU_GUI and Qul::Core
        # libraries (Qul::Core depends on symbols autogenerated
        # in Qt4MCU_GUI build process)
        # Same sets of libraries chosen above need to match those below.
        # For example if above we choose Qul::MonotypeUnicodeEngineShaperDisabled
        # then here below we add the same library as cyclic dependency to Qul::Core.
        Qul::Core
        $<$<BOOL:${CMAKE_CROSSCOMPILING}>:Qul::DeviceLink>
        Qul::MonotypeUnicodeEngineShaperDisabled
        Qt4MCU_GUI
)
Qt Quick Ultraliteスタティック・ライブラリーとのインターフェース

前述のように、サンプルアプリケーションは API を通してセンサーデータを提供する。Qt Quick Ultralite スタティックライブラリはこの API を使ってセンサーデータを取得し、Qt Quick Ultralite C++ インタフェースを使って QML に公開しています。

注: Qt Quick Ultralite は別のタスクから QML のプロパティを変更するスレッドセーフな方法を提供しません。

...
#include "sensorAPI.h"

struct SensorData : Qul::Singleton<SensorData>
{
    SensorData()
        : sensorRawValue(0)
    {}
    Qul::Property<int> sensorRawValue;
    void updateSensorValue() { sensorRawValue.setValue(getSensorValue()); }
};
...

この例のgetSensorValue() 関数はランダムな値を返します。

...
int getSensorValue()
{
    return static_cast<uint32_t>(static_cast<double>(100) * Qul::Platform::getPlatformInstance()->rand());
}
...

ファイル


詳細はこちら。