目前市面上的Qt无边框窗口方案多结合Windows DirectX API实现,抹除了Qt的多平台优势。
QWindowKit是一个开源跨平台的Qt无边框窗口组件库,支持Qt5.12以上版本。
借助QWindowKit项目,我们可以轻松在自己的Qt项目中实现无边框窗口效果。
本文将介绍使用Qt Quick并结合CMake调用QWindowKit库。QWidget应用类似,可参考官方帮助文档。
初始化工程
使用Qt Creator新建一个Qt Quick应用工程。若已有项目,可以跳过该步。
默认初始工程
1
2
3
| mkdir 3rdparty
git submodule add https://github.com/stdware/qwindowkit.git 3rdparty/qwindowkit
git submodule update --init --recursive
|
添加完毕后,项目结构如下:
1
2
3
4
5
6
7
8
| ├─3rdparty
│ └─qwindowkit
│ ......
├─build
│ ......
│CMakeLists.txt
│main.cpp
│Main.qml
|
使用CMake将QWindowKit作为子目录加入到工程中
- 编辑项目目录下的CMakeLists.txt,加入QWindowKit子目录并设置相关参数,再将我们自己的主程序和QWindowKit的库链接起来;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| cmake_minimum_required(VERSION 3.16)
project(framelessQML VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#[1]
set(QWINDOWKIT_BUILD_STATIC ON)
set(QWINDOWKIT_BUILD_EXAMPLES OFF)
set(QWINDOWKIT_BUILD_QUICK ON)
set(QWINDOWKIT_BUILD_WIDGETS OFF)
set(QWINDOWKIT_ENABLE_STYLE_AGENT ON)
set(QWINDOWKIT_INSTALL OFF)
add_subdirectory(3rdparty/qwindowkit)
#[1]
find_package(Qt6 6.5 REQUIRED COMPONENTS Quick)
qt_standard_project_setup(REQUIRES 6.5)
qt_add_executable(appframelessQML
main.cpp
)
qt_add_qml_module(appframelessQML
URI framelessQML
VERSION 1.0
QML_FILES
Main.qml
)
# 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(appframelessQML PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appframelessQML
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(appframelessQML
PRIVATE Qt6::Quick
)
#[2]
target_link_libraries(appframelessQML
PUBLIC QWindowKit::Quick
)
include_directories(3rdparty/qwindowkit/include)
#[2]
include(GNUInstallDirs)
install(TARGETS appframelessQML
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
|
实现无边框窗口
参考官网的Example,修改main.cpp和Main.qml文件;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| //main.cpp
#include <QtQuick/QQuickWindow>
#include <QQmlApplicationEngine>
//[1]
#include <QWKQuick/qwkquickglobal.h>
//![1]
int main(int argc, char *argv[])
{
//[2]
qputenv("QT_WIN_DEBUG_CONSOLE", "attach");
qputenv("QSG_INFO", "1");
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
qputenv("QT_QUICK_CONTROLS_STYLE", "Basic");
#else
qputenv("QT_QUICK_CONTROLS_STYLE", "Default");
#endif
qputenv("QSG_RHI_BACKEND", "opengl");
//qputenv("QSG_RHI_HDR", "scrgb");
//qputenv("QT_QPA_DISABLE_REDIRECTION_SURFACE", "1");
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
//![2]
QGuiApplication app(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
QQmlApplicationEngine engine;
//[3]
QWK::registerTypes(&engine);
//![3]
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("framelessQML", "Main");
return app.exec();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| #Main.qml
import QtQuick
import QWindowKit 1.0
Window {
id: window
width: 800
height: 600
color: darkStyle.windowBackgroundColor
title: qsTr("Hello, world!")
Component.onCompleted: {
windowAgent.setup(window)
window.visible = true
}
QtObject {
id: lightStyle
}
QtObject {
id: darkStyle
readonly property color windowBackgroundColor: "#1E1E1E"
}
WindowAgent {
id: windowAgent
}
Rectangle {
id: titleBar
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: 32
color: window.active ? "#3C3C3C" : "#505050"
Component.onCompleted: windowAgent.setTitleBar(titleBar)
Text {
anchors {
verticalCenter: parent.verticalCenter
left: iconButton.right
leftMargin: 10
}
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: window.title
font.pixelSize: 14
color: "#ECECEC"
}
}
}
|
构建/部署/运行
参考使用以下CMake参数进行CMake配置:
1
2
3
4
| -DCMAKE_PREFIX_PATH=C:\Qt\6.7.2\mingw_64
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_CXX_COMPILER:FILEPATH=C:/Qt/Tools/mingw1120_64/bin/g++.exe
-DCMAKE_CXX_FLAGS_INIT:STRING=-DQT_QML_DEBUG
|
使用以下参数进行CMake构建:
1
| --parallel --target all
|
构建完成后,除Windows以外的平台可以直接运行可执行文件。Windows平台下需要使用windeploy进行部署。
1
| C:\Qt\6.7.2\mingw_64\bin\windeployqt.exe --qmldir C:\Qt\6.7.2\mingw_64\qml .\appframelessQML.exe
|
效果