我使用QListView
和QFileSystemModel
来显示目录的内容。我正在尝试模拟Windows文件资源管理器,在该资源管理器中,如果文件/文件夹文本足够长,它会自动换行以显示对象的全名。
当它在文件资源管理器中显示时
在我看来,我已经尝试了setGridSize(QtCore.QSize(80, 80))
,以便给我足够的空间、setWordWrap(True)
和setTextElideMode(QtCore.Qt.ElideNone)
但是文本仍然会被裁剪。
我已经研究过使用QStyledItemDelegate
来包装文本,但我不确定如何获得我想要的行为。
如何将视图设置为显示文本换行而不裁剪任何文本?
这是我到目前为止创建的代码...
import sys
from PySide2 import QtCore
from PySide2 import QtWidgets
from shiboken2 import wrapInstance
class TreeViewDialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(TreeViewDialog, self).__init__(parent)
self.setMinimumSize(500, 400)
self.create_widgets()
self.create_layout()
def create_widgets(self):
root_path = r"C:\Users\Documents\Test"
self.model = QtWidgets.QFileSystemModel()
self.model.setRootPath(root_path)
self.list_view = QtWidgets.QListView()
self.list_view.setViewMode(QtWidgets.QListView.IconMode)
self.list_view.setResizeMode(QtWidgets.QListView.Adjust)
self.list_view.setFlow(QtWidgets.QListView.LeftToRight)
self.list_view.setMovement(QtWidgets.QListView.Snap)
self.list_view.setModel(self.model)
self.list_view.setRootIndex(self.model.index(root_path))
self.list_view.setGridSize(QtCore.QSize(80, 80))
self.list_view.setUniformItemSizes(True)
self.list_view.setWordWrap(True)
self.list_view.setTextElideMode(QtCore.Qt.ElideNone)
def create_layout(self):
main_layout = QtWidgets.QHBoxLayout(self)
main_layout.setContentsMargins(2, 2, 2, 2)
main_layout.addWidget(self.list_view)
if __name__ == "__main__":
app = QtWidgets.QApplication.instance()
if not app:
app = QtWidgets.QApplication(sys.argv)
tree_view_dialog = TreeViewDialog()
tree_view_dialog.show()
sys.exit(app.exec_())
发布于 2021-10-08 00:01:56
因此,通过实现自定义QStyledItemDelegate
、实现paint()
和sizeHint()
方法以及在QListView
上设置setItemDelegate()
,我能够获得所需的行为。
delegate = FileNameDelegate(self)
self.list_view.setItemDelegate(delegate)
这是我的委托类。
class FileNameDelegate(QtWidgets.QStyledItemDelegate):
"""Delegate to wrap filenames."""
def paint(self, painter, option, index):
if not index.isValid():
return
painter.save()
# Selected
if option.state & QtWidgets.QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.highlight())
# Icon
icon = index.data(QtCore.Qt.DecorationRole)
mode = QtGui.QIcon.Normal
state = QtGui.QIcon.On if option.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
icon_rect = QtCore.QRect(option.rect)
icon_rect.setSize(QtCore.QSize(option.rect.width(), 40))
icon.paint(painter, icon_rect, alignment=QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter, mode=mode, state=state)
# Text
text = index.data(QtCore.Qt.DisplayRole)
font = QtWidgets.QApplication.font()
font_metrics = QtGui.QFontMetrics(font)
padding = 8
rect = font_metrics.boundingRect(option.rect.left()+padding/2, option.rect.bottom()-icon_rect.height()+padding/2,
option.rect.width()-padding, option.rect.height()-padding,
QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop | QtCore.Qt.TextWrapAnywhere,
text)
color = QtWidgets.QApplication.palette().text().color()
pen = QtGui.QPen(color)
painter.setPen(pen)
painter.setFont(font)
painter.drawText(rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop | QtCore.Qt.TextWrapAnywhere, text)
painter.restore()
def sizeHint(self, option, index):
if not index.isValid():
return super(FileNameDelegate, self).sizeHint(option, index)
else:
text = index.data()
font = QtWidgets.QApplication.font()
font_metrics = QtGui.QFontMetrics(font)
rect = font_metrics.boundingRect(0, 0, option.rect.width(), 0,
QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop | QtCore.Qt.TextWrapAnywhere,
text)
size = QtCore.QSize(option.rect.width(), option.rect.height()+rect.height())
return size
现在,我在运行代码时得到了这个结果。
https://stackoverflow.com/questions/69474089
复制相似问题