pandas使用QGraphicsView自动排列项目的实现

作者:

文章目录
  • 目录
    • 解决方案
      • 方法一:使用 QGraphicsFlowLayout
      • 方法二:使用 QListWidget

    我想使用 QGraphicsView 来编写一个资源浏览器。它与使用 QGraphicsView 和 QGraphicsItems 的例子略有不同,因为我只希望有一个滚动条,并且我希望项目在视区大小更改时能够自动移动。例如,当视区宽度足够大以显示 4 个资产时,它们应该像这样显示:

    aaaa
    aaaa
    aa

    但是当视区缩小并且只能在一行中容纳 3 个时,它应该像这样显示:

    aaa
    aaa
    aaa
    a

    我不想自己移动这些资产,而是让图形视图管理它们。这可能吗?

    我曾经写过这样一件事,但使用 QWidget 和 paintEvent,自己绘制所有资产并跟踪一行中可以显示多少资产。可以用 QGraphicsView 更简单地完成吗?

    QGraphicsView 支持布局。您需要做的是实现您自己的布局管理器,继承自 QGraphicsLayout。

    对于您需要的布局,请查看 Qt 的流布局示例。转换该示例将为您提供一个 QGraphicsFlowLayout。将您的 QGraphicsItems 添加到此布局并将您的 QGraphicsView 的布局设置为该布局,这将完成这项工作。

    听起来您想要一个列表,而不是一个图形视图。可以将列表设置为显示像您希望的那样换行的内容。请参阅拼图示例,注意左侧的拼图块列表。对于所提出的情况,设置起来非常简单。

    当然,如果您真的想在图形视图中实现它,我想您可以将一个列表添加到视图中并在那里使用它。

    代码示例

    from PyQt5.QtCore import QRectF
    from PyQt5.QtGui import QBrush, QColor, QPen
    from PyQt5.QtWidgets import QApplication, QGraphicsItem, QGraphicsRectItem, QGraphicsScene, QGraphicsView, QVBoxLayout, QWidget
    
    
    class QGraphicsFlowLayout(QGraphicsLayout):
        def __init__(self):
            super().__init__()
    
            self.item_list = []
    
        def addItem(self, item):
            self.item_list.append(item)
    
        def count(self):
            return len(self.item_list)
    
        def itemAt(self, index):
            return self.item_list[index]
    
        def takeAt(self, index):
            item = self.item_list.pop(index)
            return item
    
        def boundingRect(self):
            rect = QRectF()
            for item in self.item_list:
                rect |= item.rect()
            return rect
    
        def sizeHint(self, which, constraint):
            return self.boundingRect().size()
    
        def minimumSize(self):
            return self.sizeHint(QGraphicsLayout.MinimumSize, QSizeF())
    
        def preferredSize(self):
            return self.sizeHint(QGraphicsLayout.PreferredSize, QSizeF())
    
        def get_row_width(self):
            row_width = 0
            for item in self.item_list:
                row_width += item.rect().width()
            return row_width
    
        def get_row_height(self):
            row_height = 0
            for item in self.item_list:
                row_height = max(row_height, item.rect().height())
            return row_height
    
        def get_num_rows(self, view_width):
            row_width = self.get_row_width()
            num_rows = 1
            if row_width > view_width:
                num_rows = row_width // view_width + 1
            return num_rows
    
        def get_row_spacing(self):
            return 10
    
        def get_column_spacing(self):
            return 10
    
        def get_item_position(self, item, row, column):
            x = column * (item.rect().width() + self.get_column_spacing())
            y = row * (item.rect().height() + self.get_row_spacing())
            return QPointF(x, y)
    
        def setGeometry(self, rect):
            view_width = rect.width()
            num_rows = self.get_num_rows(view_width)
            row_height = self.get_row_height()
    
            for i, item in enumerate(self.item_list):
                row = i // num_rows
                column = i % num_rows
                pos = self.get_item_position(item, row, column)
                item.setPos(pos)
    
    
    class QGraphicsFlowView(QGraphicsView):
        def __init__(self):
            super().__init__()
    
            self.scene = QGraphicsScene(self)
            self.layout = QGraphicsFlowLayout()
            self.scene.setLayout(self.layout)
    
            self.setRenderHints(QGraphicsView.Antialiasing | QGraphicsView.SmoothPixmapTransform)
            self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
    
        def add_item(self, item):
            self.layout.addItem(item)
    
        def resizeEvent(self, event):
            super().resizeEvent(event)
            self.layout.setGeometry(self.rect())
    
    
    class QGraphicsFlowItem(QGraphicsRectItem):
        def __init__(self, color):
            super().__init__()
    
            self.setRect(0, 0, 100, 100)
            self.setBrush(QBrush(color))
            self.setPen(QPen(QColor(0, 0, 0), 1))
    
    
    if __name__ == "__main__":
        app = QApplication([])
    
        view = QGraphicsFlowView()
        view.add_item(QGraphicsFlowItem(QColor(255, 0, 0)))
        view.add_item(QGraphicsFlowItem(QColor(0, 255, 0)))
        view.add_item(QGraphicsFlowItem(QColor(0, 0, 255)))
        view.add_item(QGraphicsFlowItem(QColor(255, 255, 0)))
        view.add_item(QGraphicsFlowItem(QColor(255, 0, 255)))
        view.add_item(QGraphicsFlowItem(QColor(0, 255, 255)))
        view.show()
    
        app.exec_()

    到此这篇关于pandas使用QGraphicsView自动排列项目的实现的文章就介绍到这了,更多相关pandas QGraphicsView自动排列内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 

    您可能感兴趣的文章:

    • 浅析pandas随机排列与随机抽样

    站内搜索