如何在Qt中维护小部件的宽高比?

Ble*_*dof 32 user-interface qt widget aspect-ratio

如何在Qt中维护窗口小部件的宽高比以及如何使窗口小部件居中呢?

Mar*_*utz 17

您不必实现自己的布局管理器.你可以做继承QWidget和重新实现

int QWidget::heightForWidth( int w ) { return w; }
Run Code Online (Sandbox Code Playgroud)

保持广场 但是,heightForWidth()对于X11上的顶级窗口不起作用,因为显然X11协议不支持它.至于居中,你可以传递Qt::AlignCenter第三个参数QBoxLayout::addWidget()或第五个参数QGridLayout::addWidget().

注意:至少在Qt的较新版本中,QWidget不具有heightForWidthwidthForHeight不再(因此它们不能被覆盖),因此setWidthForHeight(true)setHeightForWidth(true) 仅对QGraphicsLayout的后代有效.

  • 如果我想设置widthForHeight怎么办?QWidget没有`widthForHeight`方法. (5认同)
  • 那么如何在新的Qt版本中做到这一点? (3认同)

Ble*_*dof 8

正确的答案是创建自定义布局管理器.这可以通过继承QLayout来实现.

子类化QLayout时实现的方法

void addItem(QLayoutItem*item);
将项添加到布局.
int count()const;
返回项目计数.
QLayoutItem*itemAt(int index)const;
返回索引处的项引用,如果没有则返回0.
QLayoutItem*takeAt(int index);
从索引中获取并返回布局中的项目,如果没有则返回0.
Qt :: Orientations expandingDirections()const;
返回展开方向的布局.
bool hasHeightForWidth()const;
判断布局是否处理宽度计算的高度.
QSize minimumSize()const;
返回布局的最小大小.
void setGeometry(const QRect&rect);
设置布局的几何形状及其中的项目.在这里,您必须保持纵横比并进行居中.
QSize sizeHint()const;
返回布局的首选大小.

进一步阅读

  • 所有链接都已死亡. (2认同)

dF.*_*dF. 5

resize()从内部调用resizeEvent()从来没有对我有用 - 最好它会导致闪烁,因为窗口调整大小两次(就像你有),最坏的情况是无限循环.

我认为维持固定宽高比的"正确"方法是创建自定义布局.你必须只重写两个方法,QLayoutItem::hasHeightForWidth()并且QLayoutItem::heightForWidth().


tal*_*osh 5

我也试图实现所要求的效果:一个保持固定纵横比同时保持在其分配空间中心的小部件。起初我尝试了这个问题的其他答案:

\n\n
    \n
  • 实施heightForWidthhasHeightForWidth按照 marc-mutz-mmutz 的建议对我来说根本不起作用。
  • \n
  • 我简单地考虑过实现一个自定义布局管理器,但所有 Bleadof 的链接都已失效,当我找到文档并通读它时,它看起来对于我想要实现的目标来说太复杂了。
  • \n
\n\n

我最终创建了一个自定义小部件,它响应resizeEvent并用于setContentsMargin设置边距,以便剩余内容区域保持所需的比例。

\n\n

我发现我还必须将小部件的大小策略设置为QSizePolicy::Ignored双向,以避免因子小部件\xe2\x80\x94的大小请求而导致的奇怪的调整大小问题最终结果是我的小部件接受其父级分配给的任何大小(然后如上所述设置其边距,以在其内容区域中保持所需的宽高比)。

\n\n

我的代码如下所示:

\n\n
from PySide2.QtWidgets import QWidget, QSizePolicy\n\n\nclass AspectWidget(QWidget):\n    \'\'\'\n    A widget that maintains its aspect ratio.\n    \'\'\'\n    def __init__(self, *args, ratio=4/3, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.ratio = ratio\n        self.adjusted_to_size = (-1, -1)\n        self.setSizePolicy(QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored))\n\n    def resizeEvent(self, event):\n        size = event.size()\n        if size == self.adjusted_to_size:\n            # Avoid infinite recursion. I suspect Qt does this for you,\n            # but it\'s best to be safe.\n            return\n        self.adjusted_to_size = size\n\n        full_width = size.width()\n        full_height = size.height()\n        width = min(full_width, full_height * self.ratio)\n        height = min(full_height, full_width / self.ratio)\n\n        h_margin = round((full_width - width) / 2)\n        v_margin = round((full_height - height) / 2)\n\n        self.setContentsMargins(h_margin, v_margin, h_margin, v_margin)\n
Run Code Online (Sandbox Code Playgroud)\n\n

(显然,此代码是用 Python 编写的,但用 C++ 或您选择的语言表达应该很简单。)

\n