弹窗功能
This commit is contained in:
+8
-1
@@ -9,6 +9,11 @@ int main(int argc, char *argv[])
|
||||
app.setApplicationName("FancyInput");
|
||||
app.setApplicationVersion("1.2.0");
|
||||
|
||||
// 显式锁定 QuickControls2 风格为 Basic:
|
||||
// 部署时裁剪掉了 Material/Universal/Imagine/FluentWinUI3,
|
||||
// 若不显式指定,Qt 6.7+ 默认 FluentWinUI3,找不到会直接崩溃。
|
||||
qputenv("QT_QUICK_CONTROLS_STYLE", "Basic");
|
||||
|
||||
// Qt 6 默认启用高 DPI 缩放,叠层/遮罩坐标后续用 devicePixelRatio 归一化
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
@@ -24,7 +29,9 @@ int main(int argc, char *argv[])
|
||||
&app, []() { QCoreApplication::exit(-1); },
|
||||
Qt::QueuedConnection);
|
||||
|
||||
engine.loadFromModule("FancyInputQt", "Main");
|
||||
// 加载 MainWindow.qml(Window 壳,内含 Rectangle 根的主界面 Main.qml):
|
||||
// 窗口级属性与内容自适应由 QML 侧处理,C++ 保持最简。
|
||||
engine.loadFromModule("FancyInputQt", "MainWindow");
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
+78
-8
@@ -2,18 +2,66 @@
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FancyInput.Controls
|
||||
import FancyInput.Windows
|
||||
|
||||
// 阶段 0:Hello World 骨架
|
||||
// 窗口尺寸沿用 WPF 主窗 600x480,主题色 #651F65
|
||||
ApplicationWindow {
|
||||
// 主界面(根元素为 Rectangle —— Qt Creator 设计模式可可视化编辑)
|
||||
// 由 main.cpp 用 QQuickWindow 包装成主窗口。
|
||||
Rectangle {
|
||||
id: root
|
||||
width: 600
|
||||
height: 480
|
||||
visible: true
|
||||
title: qsTr("FancyInput · Qt 迁移版(阶段 0)")
|
||||
|
||||
color: Theme.background
|
||||
|
||||
property int clickCount: 0
|
||||
|
||||
// 弹独立窗口:统一包装器现包装(等价 WPF 的 new SettingsWindow().Show())
|
||||
// 关键:createObject 的 parent 传 root(主窗口)→ FancyWindow 自动成为
|
||||
// transient parent 窗口(= WPF 的 Owner)。有了它:
|
||||
// · 非模态:随主窗口最小化/关闭,任务栏不单列
|
||||
// · 模态:Qt.WindowModal 在同一窗口组内生效,主窗口被系统禁用,
|
||||
// 点击主窗口时 Windows 自带标题栏闪烁反馈(同 WPF ShowDialog)
|
||||
function openSettingsWindow(modal) {
|
||||
var win = settingsWindowComp.createObject(modal ? root : null, { modal: modal })
|
||||
if (win) win.show()
|
||||
}
|
||||
// 打开无边框透明悬浮窗(WPF WindowStyle=None + AllowsTransparency + Topmost)
|
||||
function openOverlayWindow() {
|
||||
var win = overlayWindowComp.createObject(null, {})
|
||||
if (win) win.show()
|
||||
}
|
||||
// 设置窗口:FancyWindow 包装 SettingsWindow 内容
|
||||
Component {
|
||||
id: settingsWindowComp
|
||||
FancyWindow {
|
||||
width: 480
|
||||
height: 360
|
||||
windowTitle: qsTr("设置 · FancyInput")
|
||||
|
||||
SettingsWindow {
|
||||
anchors.fill: parent
|
||||
onCloseRequested: rootWindow.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 悬浮窗:无边框 + 透明 + 置顶 + 工具窗(FancyWindow 一键配置)
|
||||
Component {
|
||||
id: overlayWindowComp
|
||||
FancyWindow {
|
||||
width: 280
|
||||
height: 180
|
||||
frameless: true
|
||||
transparent: true
|
||||
alwaysOnTop: true
|
||||
toolWindow: true
|
||||
|
||||
OverlayWindow {
|
||||
anchors.fill: parent
|
||||
onCloseRequested: rootWindow.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 16
|
||||
@@ -63,7 +111,29 @@ ApplicationWindow {
|
||||
console.log("点击次数:", root.clickCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property int clickCount: 0
|
||||
// 打开独立窗口(WPF Window.Show 等价)
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("打开设置窗口")
|
||||
font.family: Theme.fontFamily
|
||||
onClicked: root.openSettingsWindow(false)
|
||||
}
|
||||
|
||||
// 打开模态窗口(WPF Window.ShowDialog 等价)
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("打开模态窗口")
|
||||
font.family: Theme.fontFamily
|
||||
onClicked: root.openSettingsWindow(true)
|
||||
}
|
||||
|
||||
// 打开无边框透明悬浮窗(WPF 悬浮窗等价)
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("打开悬浮窗")
|
||||
font.family: Theme.fontFamily
|
||||
onClicked: root.openOverlayWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import QtQuick
|
||||
import FancyInput.Controls
|
||||
import FancyInput.Windows
|
||||
|
||||
// 主窗口:用统一包装器 FancyWindow 包装主界面内容
|
||||
// 内容在 Main.qml(Rectangle 根,Qt Creator 可可视化编辑)
|
||||
// main.cpp 通过 loadFromModule("FancyInputQt", "MainWindow") 加载本文件。
|
||||
FancyWindow {
|
||||
id: win
|
||||
width: 600
|
||||
height: 480
|
||||
visible: true
|
||||
windowTitle: qsTr("FancyInput · Qt 迁移版(阶段 0)")
|
||||
|
||||
// 内容组件:anchors.fill 跟随窗口缩放
|
||||
Main {
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import QtQuick
|
||||
|
||||
// 统一窗口包装器(等价 WPF 的 Window 类)
|
||||
//
|
||||
// 用法:内容组件一律保持 Rectangle 根(Qt Creator 设计模式可可视化编辑),
|
||||
// 需要窗口时用本包装器现包装即可:
|
||||
//
|
||||
// FancyWindow {
|
||||
// width: 480
|
||||
// height: 360
|
||||
// windowTitle: qsTr("设置")
|
||||
// modal: true // 模态(WPF ShowDialog 等价)
|
||||
// SettingsWindow { anchors.fill: parent }
|
||||
// }
|
||||
//
|
||||
// // 无边框透明悬浮窗(WPF WindowStyle=None + AllowsTransparency + Topmost)
|
||||
// FancyWindow {
|
||||
// frameless: true
|
||||
// transparent: true
|
||||
// alwaysOnTop: true
|
||||
// toolWindow: true
|
||||
// OverlayWindow { anchors.fill: parent }
|
||||
// }
|
||||
//
|
||||
// 子项(内容组件)直接写在包装器里即可 —— Window 的 data 默认行为
|
||||
// 会自动把 Item 子项挂到内容区(contentItem)。
|
||||
Window {
|
||||
id: root
|
||||
|
||||
// 内容组件可通过 rootWindow 访问包装器(如 rootWindow.close() 关窗)
|
||||
// 固定别名,统一命名,避免每个包装处都要 id 转发
|
||||
property alias rootWindow: root
|
||||
|
||||
// ===== 窗口级属性(对齐 WPF Window) =====
|
||||
property string windowTitle: "" // 标题(WPF Title)
|
||||
property bool modal: false // true=ShowDialog(WindowModal),false=Show
|
||||
property bool frameless: false // 无边框(WPF WindowStyle=None)
|
||||
property bool transparent: false // 透明背景(WPF AllowsTransparency=True)
|
||||
property bool alwaysOnTop: false // 置顶(WPF Topmost)
|
||||
property bool toolWindow: false // 工具窗口:任务栏不显示、随 Owner 关闭
|
||||
|
||||
title: windowTitle
|
||||
modality: modal ? Qt.WindowModal : Qt.NonModal
|
||||
flags: Qt.Window
|
||||
| (frameless ? Qt.FramelessWindowHint : 0)
|
||||
| (alwaysOnTop ? Qt.WindowStaysOnTopHint : 0)
|
||||
| (toolWindow ? Qt.Tool : 0)
|
||||
color: transparent ? "transparent" : "#FFFFFF"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FancyInput.Controls
|
||||
|
||||
// 悬浮窗内容(根元素 Rectangle —— Qt Creator 设计模式可可视化编辑)
|
||||
// 使用场景:无边框透明窗口,只呈现内容本身,对应 WPF:
|
||||
// · WindowStyle=None → 包装层 flags: Qt.FramelessWindowHint
|
||||
// · AllowsTransparency=True → 包装层 color: "transparent"
|
||||
// · Topmost= true → 包装层 Qt.WindowStaysOnTopHint
|
||||
// 由调用方(Main.qml)用 Window 现包装,包装层负责窗口级属性。
|
||||
Rectangle {
|
||||
id: content
|
||||
width: 280
|
||||
height: 180
|
||||
color: "transparent" // 内容自身透明,只有卡片可见
|
||||
|
||||
// 请求关闭(Window 包装层监听后调用 close())
|
||||
signal closeRequested
|
||||
|
||||
// 无边框窗口没有标题栏,需自行实现拖拽移动。
|
||||
// 用系统原生拖拽(startSystemMove,等同拖标题栏):
|
||||
// 窗口系统接管整个移动过程(DWM 合成,移动的是窗口快照),
|
||||
// 流畅无闪烁 —— 手动跟踪鼠标坐标逐帧改 x/y 在透明窗口上会
|
||||
// 触发重绘同步,造成卡顿和残影(Windows 合成器下尤其明显)。
|
||||
MouseArea {
|
||||
id: dragArea
|
||||
anchors.fill: parent
|
||||
z: 0
|
||||
cursorShape: Qt.SizeAllCursor
|
||||
|
||||
onPressed: {
|
||||
var w = content.Window.window
|
||||
if (w) w.startSystemMove()
|
||||
}
|
||||
}
|
||||
|
||||
// 半透明圆角卡片(真正呈现的内容)
|
||||
Rectangle {
|
||||
id: card
|
||||
anchors.centerIn: parent
|
||||
width: 240
|
||||
height: 140
|
||||
radius: 16
|
||||
color: "#CC1E1E24" // 半透明主题 surface 色(alpha=0xCC)
|
||||
border.color: Theme.border
|
||||
border.width: 1
|
||||
z: 1
|
||||
|
||||
// 浅色描边让卡片在任意背景下都可见
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 16
|
||||
color: "transparent"
|
||||
border.color: "#33FFFFFF"
|
||||
border.width: 1
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16
|
||||
spacing: 10
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("悬浮窗")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("无边框 · 透明 · 置顶\n拖拽本窗口移动")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Theme.textSecondary
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("关闭")
|
||||
font.family: Theme.fontFamily
|
||||
onClicked: content.closeRequested()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FancyInput.Controls
|
||||
|
||||
// 设置窗口界面(根元素为 Rectangle —— Qt Creator 设计模式可可视化编辑)
|
||||
// 需要弹窗时由调用方(Main.qml)现场用 Window 包装,本组件只负责内容。
|
||||
Rectangle {
|
||||
id: content
|
||||
width: 480
|
||||
height: 360
|
||||
color: Theme.background
|
||||
|
||||
// 请求关闭(Window 包装层监听后调用 close())
|
||||
signal closeRequested
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 16
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("设置窗口(来自 FancyInput.Windows)")
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 18
|
||||
font.bold: true
|
||||
color: Theme.textPrimary
|
||||
}
|
||||
|
||||
// 复用 controls 模块的自定义控件,验证跨模块引用
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("关闭")
|
||||
font.family: Theme.fontFamily
|
||||
onClicked: content.closeRequested()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user