在 QTreeWidget 中调整小部件的大小(使用 setItemWidget 设置)?
Resize widget inside QTreeWidget (set with setItemWidget)?
我在 QTreeWidget
中有一个 QListWidget
,我希望它在添加或删除行时自动调整高度。我让 QListWidget
自动调整工作正常,但当它在 QTreeWidget
内时它会中断,QListWidget
的大小增加但 QTreeWidget
没有正确调整它并且其他行得到覆盖。
from PyQt5 import QtCore, QtGui, QtWidgets, sip
from PyQt5.QtCore import Qt
class MyListWidget(QtWidgets.QListWidget):
def sizeHint(self):
width = super().sizeHint().width()
height = sum([self.sizeHintForRow(i) for i in range(self.count())]) + 5
return QtCore.QSize(width, height)
app = QtWidgets.QApplication([])
tree = QtWidgets.QTreeWidget()
item1 = QtWidgets.QTreeWidgetItem(tree, ['item1'])
item2 = QtWidgets.QTreeWidgetItem(tree, ['item2'])
item3 = QtWidgets.QTreeWidgetItem(tree, ['item3'])
list_widget = MyListWidget()
list_widget.addItems(list('abcd'))
tree.setItemWidget(item1, 0, list_widget)
button = QtWidgets.QPushButton("Add row")
button.clicked.connect(lambda: [list_widget.addItem("New row"),
list_widget.adjustSize(),
tree.adjustSize(),
tree.updateGeometry()
])
container = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
container.setLayout(layout)
layout.addWidget(tree)
layout.addWidget(button)
container.show()
list_widget.show()
app.exec_()
初始输出:
点击新增后的输出:
正如您在第二张图片中看到的,item2
现在被展开的列表小部件覆盖,所需的输出将是移动 item2
,这样在添加新项目后列表小部件未覆盖同一树小部件中其下方的项目。
您可以将树子类化并连接模型的 rowsInserted
和 rowsRemoved
信号,然后相应地更新几何图形,包括项目的几何图形:
class TreeWidget(QtWidgets.QTreeWidget):
def setItemWidget(self, item, column, widget):
super().setItemWidget(item, column, widget)
if isinstance(widget, MyListWidget):
widget.model().rowsInserted.connect(
lambda: self.updateItemWidget(item, column))
widget.model().rowsRemoved.connect(
lambda: self.updateItemWidget(item, column))
def updateItemWidget(self, item, column):
widget = self.itemWidget(item, column)
item.setSizeHint(column, widget.sizeHint())
self.updateGeometries()
我在 QTreeWidget
中有一个 QListWidget
,我希望它在添加或删除行时自动调整高度。我让 QListWidget
自动调整工作正常,但当它在 QTreeWidget
内时它会中断,QListWidget
的大小增加但 QTreeWidget
没有正确调整它并且其他行得到覆盖。
from PyQt5 import QtCore, QtGui, QtWidgets, sip
from PyQt5.QtCore import Qt
class MyListWidget(QtWidgets.QListWidget):
def sizeHint(self):
width = super().sizeHint().width()
height = sum([self.sizeHintForRow(i) for i in range(self.count())]) + 5
return QtCore.QSize(width, height)
app = QtWidgets.QApplication([])
tree = QtWidgets.QTreeWidget()
item1 = QtWidgets.QTreeWidgetItem(tree, ['item1'])
item2 = QtWidgets.QTreeWidgetItem(tree, ['item2'])
item3 = QtWidgets.QTreeWidgetItem(tree, ['item3'])
list_widget = MyListWidget()
list_widget.addItems(list('abcd'))
tree.setItemWidget(item1, 0, list_widget)
button = QtWidgets.QPushButton("Add row")
button.clicked.connect(lambda: [list_widget.addItem("New row"),
list_widget.adjustSize(),
tree.adjustSize(),
tree.updateGeometry()
])
container = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
container.setLayout(layout)
layout.addWidget(tree)
layout.addWidget(button)
container.show()
list_widget.show()
app.exec_()
初始输出:
点击新增后的输出:
正如您在第二张图片中看到的,item2
现在被展开的列表小部件覆盖,所需的输出将是移动 item2
,这样在添加新项目后列表小部件未覆盖同一树小部件中其下方的项目。
您可以将树子类化并连接模型的 rowsInserted
和 rowsRemoved
信号,然后相应地更新几何图形,包括项目的几何图形:
class TreeWidget(QtWidgets.QTreeWidget):
def setItemWidget(self, item, column, widget):
super().setItemWidget(item, column, widget)
if isinstance(widget, MyListWidget):
widget.model().rowsInserted.connect(
lambda: self.updateItemWidget(item, column))
widget.model().rowsRemoved.connect(
lambda: self.updateItemWidget(item, column))
def updateItemWidget(self, item, column):
widget = self.itemWidget(item, column)
item.setSizeHint(column, widget.sizeHint())
self.updateGeometries()