我想使用 qgraphicsview 来编写一个资源浏览器。它与使用 qgraphicsview 和 qgraphicsitems 的例子略有不同,因为我只希望有一个滚动条,并且我希望项目在视区大小更改时能够自动移动。例如,当视区宽度足够大以显示 4 个资产时,它们应该像这样显示:
aaaa
aaaa
aa
但是当视区缩小并且只能在一行中容纳 3 个时,它应该像这样显示:
aaa
aaa
aaa
a
我不想自己移动这些资产,而是让图形视图管理它们。这可能吗?
我曾经写过这样一件事,但使用 qwidget 和 paintevent,自己绘制所有资产并跟踪一行中可以显示多少资产。可以用 qgraphicsview 更简单地完成吗?
解决方案
方法一:使用 qgraphicsflowlayout
qgraphicsview 支持布局。您需要做的是实现您自己的布局管理器,继承自 qgraphicslayout。
对于您需要的布局,请查看 qt 的流布局示例。转换该示例将为您提供一个 qgraphicsflowlayout。将您的 qgraphicsitems 添加到此布局并将您的 qgraphicsview 的布局设置为该布局,这将完成这项工作。
方法二:使用 qlistwidget
听起来您想要一个列表,而不是一个图形视图。可以将列表设置为显示像您希望的那样换行的内容。请参阅拼图示例,注意左侧的拼图块列表。对于所提出的情况,设置起来非常简单。
当然,如果您真的想在图形视图中实现它,我想您可以将一个列表添加到视图中并在那里使用它。
代码示例
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自动排列内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论