2016-11-04 36 views
1

这里是我的测试代码:如何在强制固定宽高比时停止窗口大小跳动?

import QtQuick 2.4 
import QtQuick.Window 2.2 

Window { 
    visible: true 
    readonly property int defaultWidth: 700 
    readonly property int defaultHeight: 500 
    width: defaultWidth 
    height: defaultHeight 

    readonly property real aspectRatio: defaultWidth/defaultHeight 
    readonly property real scaleFactor: width/defaultWidth 

    onWidthChanged: { 
     var properHeight = Math.round(width/aspectRatio); 
     if (height !== properHeight) { 
      height = properHeight 
     } 
    } 
    onHeightChanged: { 
     var properWidth = Math.round(height * aspectRatio); 
     if (width !== properWidth) { 
      width = properWidth 
     } 
    } 

    TextEdit { 
     id: textEdit 
     text: "Lorem ipsum" 
     font.pixelSize: 40 * scaleFactor 
     anchors.fill: parent 
    } 
} 

它实现固定纵横比,但它并不能很好地工作:有几分固定纵横比的大小和鼠标器之间闪烁(窗口大小的跳跃调整后的大小),并且可以根据宽度和高度变化事件的顺序来调整错误的尺寸。实际上,当以编程方式调整大小时,窗口边缘可能会在鼠标光标位置和编程设置的不同位置之间开始跳转。

什么应该发生时,它被拖动应遵循的鼠标光标(如在任何大小调整)的窗口边缘,而另一个边缘应改变,以保持高宽比:

  • 如果用户拖动左/右边缘,底部边缘应移动以保持宽高比。
  • 如果用户拖动上/下边缘,则右边缘也应移动以保持宽高比。
  • 当用户拖动一个角落里,有两种可能的大小取,以保持高宽比,如高度或宽度可以被编程改变。如何确定这一点并不重要,只要它是一致的即可。
  • 没问题,如果宽高比只有在调整大小停止后才固定,但实时会更好。但如何可靠地检测调整大小实际上停止?
  • 如果不能使用Qt独自完成,我感兴趣的是Windows和X11/Linux的具体解决方案。

如何实现调整大小,同时保留长宽比,使用本机窗口调整控件(正常窗口边框或任何平台使用),这样它的行为逻辑和看起来不错


编辑,“提示”:我有时间做一些研究,覆盖QQuickView::resizeEvent并呼吁resize从那里似乎是能够做的伎俩,但我没有时间去得到它的工作非常正确。

回答

3

我有这样一个问题,有一次,我结束了一个“先有鸡还是先有蛋”的悖论,所以我完全禁用窗口装饰和制作自定义缩放条。这从成立处理一个适当的值流向方面,没有它的流量是尺寸大小,如果让任何意义......

如果卸下窗框是不是你的问题,你可以走那条路,对我来说这不是因为我一直在寻找一个自定义的平台独立的样子,所以窗框实际上是应用程序的一部分:

Window { 
    id: main 
    visible: true 
    width: 500 
    height: 250 
    flags: Qt.FramelessWindowHint | Qt.Window 

    MouseArea { 
     width: 20 
     height: 20 
     anchors.bottom: parent.bottom 
     anchors.right: parent.right 
     onPositionChanged: { 
     var w = mouseX + x, h = mouseY + y 
     if (w > (h * 2)) { 
      main.width = w 
      main.height = w * .5 
     } else { 
      main.height = h 
      main.width = h * 2 
     } 
     } 
     Rectangle { 
     anchors.fill: parent 
     color: "red" 
     } 
    } 
} 

这只是一个简单的例子,很明显你应该做一个完整的解决方案各方面和角落。长宽比固定为2/1。

在我的系统仍然有一些闪烁整个窗口,但我认为这仅仅是场景图,但“尺寸跳来跳去”问题有效解决。

编辑:

为了澄清,我的意思的“流量为维度尺寸”的是,操纵手柄的尺寸,和你钩到changed处理程序......做出改变。我怀疑这就是为什么它如此片面。如果是这样,为了使用窗框进行尺寸调整,必须切断手柄和窗口尺寸之间的连接以插入纵横比代码。不幸的是,在QGuiApplication级别过滤掉resize事件并不妨碍调整大小,但也许有另一种方式来做到这一点,例如覆盖类。

+0

感谢您的想法。我想我会保持框架,但我可能会做类似于你的事情:不允许正常调整大小,并且只是具有可切换的“正常大小”和“最大化大小”,​​而不是我自己调整大小的句柄。不过,我希望有人用完整的解决方案来回答。 – hyde

+0

唉,过滤掉resize事件不会阻止窗口调整大小,因为我认为它会。 – dtech

+0

看起来您可以通过设置最大和最小高度和宽度来停止调整大小,以仅允许一个大小。 – hyde

1

好的,这里有一个可能的解决方法。它不会尝试控制窗口大小,而是在窗口内添加额外的项目,然后包含UI的其余部分,并保持所需的宽高比:如果窗口宽高比不同,则上面有空白区域和用窗口颜色(此处为“灰色”)绘制的内容区域的下方或左侧和右侧。内容区域填充“黄色”以显示区别。

import QtQuick 2.4 
import QtQuick.Window 2.2 

Window { 

    readonly property int defaultWidth: 700 
    readonly property int defaultHeight: 500 
    readonly property real defaultAspectRatio: defaultWidth/defaultHeight 

    readonly property real aspectRatio: width/height 
    readonly property real scaleFactor: content.width/defaultWidth 

    visible: true 
    width: defaultWidth 
    height: defaultHeight 
    color: "gray" 

    Item { 
     id: content 
     anchors.centerIn: parent 
     width: (aspectRatio > defaultAspectRatio) 
       ? parent.height * defaultAspectRatio 
       : parent.width 
     height: (aspectRatio < defaultAspectRatio) 
       ? parent.width/defaultAspectRatio 
       : parent.height 

     Rectangle { color: "yellow"; anchors.fill: parent } // just to show the effect 

     TextEdit { 
      clip: true // text drawing needs to be clipped explicitly 
      id: textEdit 
      text: "Lorem ipsum" 
      font.pixelSize: 40 * scaleFactor 
      anchors.fill: parent 
     } 
    } 
} 

但这只是一个解决方法,而不是问题中要求的完整解决方案,因此问题仍然存在。

相关问题