PyQt5:创建强制固定高度的流布局

时间:2018-11-06 13:46:08

标签: python pyqt pyqt5

我正在尝试制作流布局效果,用户可以修改小部件的宽度,并调整大小以进行补偿。我已经研究过创建自定义布局,但是该布局从不增加高度来补偿宽度的缩小。

我能想到的最好的解决方案是在调整大小时手动设置高度,但是在PyQt5中,这似乎(如果您迅速尝试调整窗口的大小)锁定了整个窗口,因此您无法调整其大小或移动它了。可以通过编程方式调整它的大小或移动它,但是窗口不再响应用户调整大小/移动请求。

似乎类似于递归错误,但我找不到触发的任何递归事件,并且UI的其余部分没有挂起,只是调整大小。

这是我的用例:

import random
import sys
import math

from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtWidgets import QWidget, QApplication


class ChangingHeightWidget(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._allow_height_change = False
        self._child_widgets = []
        self._create_children(8)


    def _create_children(self, count: int):
        for i in range(count):
            # Create a panel
            new_child = QWidget()
            new_child.setFixedSize(64, 64)
            new_child.setParent(self)
            new_child.show()

            # Set the color
            pal = QPalette()
            pal.setColor(QPalette.Background, QColor(random.randint(100, 255), random.randint(100, 255), random.randint(100, 255)))
            new_child.setAutoFillBackground(True)
            new_child.setPalette(pal)

            self._child_widgets.append(new_child)

        self._move_panels()

    def _move_panels(self):
        num_per_row = max(int((self.width()) / 64), 1)

        for i in range(8):
            y = int(i / num_per_row)
            x = i % num_per_row
            self._child_widgets[i].move(x * 64, y * 64)

        num_rows = math.ceil(8 / float(num_per_row))
        min_height = num_rows * 64
        self.setFixedHeight(min_height)

    def resizeEvent(self, QResizeEvent):
        self._move_panels()


if __name__ == '__main__':
    import callback_fix
    app = QApplication(sys.argv)
    gui = ChangingHeightWidget()
    gui.show()
    app.exec_()

是否有办法阻止这种锁定的发生?另外,是否有一种方法可以实现此效果而无需在resizeEvent中调用setFixedHeight?

1 个答案:

答案 0 :(得分:0)

尝试一下:

import random
import sys
import math

from PyQt5.QtGui     import QPalette, QColor
from PyQt5.QtWidgets import QWidget, QApplication, QListWidget


class ChangingHeightWidget(QListWidget):           # - QWidget  
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setFrameShape(self.NoFrame)           # +++
        self.setFlow(self.LeftToRight)             # +++
        self.setWrapping(True)                     # +++
        self.setResizeMode(self.Adjust)            # +++


        self._allow_height_change = False
        self._child_widgets = []
        self._create_children(8)


    def _create_children(self, count: int):
        for i in range(count):
            # Create a panel
            new_child = QWidget()
            new_child.setFixedSize(64, 64)
            new_child.setParent(self)
            new_child.show()

            # Set the color
            pal = QPalette()
            pal.setColor(QPalette.Background, QColor(random.randint(100, 255), random.randint(100, 255), random.randint(100, 255)))
            new_child.setAutoFillBackground(True)
            new_child.setPalette(pal)

            self._child_widgets.append(new_child)

        self._move_panels()

    def _move_panels(self):
        num_per_row = max(int((self.width()) / 64), 1)

        for i in range(8):
            y = int(i / num_per_row)
            x = i % num_per_row
            self._child_widgets[i].move(x * 64, y * 64)

#        num_rows = math.ceil(8 / float(num_per_row))
#        min_height = num_rows * 64
#        self.setFixedHeight(min_height)

    def resizeEvent(self, QResizeEvent):
        self._move_panels()


if __name__ == '__main__':
#    import callback_fix
    app = QApplication(sys.argv)
    gui = ChangingHeightWidget()
    gui.show()
    app.exec_()

enter image description here

相关问题