PyQt5: создание макета потока с принудительной высотой - PullRequest
0 голосов
/ 06 ноября 2018

Я пытаюсь создать эффект макета потока, при котором пользователь может изменять ширину виджета, а размер корректируется для компенсации. Я рассмотрел создание собственного макета, но макет никогда не увеличивает высоту, чтобы компенсировать уменьшающуюся ширину.

Лучшее решение, которое я мог бы придумать, это установить высоту вручную при изменении размера, но в PyQt5 это, кажется, (если вы быстро пытаетесь изменить размер окна) блокирует все окно, поэтому вы не можете изменить его размер или переместить его больше , Он может быть изменен или перемещен программно, но окно больше не отвечает на запросы пользователя на изменение размера / перемещение.

Это кажется как ошибка рекурсии, но я не могу найти никаких инициируемых рекурсивных событий, а остальная часть пользовательского интерфейса не зависает, только изменение размера.

Вот мой пример использования:

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_()

Есть ли способ остановить это запирание? В качестве альтернативы, есть ли способ добиться этого эффекта без необходимости вызывать setFixedHeight внутри resizeEvent?

1 Ответ

0 голосов
/ 06 ноября 2018

Попробуйте:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...