如何在QTableView/QbstractTableModel中使用多行文字/换行符

How to use multiline text / linebreaks in QTableView/QAbstractTableModel?

本文关键字:换行符 文字 QTableView QbstractTableModel      更新时间:2023-10-16

我已经将QAbstractTableModel和QTabelView(以及QSortFilterProxyModel)划分为子类,我希望允许用户在文本单元格中显示和输入多行文本(目前,点击回车键将确认编辑,而不是插入换行符)。

应该有一些简单的标志来设置,我只是不知道是哪一个。。。

QItemDelegate实际上可以在多行上绘制文本(如果它包含显式的'\n'字符),而默认的QStyledItemDelegate不能做到这一点(至少在Linux上没有,我没有测试其他平台)。因此,我们需要使用QItemDelegate进行渲染。

但我们也需要更改用于编辑的小部件,它不能再是QLineEdit,它需要是QPlainTextEdit。因此,我们必须从QItemDelegate派生,并更改为进行编辑而创建的小部件的类型。

#ifndef MULTILINEDELEGATE_H
#define MULTILINEDELEGATE_H
#include <QItemDelegate>
class MultilineDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    using QItemDelegate::QItemDelegate;
public:
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
};
#endif
#include "multilinedelegate.h"
#include <QPlainTextEdit>
QWidget *MultilineDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option);
    Q_UNUSED(index);
    return new QPlainTextEdit(parent);
}
void MultilineDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if (auto *textEdit = qobject_cast<QPlainTextEdit *>(editor)) {
        textEdit->setPlainText(index.data(Qt::EditRole).toString());
    } else {
        QItemDelegate::setEditorData(editor, index);
    }
}
void MultilineDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    if (auto *textEdit = qobject_cast<QPlainTextEdit *>(editor)) {
        model->setData(index, textEdit->toPlainText());
    } else {
        QItemDelegate::setModelData(editor, model, index);
    }
}

现在,剩下要做的就是在适当的列上使用该委托。例如tableView->setItemDelegateForColumn(MyModel::AddressColumn, new MultilineDelegate(this));

如果行根据需要垂直增长,效果也会更好:tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

用Qt 5.15测试,希望它也能用Qt 6。

不完全确定你在问什么,但我假设你的单元格已经设置了一个可以接受多行输入的小部件(即QTextEditQTableView上使用setItem)。

如果你有,我相信你会想要创建一个自定义的QItemDelegate派生类,并覆盖默认的Enter行为来插入换行符,而不是像默认行为那样提交委托的数据

请参阅http://qt-project.org/doc/qt-4.8/qitemdelegate.html#eventFilter让你朝着正确的方向开始。