如果 Layout 连接到父级,为啥动态调整大小不起作用?

Posted

技术标签:

【中文标题】如果 Layout 连接到父级,为啥动态调整大小不起作用?【英文标题】:Why does dynamic resizing not work if Layout is connected to the parent?如果 Layout 连接到父级,为什么动态调整大小不起作用? 【发布时间】:2020-04-11 16:42:45 【问题描述】:

我的代码

import sys
from PyQt5.QtWidgets import *

class Test(QWidget):
    def __init__(self):
        super().__init__()

        lay = QVBoxLayout(self)
        lay.setContentsMargins(0, 0, 0, 0)

        widget_1 = QWidget()
        lay.addWidget(widget_1)

        lay_2 = QVBoxLayout(widget_1)
        label_1 = QLabel(widget_1)
        label_1.setText("Test - 1")
        label_1.setStyleSheet('background:;margin:100'.format('yellow'))
        lay_2.addWidget(label_1)

        self.radio = QRadioButton()
        self.radio.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.radio.setStyleSheet('background:;margin:100'.format('black'))
        lay_2.addWidget(self.radio)

        #face_widget = QWidget(self)
        #face_widget.resize(widget_1.sizeHint().width(), widget_1.sizeHint().height())
        #widget_2 = QWidget(face_widget)

        widget_2 = QWidget(self)
        widget_2.setStyleSheet('background:'.format('brown'))
        widget_2.move(10,10)
        #widget_2.resize(65, 55)

        widget_2.raise_()

        lay_3 = QVBoxLayout(widget_2)

        lay_3.setSpacing(0)
        lay_3.setContentsMargins(0, 0, 0, 0)
        label_2 = QLabel(widget_2)
        label_2.setText("Test - 2")
        label_2.setStyleSheet('background:'.format('blue'))
        lay_3.addWidget(label_2)

        label_3 = QLabel(widget_2)
        label_3.setText("Test - 3")
        label_3.setStyleSheet('background:; padding:10'.format('red'))
        lay_3.addWidget(label_3)






if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Test()
    w.show()
    sys.exit(app.exec_())

我的问题是,当 Layout 连接到父级时,widget_2 不想动态更改其大小。

我不知道这与什么有关。而且我不知道如何解决它

我明白了

我需要

我需要lay,因为它定义了widget_2的起点

我需要laywidget_2 可以根据内容动态改变其大小的东西

而且我需要能够在不跟踪他在太空中的位置的情况下点击radio。因为如果会有很多按钮,那么每个都写

        self.x1r1, self.x2r1, self.y1r1, self.y2r1 = ..., ..., ..., ...     
        self.x1r2, self.x2r2, self.y1r2, self.y2r2 = ..., ..., ..., ...
        self.x1r3, self.x2r3, self.y1r3, self.y2r3 = ..., ..., ..., ...
    def onButtonClicked(self, id):
        print(id)

    def resizeEvent(self, event):                                       
        g1 = self.radio.geometry()
        self.x1r1 = g1.x() 
        self.y1r1 = g1.y()
        self.x2r1 = g1.x() + g1.width()
        self.y2r1 = g1.y() + g1.height()


        super().resizeEvent(event)  

    def mousePressEvent(self, event):     
        x = event.pos().x()
        y = event.pos().y()
        if (self.x1r1 < x < self.x2r1) and (self.y1r1 < y < self.y2r1):
            self.radio.click()

太耗电了。

【问题讨论】:

好吧,您根本没有将widget_2 添加到任何布局中,因此它无法知道父级何时更改其大小。使用lay.addWidget(widget_2) widget_2 应该与lay 平行并且处于空闲位置。我想使用widget_2.move() 您可以将小部件添加到布局并让该布局管理小部件的大小和位置,或者手动设置其geometry。您不能以透明/自动的方式同时使用它们。 @musicamante 但我使用两个不同的小部件和一个父级。为什么我不能应用一对一,第二个应用到第二个 您正在设置布局管理器ON widget_2,但您没有添加该小部件TO布局管理器。这意味着该小部件(及其所有内容)完全不知道其父级上的任何几何更改,因此您必须自己设置widget_2 几何。 没有其他解决方案。另一方面,这没有多大意义:“我需要能够在不跟踪他在太空中的位置的情况下点击收音机”。考虑到您以前的问题,恐怕您正试图为一个不同且不相关的问题(又名另一个 XY 问题)找到一个困难的解决方案。 【参考方案1】:

我找到了答案。但这是一种解决方法

import sys
from PyQt5.QtWidgets import *

class Test(QWidget):
    def __init__(self):
        super().__init__()

        widget_block = QWidget(self)

        widget_block.setStyleSheet('background:;'.format('yellow'))

        lay_2 = QVBoxLayout(widget_block)

        lay_2.setSpacing(0)
        lay_2.setContentsMargins(0, 0, 0, 0)


        label_1 = QLabel(widget_block)
        label_1.setText("Test - 1")
        label_1.setStyleSheet('background:;margin:100'.format('red'))
        lay_2.addWidget(label_1)

        self.radio = QRadioButton(widget_block)
        self.radio.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.radio.setStyleSheet('background:;margin:100'.format('black'))
        lay_2.addWidget(self.radio)



        self.resize(widget_block.sizeHint().width(), widget_block.sizeHint().height())
        widget_2 = QWidget(self)


        widget_2.setStyleSheet('background:'.format('brown'))
        widget_2.move(10,10)

        widget_2.raise_()

        lay_3 = QVBoxLayout(widget_2)

        lay_3.setSpacing(0)
        lay_3.setContentsMargins(0, 0, 0, 0)
        label_2 = QLabel(widget_2)
        label_2.setText("Test - 2")
        label_2.setStyleSheet('background:'.format('blue'))
        lay_3.addWidget(label_2)

        label_3 = QLabel(widget_2)
        label_3.setText("Test - 3")
        label_3.setStyleSheet('background:; padding:10'.format('red'))
        lay_3.addWidget(label_3)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Test()
    w.show()
    sys.exit(app.exec_())

【讨论】:

以上是关于如果 Layout 连接到父级,为啥动态调整大小不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的动态数组可以在不调整大小的情况下工作? [复制]

为啥 Scrolltrigger 在调整窗口大小时不更新我的动态 x 值?

连接到实现信号:奇怪的窗口大小调整行为

为啥我的列表框没有调整大小? (动态调整对话框组件的大小)

在 ConstraintLayout 中自动调整多行文本视图的大小

JavaFX TabPane 和调整父级的大小