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

2024-04-25 19:18:47 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我能想到的最好的解决方案是在resize时手动设置高度,但是在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?你知道吗


Tags: importselfchildnewmovedefrandom布局
1条回答
网友
1楼 · 发布于 2024-04-25 19:18:47

试试看:

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

相关问题 更多 >