如何解决Qml Popup不在子窗口顶部
我有一个Qml应用,该应用具有Win32窗口作为子窗口。现在,我只想在Win32窗口顶部单击一个按钮(或本例中的Image)显示一个弹出窗口,但是弹出窗口不在顶部。
工作代码如下:-
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QWindow>
#include "qt_windows.h"
#include "Windows.h"
#pragma comment(lib,"user32.lib")
/*
* Input Window proc
*/
LRESULT CALLBACK uiInputWindowProc(
HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
/*
* Create window that receives and forwards input
*/
void uiCreateInputWindow(
HWND parentWindow,int x,int y,int width,int height)
{
#define UI_INPUT_WINDOW_CLASS L"uiNativeInputWindowClass"
/*
* Register Window Class
*/
WNDCLASSEX wcex;
wcex.cbSize = sizeof wcex;
wcex.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)uiInputWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(void*);
wcex.hInstance = NULL;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = UI_INPUT_WINDOW_CLASS;
wcex.hIconSm = NULL;
if (RegisterClassEx(&wcex) == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
{
return;
}
DWORD style = WS_CHILD;
DWORD exstyle = 0;
/*
* Create Window
*/
HWND hwnd = CreateWindowEx(
exstyle,// dwExStyle
UI_INPUT_WINDOW_CLASS,// lpClassName
L"uiNativeInputWindow",// lpWindowName
style,// dwStyle
x,// x
y,// y
width,// nWidth
height,// nHeight
parentWindow,// hWndParent
NULL,// hMenu
0,// hInstance
0); // lpParam
if (hwnd != NULL)
{
ShowWindow(hwnd,SW_SHOW);
SetFocus(hwnd);
}
}
/*
* Initialize ui
*/
int main(int argc,char* argv[])
{
QGuiApplication app(argc,argv);
QQmlApplicationEngine* engine = new QQmlApplicationEngine;
engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject* qmlRoot = engine->rootObjects().first();
QWindow* mainWindow = qobject_cast<QWindow*>(qmlRoot);
int fbWidth = 1920,fbHeight = 1080;
uiCreateInputWindow((HWND)mainWindow->winId(),70,fbWidth,fbHeight);
app.exec();
}
main.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Window 2.12
ApplicationWindow {
id: root
x: 10
y: 10
width: 1920
height: 1150
visible: true
flags: Qt.Window | Qt.FramelessWindowHint
RowLayout {
anchors.fill: parent
spacing: 0
ColumnLayout {
spacing: 0
Rectangle {
id: topbar
color: "#232642"
Layout.fillWidth: true
Layout.preferredHeight: 70
MouseArea {
anchors.fill: parent
property point lastMouse
onPressed: {
lastMouse = mapToGlobal(mouseX,mouseY)
}
onPositionChanged: {
var newMouse = mapToGlobal(mouseX,mouseY)
root.x += newMouse.x - lastMouse.x
root.y += newMouse.y - lastMouse.y
lastMouse = newMouse
}
onDoubleClicked: {
root.visibility == ApplicationWindow.Windowed ?
root.showMaximized() :
root.showNormal()
}
}
RowLayout {
anchors.fill: parent
spacing: 0
Text {
text: "Test Window"
color: "#F8F8EE"
font.family: "Segoe UI"
font.pointSize: 11
font.weight: Font.DemiBold
Layout.fillHeight: true
Layout.topMargin: 10
Layout.leftMargin: 10
}
Item {
Layout.fillWidth: true
}
/*
Show Popup on click of this image
*/
Image {
id: cfgBtn
source: "Assets/cfgmenu.png"
Layout.fillHeight: true
Layout.preferredWidth: height
MouseArea {
anchors.fill: parent
onClicked: optionsPopup.open()
}
}
Image {
source: "Assets/closewindow.png"
Layout.fillHeight: true
Layout.preferredWidth: height
MouseArea {
anchors.fill: parent
onClicked: root.close()
}
}
}
}
Rectangle {
id: containerLv1
Layout.fillWidth: true
Layout.fillHeight: true
color: "black"
Rectangle {
id: containerLv2
width: Math.round(Math.min(containerLv1.width,containerLv1.height * 16 / 9))
height: Math.round(Math.min(containerLv1.height,containerLv1.width * 9 / 16))
anchors.centerIn: parent
visible: true
color: "grey"
}
}
}
}
/*
Desired popup to show
*/
Popup {
id: optionsPopup
x: cfgBtn.x - 160
y: topbar.y + topbar.height + 5
width: 200
height: 120
focus: true
dim: false
modal: true
padding: 0
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
contentItem: Rectangle {
id: rect
anchors.centerIn: parent
color: "#FF232642"
ColumnLayout {
spacing: 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Rectangle {
Layout.preferredWidth: 200
Layout.preferredHeight: 40
color: "transparent"
Text {
anchors.fill: parent
text: "Option1"
color: "white"
font.pointSize: 14
}
}
Rectangle {
Layout.preferredWidth: 200
Layout.preferredHeight: 40
color: "transparent"
Text {
anchors.fill: parent
text: "Option2"
color: "white"
font.pointSize: 14
}
}
Rectangle {
Layout.preferredWidth: 200
Layout.preferredHeight: 40
color: "transparent"
Text {
anchors.fill: parent
text: "Option3"
color: "white"
font.pointSize: 14
}
}
}
}
}
}
本机窗口是我们应用程序的一部分,用于接收鼠标和键盘输入。任何建议都值得欢迎。
解决方法
我做了一个破解来解决这个问题。基本上,问题在于,作为Qml窗口的一部分绘制的所有内容都隐藏在本机窗口的下面,没有办法(我可以在网上找到)做到这一点,除非添加另一层模式窗口。
因此,在打开弹出窗口之前,只需创建一个透明的模式窗口即可显示您的弹出窗口,并在弹出窗口关闭时关闭该窗口。
我仍在寻找一种更好的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。