C
Qt Quick Ultralite static_library の例
Qt Quick のUltralite静的ライブラリの作成方法と使用方法を示します。
概要
このサンプルでは、Qt Quick のUltralite静的ライブラリを作成し、別のアプリケーションに組み込む方法を示します。このサンプルには、静的ライブラリとしてコンパイルされたQt Quick のUltralite GUIと、その静的ライブラリにリンクする実行可能アプリケーションという2つのターゲットが含まれています。また、アプリケーションにはセンサーデータをシミュレートするためのシンプルなAPIも用意されています。Qt Quick のUltralite GUIは、このインターフェースを使用してセンサーデータを受信し、画面に表示します。
Qt Quick のUltraliteを静的ライブラリとしてビルドする方法の詳細については、こちらをご覧ください。
注: 静的ライブラリの設定は 、FreeRTOS では動作しません。

プロジェクトの構成
このプロジェクトには、Qt Quick Ultralite GUIの静的ライブラリと実行可能アプリケーションという2つのサブプロジェクトが含まれています。これらのプロジェクトにはそれぞれ独自のCMakeLists.txt ファイルがあり、それによって対応するターゲットが作成され、依存ファイルが追加されます。
静的ライブラリのCMakeプロジェクト
静的ライブラリターゲットを作成するには、qul_add_target関数の引数としてSTATIC_LIBRARY オプションを指定する必要があります。
...
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.qml は、QtQuick.Controls QMLモジュールを使用しており、Qt4MCU_GUI ターゲットをQul::Controls ライブラリにリンクする必要があります。詳細については、Qt Quick のUltraliteスタイリングの例を参照してください。
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)
...注: `initializeHardware ` が `false` に設定された状態で `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 ライブラリにリンクすることで、この問題を解決できます。
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());
}
...ファイル:
特定のQtライセンスの下で利用可能です。
詳細はこちら。