我的应用程序具有创建并打开一个QML的子类的实例的主窗口Window {}使用createObject().这个窗口flags:设置为无边框窗口(我添加了代码,以便可以抓取并拖动它).
当我将显示器连接到笔记本电脑并将其字体比例因子设置为125%(或150%)时,当我将主窗口拖到第二个显示器时,您可以看到它突然"突然"到更大的尺寸中途点.同样地,当我将它拖回到我的笔记本电脑屏幕时,当我半途而废时,它再次"捕捉"到较小的尺寸(这种行为是我想要的,所以这里没有问题).
我的问题是,当我将创建的无边框窗口拖到显示器中时,它保持原始的100%比例因子,并且不会"捕捉"到更大的尺寸.如果我将主窗口拖到显示器上,它会变大,但无边框窗口保持较小的比例; 只有当我抓住无边框窗口并稍微移动它才会突然"捕捉"到更大的比例尺寸.相反的情况反过来 - 如果我然后将无边框窗口拖回到笔记本电脑上,它将保持较大的尺寸,直到我将主窗口向后拖动然后稍微移动无边框窗口(此时它突然"捕捉"到较小的尺寸).
所以看来这个创建Window使用了屏幕的比例因子父窗口 创建它的窗口当前处于,即使它本身位于不同的屏幕中.
这是否因为Window无边界而发生?(我即将测试这个,但我的构建过程非常慢)或者有没有办法设置这个无边框Window,以便它检测到它正在进入一个新的屏幕并重新缩放自己(就像我的方式一样)主窗口呢)?
更新:我刚刚运行了一个测试,给出了我Window的原生标题栏,并且使用标题栏,窗口立即采用("快照")任何一个屏幕的比例因子,就像我的主窗口一样(并且独立于主窗口)窗口的比例因子).
那么有没有办法用无边框窗口复制这种自动缩放窗口行为?我需要调用一些标志,或者我需要调用一些方法来让操作系统重新调整窗口大小?
更新2:我尝试了Felix的SetWindowPos解决方案.它确实会移动窗口,但这并不能解决缩放问题 - 无框窗口的行为是相同的,它仍然无法正确地获取它所在屏幕的缩放因子.
我正在运行测试,MoveWindow而不是SetWindowPos看看是否会影响任何事情[ 编辑: MoveWindow不起作用,或者 - 同样的问题].然后我将尝试SendMessage或PostMessage与NoBugz一起提出WM_DPICHANGED消息的建议.
欢迎任何其他建议.
更新3:我刚刚创建了一个快速的C#应用程序(winforms)来查看是否出现了同样的问题,而且它没有 - 当C#应用程序中的无边框表单被拖到另一个监视器中时,它会立即获取比例因子变化.所以看来这是一个Qt问题.
更新4:请参阅下面的答案,找出解决此问题的方法(如果有点破解).
据我了解,您目前的目标是通过WIN-API移动窗口.你必须通过C++这样做.方法是:
QQuickWindow(QML窗口实例化该类型,如文档中所示)QWindow::winId来获取本地HWNDSetWindowPosWIN-API方法来移动它代码示例(C++ - 部分):
// the method
void moveWindow(QQuickWindow *window, int x, int y) {
HWND handle = (HWND)window->winId();
Q_ASSERT(handle);
::SetWindowPos(handle, HWND_TOP,
x, y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER);
}
// assuming "moveWindow" is a member of "MyClass"
qmlEngine->rootContext()->setContextProperty("mover", new MyClass(qmlEngine));
Run Code Online (Sandbox Code Playgroud)
代码示例(QML部分):
// call this method as soon as the drag has finished, with the new positions
mover.moveWindow(idOfWindow, xPos, yPos);
Run Code Online (Sandbox Code Playgroud)
注意:我建议您在拖动完成后尝试调用此方法(并在此之前移动窗口,直到此时为止).如果可行,您可以尝试在拖动过程中调用此操作而不是更改窗口的x/y时会发生什么.
我想出了一个相对简单的方法来解决这个问题。由于 Qt 中的无框架窗口从创建它的窗口获取其缩放因子,因此技巧是创建另一个窗口(具有标题栏但对用户不可见)并在那里创建无框架窗口,然后将代码添加到无框窗口,以在用户拖动窗口时将隐藏窗口保持在其下方。当无框窗口被拖到另一个屏幕中时,隐藏的窗口也会随之移动,获取新的比例因子(因为它有标题栏),然后无框窗口也立即获取新屏幕的比例因子。
这是示例解决方案代码:
// HiddenWindow.qml
Window {
id: hiddenWindow
// note: just making window visible: false does not work.
opacity: 0
visible: true
flags: Qt.Tool | Qt.WindowTitleHint | Qt.WindowTransparentForInput |
Qt.WindowStaysOnTopHint // Qt.Tool keeps this window out of the
// taskbar
function createVisibleWindow() {
var component = Qt.createComponent("VisibleWindow.qml")
if (component.status === Component.Ready) {
var win = component.createObject(hiddenWindow)
return win
}
}
}
// VisibleWindow.qml
Window {
id: visibleWindow
property var creatorWindow: undefined
flags: Qt.FramelessWindowHint
onXChanged: {
creatorWindow.x = x
}
onYChanged: {
creatorWindow.y = y
}
onWidthChanged: {
creatorWindow.width = width
}
onHeightChanged: {
creatorWindow.height = height
}
}
Run Code Online (Sandbox Code Playgroud)
然后从主窗口 QML 使用这些类:
property var hiddenWindow: undefined
property var visibleWindow: undefined
Component.onCompleted: {
var component = Qt.createComponent("HiddenWindow.qml")
if (component.status === Component.Ready) {
hiddenWindow = component.createObject(null)
}
visibleWindow = hiddenWindow.createVisibleWindow()
visibleWindow.creatorWindow = hiddenWindow
visibleWindow.show()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |