拉伸因子在Qt中如何工作?

时间:2018-08-29 06:52:42

标签: python pyqt pyqt5 qlayout

我正在使用pyqt5开发GUI应用程序。在某个对话框中,我需要许多组件,作为QWebEngineView的组件之一,可以用作绘制数据的画布,即使创建对话框时图表尚未准备就绪,该组件也应占用大部分可用空间。

我希望它看起来像这样: enter image description here

我调查并发现了拉伸因子。我看到QSizePolicy仅直接适用于小部件,而不适用于布局as shown in this SO answer。但是后来我发现方法addWidget和addLayout允许我在QBoxLayout的方向上设置拉伸因子,这对于我的意图来说似乎是理想的。

所以我尝试了:

from PyQt5.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout
from strategy_table import StrategyTable

layout = QVBoxLayout()
layout.addWidget(QLabel("Strategy components"))

# Upper layout for a table. Using a 30% of vertical space
upper_layout = QHBoxLayout() # I'm using a HBox because I also want a small button at the right side of the table
self.table = StrategyTable(self) # Own class derived from QTableWidget
upper_layout.addWidget(self.table)

add_button = QPushButton('Add')
add_button.clicked.connect(self._show_add_dialog)
upper_layout.addWidget(add_button)
layout.addLayout(upper_layout, 3) # Setting 20% of size with the stretch factor

# Then the plot area, using 60% of vertical space
layout.addWidget(QLabel("Plot area"))
canvas = QWebEngineView()
layout.addWidget(self.canvas, 6)


# Finally, a small are of 10% of vertical size to show numerical results
layout.addWidget(QLabel("Results"))
params_layout = self._create_results_labels() # A column with several QLabel-QTextArea pairs, returned as a QHBoxLayout
layout.addLayout(params_layout, 1)

self.setLayout(layout)

但是看起来和以前完全一样: enter image description here

在底部添加结果Layout之前看起来还不错,我想是因为上面的表在开始时是空的,因此只占很小的空间,剩下的留给了画布。

无论如何,似乎拉伸因子被忽略了,所以我不知道我是否在这里缺少什么,或者我不完全了解拉伸因子。

顺便说一句,我知道我会使用QtEditor来设计GUI,但我更喜欢手动执行这些操作。

2 个答案:

答案 0 :(得分:4)

问题很简单,布局处理小部件的位置和大小,但是它有限制,其中包括小部件的最小大小,在您的情况下,最后一个元素的高度大于10%,因此物理上是不可能的。我们可以通过删除内容或使用QScrollArea来看到这一点:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets

class StrategyTable(QtWidgets.QTableWidget):
    pass

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)

        table = StrategyTable()
        button = QtWidgets.QPushButton("Add")
        hlay = QtWidgets.QHBoxLayout()
        hlay.addWidget(table)
        hlay.addWidget(button)

        canvas = QtWebEngineWidgets.QWebEngineView()
        canvas.setUrl(QtCore.QUrl("http://www.google.com/"))

        scroll = QtWidgets.QScrollArea()
        content_widget = QtWidgets.QWidget()
        scroll.setWidgetResizable(True)
        scroll.setWidget(content_widget)
        vlay = QtWidgets.QVBoxLayout()
        vlay.addWidget(QtWidgets.QLabel("Results:"))
        params_layout = self._create_results_labels()
        content_widget.setLayout(params_layout)
        vlay.addWidget(scroll)

        lay.addLayout(hlay, 3)
        lay.addWidget(canvas, 6)
        lay.addLayout(vlay, 1)


    def _create_results_labels(self):

        flay = QtWidgets.QFormLayout()
        for text in ("Delta", "Gamma", "Rho", "Theta", "Vega"):
            flay.addRow(text, QtWidgets.QTextEdit())
        return flay


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

enter image description here

答案 1 :(得分:1)

希望这对了解布局以及拉伸系数很有用

Sample Layout based on percentages (CPP)

QVBoxLayout *topMostVerticalLayout = new QVBoxLayout(this);
QHBoxLayout *upperHorznLayout = new QHBoxLayout();
QHBoxLayout *bottomHorznLayout = new QHBoxLayout();

 QVBoxLayout *InnerVerticalLayout1 = new QVBoxLayout(this);
 QVBoxLayout *InnerVerticalLayout2 = new QVBoxLayout(this);
 QVBoxLayout *InnerVerticalLayout3 = new QVBoxLayout(this);
 QVBoxLayout *InnerVerticalLayout4 = new QVBoxLayout(this);
 QVBoxLayout *InnerVerticalLayout5 = new QVBoxLayout(this);

bottomHorznLayout->addLayout(InnerVerticalLayout1,15); //(15% stretch)
bottomHorznLayout->addLayout(InnerVerticalLayout2,15); //(15% stretch)
bottomHorznLayout->addLayout(InnerVerticalLayout3,15); //(15% stretch)
bottomHorznLayout->addLayout(InnerVerticalLayout4,15); //(15% stretch)
bottomHorznLayout->addLayout(InnerVerticalLayout5,40); //(40% stretch)

topMostVerticalLayout->addLayout(upperHorznLayout,3); //(30% stretch)
topMostVerticalLayout->addLayout(bottomHorznLayout,7); //(70% stretch)

this->setLayout(topMostVerticalLayout);