一、前言
在QML中,?頂級窗口不是絕對必需的?,但它在大多數應用場景中扮演著關鍵角色。
需要頂級窗口的典型場景:
1.獨立桌面/移動應用?
必須使用
Window
或ApplicationWindow
作為根元素。2.多窗口應用
每個獨立窗口都需要一個頂級窗口實例。
不需要頂級窗口的情況?
1.作為組件嵌入其他窗口
當QML文件被用作子組件時(通過
Loader
或直接嵌套)2.嵌入式系統
在嵌入式Linux(如使用EGLFS插件)可直接用
Item
作根元素
二、類型
1.Window
(基礎窗口)?
定位?:輕量級通用窗口,類似傳統 GUI 的 QWidget。
功能特性?:
- 僅提供基礎窗口屬性(標題、尺寸、可見性等)
- ?無預置框架?:需手動實現標題欄、關閉按鈕28
- 支持嵌套或獨立使用(如彈窗)
適用場景?:自定義彈窗、簡單浮動窗口、輕量級應用
2.ApplicationWindow
(應用主窗口)?
定位?:功能完整的應用框架,類似 QMainWindow。
功能特性?:
- 內置應用框架結構:支持菜單欄(
menuBar
)、工具欄(header
)、狀態欄(footer
)17- 內容區域(
contentItem
)自動管理布局
適用場景?:復雜桌面應用主窗口(需菜單/工具欄)
?3.區別
特性? | ?Window ? | ?ApplicationWindow ? |
---|---|---|
?功能定位? | 輕量級基礎容器 | 完整應用框架 |
?內置組件? | ? 無標題欄/菜單欄 | ? 支持菜單欄/工具欄/狀態欄 |
?內容管理? | 手動布局子元素 | 提供 contentItem 自動布局區域 |
?復雜度? | 低(適合簡單場景) | 高(適合復雜應用) |
?所屬模塊? | QtQuick.Window | QtQuick.Controls |
關鍵注意?:所有頂級窗口必須顯式設置 visible: true?和有效尺寸(如 width/height),否則會導致界面無法渲染?
三、屬性
1.Window
(基礎窗口)?
需要導入模塊
import QtQuick.Window 2.2
?分類? | ?屬性? | ?類型? | ?說明? | ?示例? |
---|---|---|---|---|
?窗口狀態? | visible | bool | 控制窗口顯示/隱藏(默認false ) | visible: true |
active | bool (只讀) | 指示窗口是否為活動窗口 | onActiveChanged: console.log(active) | |
modality | Qt::WindowModality | 窗口模態類型(非模態/窗口模態/應用模態) | modality: Qt.WindowModal | |
?尺寸位置? | width /height | int | 窗口初始尺寸(像素) | width: 800; height: 600 |
maximumWidth/maximumHeight | int | 窗口最小/最大尺寸限制 | minimumWidth: 400; maximumHeight: 900 | |
x /y | int | 窗口左上角屏幕坐標 | x: 100; y: 200 | |
?內容布局? | contentItem | Item (只讀) | 窗口內容根Item | Component.onCompleted: console.log(contentItem) |
activeFocusItem | Item (只讀) | 當前獲得鍵盤焦點的子Item | onActiveFocusItemChanged: focusItem.color = "red" | |
contentOrientation | Qt::ScreenOrientation | 強制內容旋轉方向(橫屏/豎屏) | contentOrientation: Qt.LandscapeOrientation | |
?視覺樣式? | color | color | 窗口背景色 | color: "#F0F0F0" |
opacity | real | 透明度(0.0透明~1.0不透明) | opacity: 0.8 | |
title | string | 窗口標題欄文字 | title: "設置面板" | |
?高級控制? | flags | Qt::WindowFlags | 窗口行為標志(如無邊框/置頂) | flags: Qt.FramelessWindowHint |
transientParent | QWindow | 關聯父窗口(用于對話框歸屬) | transientParent: mainWindow | |
screen | variant | 綁定到特定顯示器3 | screen: Qt.application.screens | |
visibility | QWindow::Visibility | 窗口顯示模式(全屏/最小化等) | visibility: Window.FullScreen | |
?其他? | data | list<Object> | 動態存儲子對象列表 | 通常自動管理 |
2.ApplicationWindow
(應用主窗口)?
分類? | ?屬性? | ?類型? | ?說明? | ?示例? |
---|---|---|---|---|
?焦點控制? | activeFocusControl | Control | 當前獲得鍵盤焦點的子控件(只讀屬性) | Text { focus: true } // 當該Text獲得焦點時,父控件此屬性指向它 |
?背景裝飾? | background | Item | 控件的背景元素,可覆蓋默認樣式 | background: Rectangle { color: "lightblue" } |
?內容容器? | contentData | list<Object> | 動態添加子項的默認列表(自動成為contentItem的子項) | Component.onCompleted: contentData.push(Qt.createComponent("Button.qml")) |
contentItem | Item | 內容項的根容器,用于布局子控件 | contentItem: RowLayout { spacing: 5 } | |
?文本樣式? | font | font | 控件內文本的字體屬性(可繼承) | font { family: "Arial"; pixelSize: 16 } |
?結構布局? | footer | Item | 底部區域(如Page組件的頁腳) | footer: ToolBar { Label { text: "Status" } } |
header | Item | 頂部區域(如Page組件的標題欄) | header: TabBar { TabButton { text: "Home" } } | |
?本地化? | locale | Locale | 區域設置(影響日期/數字格式) | locale: Qt.locale("zh_CN") |
?菜單系統? | menuBar | Item | 菜單欄容器(ApplicationWindow專用) | menuBar: MenuBar { Menu { title: "File" } } |
?顏色主題? | palette | palette | 控件的調色板(可覆蓋系統主題) | palette { buttonText: "red" } |
?menuBar
核心屬性與方法
?組件? | ?屬性/方法? | ?類型? | ?說明? | ?示例? |
---|---|---|---|---|
?menuBar? | delegate | Component | 自定義菜單項渲染模板 | delegate: MenuBarItem { text: model.title } |
menus | list<Menu> | 包含所有子菜單的只讀列表 | onClicked: console.log(menuBar.menus.length) | |
addMenu(Menu) | Method | 動態添加菜單 | menuBar.addMenu(Qt.createQmlObject('Menu{title:"Tools"}', menuBar)) | |
takeMenu(int) | Method | 移除指定索引的菜單 | menuBar.takeMenu(0).destroy() |
header
支持的組件類型??
組件類型? | ?說明? | ?典型應用場景? | ?示例代碼? |
---|---|---|---|
?ToolBar ? | 標準工具欄組件,通常包含操作按鈕或導航控件 | 應用頂部導航欄 | header: ToolBar {ToolButton { icon.source: "menu.svg" } Label { text: "應用標題" }} |
?TabBar ? | 選項卡欄組件,用于頁面切換 | 多頁面應用的標簽導航 | header: TabBar {TabButton { text: "首頁" } TabButton { text: "設置" }} |
?Rectangle ? | 基礎矩形容器,可自定義顏色/漸變 | 自定義背景的簡單標題欄 | header: Rectangle {color: "lightblue"; Label { anchors.centerIn: parent; text: "標題" }} |
?Row /RowLayout ? | 水平布局容器,排列子控件 | 組合多個控件(圖標+文字) | header: RowLayout { Image { source: "logo.png" } Label { text: "系統名稱"; Layout.fillWidth: true }} |
?Label ? | 文本標簽 | 簡易標題顯示 | header: Label {text: "歡迎頁面";horizontalAlignment: Text.AlignHCenter} |
?SwipeView ? | 滑動視圖容器 | 可橫向滑動的Banner區域 | header: SwipeView {Image { source: "banner1.jpg" } Image { source: "banner2.jpg" }} |
?自定義組件? | 用戶復合組件(如MyCustomHeader.qml ) | 復用復雜UI結構 | header: MyCustomHeader { title: "儀表盤" showBackButton: true} |
footer
支持的組件類型
同上? ,把示例中的header換成footer
四、代碼示例
1.Window
(基礎窗口)?
import QtQuick 2.6
import QtQuick.Window 2.2Window {visible: truewidth: 400height: 300minimumWidth: 400title: "基礎窗口"flags: Qt.Window | Qt.WindowStaysOnTopHintcolor: "lightyellow"Text {text: qsTr("Hello, World!"); font.pixelSize: 24; anchors.centerIn: parent}
}
?運行結果:
2.ApplicationWindow
(應用主窗口)?
import QtQuick 2.6
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.6ApplicationWindow {visible: trueid: mainWindowtitle: "應用主窗口"width: 800height: 600// 菜單欄實現menuBar: MenuBar {Menu {title: "文件"Action {text: "新建"onTriggered: fileHandler.createNew()}Action {text: "打開"onTriggered: fileHandler.openFile()}MenuSeparator {}Action {text: "退出"onTriggered: Qt.quit()}}Menu {title: "編輯"MenuItem {text: "復制"onTriggered: {textCopy.selectAll(); textCopy.copy()}}MenuItem {text: "粘貼"onTriggered: textEditor.paste()}}}// 狀態欄footer: Label {text: "就緒"}header: ToolBar {background: Rectangle {color: "lightyellow"}RowLayout {anchors.fill: parentLabel {text: "Title"elide: Label.ElideRighthorizontalAlignment: Qt.AlignHCenterverticalAlignment: Qt.AlignVCenterLayout.fillWidth: true}ToolButton {text: qsTr("?")onClicked: menu.open()}}}// 主內容區域SplitView {anchors.fill: parentorientation: Qt.VerticalTextEdit {id: textEditorhorizontalAlignment: Text.AlignHCenterwrapMode: TextEdit.WrapSplitView.fillHeight: trueselectByMouse: true}TextEdit {id: textCopyhorizontalAlignment: Text.AlignHCenterwrapMode: TextEdit.Wraptext:"在此輸入要復制的內容"color: "blue"SplitView.minimumWidth: 400selectByMouse: true}}// 業務邏輯處理對象QtObject {id: fileHandlerfunction createNew() {textEditor.text = "新建文件"console.log("新建文件邏輯")}function openFile() {textEditor.text = "打開文件"console.log("打開文件邏輯")}}
}
運行結果: