系列文章目录
一、创建 Qt Quick Application
打开 QtCreator,点击菜单 File => New Project
修改后的 CMakeLists.txt
大致如下:
cmake_minimum_required(VERSION 3.16)
project(swApp VERSION 0.1 LANGUAGES CXX)
if (CMAKE_SYSTEM_NAME MATCHES "^Linux")
if (NOT LINUX)
set(LINUX 1)
endif ()
endif ()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (WIN32)
add_compile_definitions(_WIN32_)
set(SwApiTopDir "${CMAKE_SOURCE_DIR}/../swApi")
elseif (LINUX)
add_compile_definitions(_LINUX_)
set(SwApiTopDir "${CMAKE_SOURCE_DIR}/../swApi")
endif ()
# set(CMAKE_MAKE_PROGRAM "C:/Program Files/CMake/bin/ninja.exe" CACHE FILEPATH "Path to make executable")
INCLUDE_DIRECTORIES(${SwApiTopDir})
INCLUDE_DIRECTORIES(${SwApiTopDir}/3rdParty/include)
LINK_DIRECTORIES(${SwApiTopDir}/build/RelWithDebInfo)
set(baseDir ${CMAKE_CURRENT_LIST_DIR})
file(GLOB baseUtilsSources ${baseDir}/utils/*.cpp ${baseDir}/utils/*.h)
INCLUDE_DIRECTORIES(${baseDir}/utils)
# message(STATUS "baseUtilsSources:${baseUtilsSources}")
find_package(Qt6 REQUIRED COMPONENTS Quick)
qt_standard_project_setup(REQUIRES 6.8)
qt_add_executable(swApp
main.cpp
Log.h Log.cpp
Bridge.h Bridge.cpp
${baseUtilsSources}
)
# 设置单例
set_source_files_properties(Bridge.qml
PROPERTIES
QT_QML_SINGLETON_TYPE true
)
qt_add_qml_module(swApp
URI swApp
VERSION 1.0
QML_FILES Main.qml
QML_FILES TTYView.qml
QML_FILES JtagView.qml
QML_FILES Bridge.qml
RESOURCES swApp.qrc
)
# 增加资源文件
qt_add_resources(swApp "configuration"
PREFIX "/"
FILES
qtquickcontrols2.conf
)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(swApp PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.swApp
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
target_link_libraries(swApp
PRIVATE Qt6::Quick
PRIVATE swApi
)
include(GNUInstallDirs)
install(TARGETS swApp
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
QT_QML_SINGLETON_TYPE
set_source_files_properties(Bridge.qml
PROPERTIES
QT_QML_SINGLETON_TYPE true
)
QT_QML_SINGLETON_TYPE true
控制对应的 Bridge.qml 编译成单例。
- Bridge.qml
pragma Singleton
import QtQuick 2.0
Item {
}
- qmldir
module BridgeModule
singleton Bridge 1.0 Bridge.qml
qt_add_resources
qt_add_resources(swApp "configuration"
PREFIX "/"
FILES
qtquickcontrols2.conf
)
qt_add_resources
增加资源文件。qtquickcontrols2.conf
可控制控件显示的风格。
[Controls]
# Style=Basic
# Style=Fusion
# Style=Material
# [Material]
# Theme=Light
# Accent=Teal
# Primary=BlueGrey
# Foreground=White
# Background=Black
# Font\Family=Microsoft YaHei
# Font\PixelSize=16
二、Loader中的Component访问
Window {
Component {
id: myComponent
Row {
id: root
// 显式导出子对象(Text)为属性,供外部访问
property Item myTextItem: textItem // 关键:将子对象暴露为属性
signal textClicked() // 自定义信号
Text {
id: textItem
text: "Hello from Loader!"
font.pixelSize: 20
MouseArea {
anchors.fill: parent
onClicked: root.textClicked() // 子对象触发信号
}
}
// 可选:添加自定义方法供外部调用
function changeText(newText) {
textItem.text = newText;
}
}
}
Loader {
id: loader
anchors.centerIn: parent
sourceComponent: myComponent // 加载子组件
// 监听加载完成事件(确保组件已实例化)
onLoaded: {
loader.item.textClicked.connect(() => {
console.log("Text clicked!");
});
// 访问子组件的公开属性(myTextItem)
console.log("Loaded text:", loader.item.myTextItem.text); // 输出:"Hello from Loader!"
// 调用子组件的公开方法
loader.item.changeText("Text updated by external!");
}
}
}
可以通过以下方式访问 Component 中的子对象:
- 通过定义公开方法访问
- 通过定义信号访问
- 通过定义属性访问
除了以上几种方法访问,也可以通过如下方式访问:
var childs = loader.item.children
for (var i = 0; i < childs.length) {
const child = childs.children[i];
console.log(`子对象 ${i}:`, child.objectName || "未命名");
}
而以下几种看起来好像无效
onLoaded: {
// 方法 1:直接通过路径查找(需知道子对象的完整层级)
// 假设已知子对象路径为 root.textItem
let textItem = loader.item.root.textItem;
console.log("Found text (direct path):", textItem.text);
// 方法 2:使用 findChild 递归查找(更灵活)
let foundItem = loader.item.findChild("textItem"); // 根据 ID 查找
if (foundItem) {
console.log("Found text (findChild):", foundItem.text);
}
}