QSplitter设置宽高比例的正确方法

问题

实际开发中,需要经常调整QSplitter中子窗口的宽度/高度比例。对水平QSplitter来说,是宽度比例;对垂直QSplitter来说,是高度比例。下面以水平QSplitter为例说明。

我们首先应该会想起看看QSplitter是不是有设置比例的函数。查找文档,发现有一个setStretchFactor函数。经过尝试以后,发现无论如何设置,都不能获得想要的效果。

没有想象的顺利,那么就需要仔细阅读官方文档。下面是官方文档对于此函数的描述:
请添加图片描述

翻译过来意思是:

此函数用于更新尺寸策略中,对应索引位置窗口的伸缩比例值。

参数stretch不是真正有效的伸缩比例;最终呈现的窗口大小是伸缩因子stretch乘上index对应的子窗口的初始宽度(以水平为例)。

可见,最终的子窗口的宽度或高度,并不是仅仅调用一次setStretchFactor就可以控制最终显示效果的。也就是说,最终显示结果是由stretch factor和子窗口初始宽度以乘积的方式共同决定的。

方案

点击QSplitter函数文档下方的链接的相关函数,可以发现setSizes函数是用来设置子窗口宽度值的。
请添加图片描述
于是使用以下代码设置并测试:

// 设置比例5:1
QList<int> sizes;

// 在保持比例的情况下,绝对值要尽量大
sizes << 50000 << 10000; 
ui->splitter->setSizes(sizes);

注意上面的代码,我们没有调用setStretchFactor,所以stretchFactor默认为1:1,所以最终比例由setSizes函数来决定。

提出一个小问题:为什么setSizes绝对值要尽量大?此处为答案1

总结

以后遇到QSplitter设置比例,直接使用setSizes,且在保持你想要设置的比例的前提下,尽量给setSizes设置比较大的参数。


  1. 小问题答案:如果给setSizes的参数很小,且如果小于QSplitter,QSplitter内的子窗口将被拉伸,想要保持你想要的比例根本不可能。所以,将setSizes参数设置为万级别大小,是一个比较好的选择。 ↩︎

### PySide6 中 QSplitter 的使用方法 #### 创建基本的 QSplitter 布局 为了创建一个简单的 `QSplitter`,可以先导入必要的模块并初始化应用程序实例: ```python from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QSplitter import sys app = QApplication(sys.argv) # 初始化窗口和布局管理器 window = QWidget() layout = QVBoxLayout(window) splitter = QSplitter() # 添加子部件到分割器中 label1 = QLabel("Panel 1") label2 = QLabel("Panel 2") splitter.addWidget(label1) splitter.addWidget(label2) layout.addWidget(splitter) window.setLayout(layout) window.show() sys.exit(app.exec()) ``` 上述代码展示了如何通过 `addWidget()` 方法向 `QSplitter` 中添加多个面板[^1]。 #### 设置方向 默认情况下,`QSplitter` 是水平排列的。如果希望垂直显示,则可以通过调用 `setOrientation(Qt.Vertical)` 来改变其方向: ```python from PySide6.QtCore import Qt splitter.setOrientation(Qt.Vertical) ``` 这使得两个标签将以上下方式堆叠而不是左右分布。 #### 调整大小策略 有时可能需要调整各个部分之间的初始比例关系。此时可以用 `setSizes([width1, width2])` 函数来指定各分隔区间的度或度(取决于当前的方向)。例如: ```python splitter.setSizes([200, 80]) ``` 此操作会将第一个区域设为较而第二个相对窄一些。 #### 处理事件与信号 当用户拖动分隔条时会产生一系列变化;为此提供了几个有用的信号用于监听这些动作的发生,比如 `splitterMoved(int pos, int index)` 可以用来跟踪具体位置的变化情况。下面是一个简单的例子说明怎样连接这个信号到槽函数上: ```python def on_splitter_moved(pos, idx): print(f"Position changed to {pos} at index {idx}") splitter.splitterMoved.connect(on_splitter_moved) ``` 每当有新的移动发生时就会触发打印语句执行。 #### 解决常见问题 对于某些特定场景下的异常状况处理,如遇到 “wglMakeCurrent failed in MakeCurrent after closed a window with two vtk widget.” 这样的错误提示,在关闭含有 VTK 小部件的应用程序之前应该确保释放所有资源以及正确清理 OpenGL 上下文环境[^4]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撬动未来的支点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值