自定义项目委托的大小调整和交互

时间:2019-04-29 14:52:25

标签: python pyside

我正在为要在pyside中创建的新闻提要创建自定义项目委托。我不太确定如何使textEdit自动调整其大小以适合要换行的文本的内容,然后保持Text Interaction功能,用户可以在其中单击并突出显示文本?

这是我目前正在得到的,您可以看到文本框被绘制在顶部,而垂直尺寸不正确:

enter image description here

import os, sys
from Qt import QtWidgets, QtCore, QtGui


class NewsItem(object):
    def __init__(self, **kwargs):
        super(NewsItem, self).__init__()
        self.title = kwargs.get('title', '')
        self.date = kwargs.get('date', '')
        self.content = kwargs.get('content', '')


class NewsItemDelegate(QtWidgets.QItemDelegate):

    def __init__(self, parent=None):
        super(NewsItemDelegate, self).__init__(parent)


    def paint(self, painter, option, index):
        # rect = option.rect.adjusted(1, 1, -1, -1)
        # painter.fillRect(rect, QtGui.QColor(20,40,170,50))
        # QtWidgets.QItemDelegate.paint(self, painter, option, index)

        # get data from userrole
        data = index.data(role=QtCore.Qt.UserRole)

        # Main Widget
        title = QtWidgets.QLabel(data.title)
        content = QtWidgets.QTextEdit(data.content)
        content.setFixedHeight(content.sizeHint().height())

        widget = QtWidgets.QWidget()
        layout = QtWidgets.QGridLayout(widget)
        layout.addWidget(title, 0, 0)
        layout.addWidget(content, 1, 0)
        widget.setGeometry(option.rect)

        widget.render(painter, option.rect.topLeft())

        # painter.save()
        # painter.restore()


    def sizeHint(self, option, index):
        return QtCore.QSize(100, 50)
        return QtWidgets.QItemDelegate.sizeHint(self, option, index)


class NewsModel(QtGui.QStandardItemModel):

    def __init__(self, *args, **kwargs):
        QtGui.QStandardItemModel.__init__(self, *args, **kwargs)


class NewsListView(QtWidgets.QListView):
    def __init__(self, parent=None):
        super(NewsListView, self).__init__(parent)

        self.setModel(NewsModel(self))
        self.setItemDelegate(NewsItemDelegate(self))
        self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)


    def setNewsItems(self, lst):
        self.model().clear()
        for x in lst:
            item = QtGui.QStandardItem()
            # item.setData(x.title, role=QtCore.Qt.DisplayRole)
            item.setData(x, role=QtCore.Qt.UserRole)
            self.model().appendRow(item)


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(350, 500)

        # Controls
        self.uiListView = NewsListView()
        self.setCentralWidget(self.uiListView)


    def unitTest(self):
        self.uiListView.setNewsItems([
            NewsItem(title='Big Update', date='Today', content='Something goes here...'),
            NewsItem(title='Smaller Update', date='Yesterday', content='Something goes here which should support word wrap'),
            NewsItem(title='Another Update', date='Last Year', content='Something goes here...'),
            NewsItem(title='Old Update', date='Unknown', content='Something goes here...'),
        ])


def main():
    app = QtWidgets.QApplication(sys.argv)
    ex = MainWindow()
    ex.unitTest()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:0)

在这种情况下,是创建一个小部件作为编辑器,为此,您必须在paint方法中调用openPersistentEditor()。 createEditor(),setEditorData()和setModelData()方法也必须被覆盖。

# ...
from functools import partial
# ...
class EditorWidget(QtWidgets.QWidget):
    editingFinished = QtCore.Signal()

    def __init__(self, data=None, parent=None):
        super(EditorWidget, self).__init__(parent)
        self.title_label = QtWidgets.QLabel()
        self.content_textedit = QtWidgets.QTextEdit()
        self.content_textedit.textChanged.connect(self.editingFinished)
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.title_label)
        lay.addWidget(self.content_textedit)
        if data is not None:
            self.data = data

    @property
    def data(self):
        return NewsItem(
            title=self.title_label.text(),
            content=self.content_textedit.toPlainText(),
        )

    @data.setter
    def data(self, d):
        self.title_label.setText(d.title)
        tc = self.content_textedit.textCursor()
        self.content_textedit.setPlainText(d.content)
        self.content_textedit.setTextCursor(tc)


class NewsItemDelegate(QtWidgets.QItemDelegate):
    def paint(self, painter, option, index):
        if isinstance(self.parent(), QtWidgets.QAbstractItemView):
            self.parent().openPersistentEditor(index)

    def createEditor(self, parent, option, index):
        data = index.data(QtCore.Qt.UserRole)
        editor = EditorWidget(data, parent)
        wrapper = partial(self.commitData.emit, editor)
        editor.editingFinished.connect(wrapper)
        model = index.model()
        model.setData(index, editor.sizeHint(), QtCore.Qt.SizeHintRole)
        return editor

    def setEditorData(self, editor, index):
        data = index.data(QtCore.Qt.UserRole)
        editor.data = data

    def setModelData(self, editor, model, index):
        model.setData(index, editor.data, QtCore.Qt.UserRole)
# ...

enter image description here