跳到主要内容

Window介绍

一、环境配置

Tip

我使用的是 VsCode 在 win 上写 qt

1.1 CMake

set(projectName "HX-01-QML")

project(${projectName}
VERSION 0.0.1
DESCRIPTION ${projectName}
HOMEPAGE_URL "https://github.com/HengXin666/HXTest"
LANGUAGES CXX
)

# QT Start
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

file(GLOB_RECURSE src_files CONFIGURE_DEPENDS
src/*.cpp
include/*.h
include/*.hpp
)

file(GLOB_RECURSE qrc_files CONFIGURE_DEPENDS
resources/*.qrc
)

find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Qml Quick)

qt_add_executable(${projectName}
${src_files}
${qrc_files}
)

target_compile_features(${projectName} PUBLIC cxx_std_20)

target_link_libraries(${projectName}
PRIVATE Qt::Core
PRIVATE Qt::Gui
PRIVATE Qt::Widgets
PRIVATE Qt::Qml
PRIVATE Qt::Quick
)

# 添加 QML 文件所在目录作为资源路径 (推荐方式)
qt_add_qml_module(${projectName}
URI ${projectName}
VERSION 1.0
QML_FILES
qml/Main.qml
)

if (WIN32)
# 解决路径问题, 确保 windeployqt.exe 存在
set(QT_BIN_DIR "${QT_COMPILER_PATH}/bin")
if(NOT EXISTS "${QT_BIN_DIR}/windeployqt.exe")
message(FATAL_ERROR "Error: windeployqt.exe not found in ${QT_BIN_DIR}")
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Debug")
add_custom_command(TARGET ${projectName} POST_BUILD
COMMAND "${QT_BIN_DIR}/windeployqt.exe" --debug "$<TARGET_FILE:${projectName}>"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/Debug"
)
elseif (CMAKE_BUILD_TYPE STREQUAL "Release")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Release")
add_custom_command(TARGET ${projectName} POST_BUILD
COMMAND "${QT_BIN_DIR}/windeployqt.exe" --release "$<TARGET_FILE:${projectName}>"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/Release"
)
endif()
endif()

set_target_properties(${projectName} PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE OFF
WIN32_EXECUTABLE OFF # 这里需要为 OFF 才可以让vscode在控制台中输出...
)

include(GNUInstallDirs)
install(TARGETS ${projectName}
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
cmake

1.2 main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection
);
engine.loadFromModule("HX-01-QML", "Main");

return app.exec();
}
cpp

1.3 文件结构

.
| - include
|
| - src
| | - main.cpp
|
| - qml
| | - Main.qml
|
| - CMakeLists.txt
shell

二、初识QML

Note

官方文档: QT-6: QML 参考资料

2.1 qml默认内容

import QtQuick

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
}
qml

这长的像是 js...

2.2 Window 常用属性讲解

以下是 Window 的常用属性, 其他属性请查阅官方文档.

import QtQuick

Window { // root 控件, 父窗口是主界面
width: 640
height: 480
visible: true
title: qsTr("Hello World")

// 相对于 父控件 的位置
x: 50
y: 50

// 控制窗口大小
minimumWidth: 400
minimumHeight: 300
maximumWidth: 720
maximumHeight: 560

// 设置窗口透明度: 0.00 ~ 1.00
opacity: 0.5
}
qml

2.3 信号与槽

2.3.1 自定义信号与槽

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")

// 自定义信号
// hxSig信号名, `()`是参数列表
signal hxSig()

// on + 大写开头的信号 => 就是对应的槽
onHxSig: {

}
}
qml

2.3.2 默认的槽函数

这种 onXxx的就是触发某信号时候调用的槽函数

import QtQuick

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")

// 宽度变化触发该槽
onWidthChanged: {
console.log("宽度变化:", width)
}
}
qml

2.4 自定义属性

import QtQuick

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")

// 自定义属性
property int hxVal: 0

// 自定义属性, 也会自动生成对应槽, 并且自动连接
onHxValChanged: {
console.log("hxVal 被修改了", hxVal);
}
}
qml

2.5 焦点 (focus)

Tip

特别的, 有时候如果我们发现键盘事件没用, 那大概率是像下面这种, focus 跑到别的地方去了.

import QtQuick
import QtQuick.Controls

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
color: "#990099" // 颜色

// 焦点
Button {
id: btn1 // 唯一标识
objectName: "左边的按钮" // 名称 (给人看的)
focus: true // 设置默认获取焦点

x: 50
y: 50
width: 50
height: 50

background: Rectangle { // 设置矩形边框样式
border.width: 6
// 根据是否有焦点, 响应式更新
border.color: btn1.focus ? "blue" : "black";
}

onCheckedChanged: {
console.log("点击了按钮")
}
Keys.onRightPressed: {
btn2.focus = true;
}
}

Button {
id: btn2
objectName: "右边的按钮"
focus: true

x: 150
y: 50
width: 50
height: 50

background: Rectangle {
border.width: 6
border.color: btn2.focus ? "blue" : "black";
}

onCheckedChanged: {
console.log("点击了按钮")
}
Keys.onLeftPressed: {
btn1.focus = true;
}
}

// 焦点改变信号
onActiveFocusItemChanged: {
console.log("当前焦点所在元素", activeFocusItem, activeFocusItem.objectName);
}
}
qml
请作者喝奶茶:
Alipay IconQR Code
Alipay IconQR Code
本文遵循 CC CC 4.0 BY-SA 版权协议, 转载请标明出处
Loading Comments...