Qt关于QTableView双击显示问题

QTableView双击单元格后显示原数据是可以做到的,但能不能做到双击后单元格内显示指定的数据呢?
譬如:指定行列的单元格对应的数据是QString类型,值为“123-456”,双击单元格后进入编辑状态只显示“456”,怎么做呢?

参考GPT和自己的思路,可以通过继承 QStyledItemDelegate 类来实现这个功能。在 QStyledItemDelegate 类中,可以重写 createEditor() 和 setEditorData() 函数来控制编辑器的创建和数据显示。

以下是一个简单的示例代码:

#include <QStyledItemDelegate>
#include <QLineEdit>
#include <QModelIndex>
#include <QObject>

class MyDelegate : public QStyledItemDelegate
{
public:
    MyDelegate(QObject *parent = nullptr)
        : QStyledItemDelegate(parent)
    {}

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override
    {
        QLineEdit *editor = new QLineEdit(parent);
        // 获取指定单元格的数据
        QString data = index.model()->data(index, Qt::EditRole).toString();
        // 获取 "-" 后面的文本
        QString suffix = data.section("-", 1);
        editor->setText(suffix);
        return editor;
    }

    void setEditorData(QWidget *editor, const QModelIndex &index) const override
    {
        // 获取指定单元格的数据
        QString data = index.model()->data(index, Qt::EditRole).toString();
        // 获取 "-" 后面的文本
        QString suffix = data.section("-", 1);
        QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor);
        lineEdit->setText(suffix);
    }

    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override
    {
        QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor);
        QString data = model->data(index, Qt::EditRole).toString();
        // 获取 "-" 前面的文本
        QString prefix = data.section("-", 0, 0);
        QString newText = prefix + "-" + lineEdit->text();
        model->setData(index, newText, Qt::EditRole);
    }
};

在使用时,只需要将这个委托类设置给 QTableView 即可:

MyDelegate *delegate = new MyDelegate(this);
ui->tableView->setItemDelegate(delegate);

这样,当双击单元格时,编辑器就会显示 "-" 后面的文本,而不是整个数据。当编辑器提交数据时,我们需要将新的文本拼接上原始文本中的 "-" 前面的部分,然后再更新到模型中。

这个你是希望改变单元格,还是只是显示一部分?后者最好覆盖一个文本框上去

该回答引用GPTᴼᴾᴱᴺᴬᴵ
可以通过重载 QStyledItemDelegate 中的 createEditor 和 setEditorData 方法来实现这个功能。下面是一个示例:

class MyDelegate(QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        editor = QLineEdit(parent)
        return editor

    def setEditorData(self, editor, index):
        value = index.model().data(index, Qt.DisplayRole)
        value = value.split('-')[1]
        editor.setText(value)

在这个示例中,我们自定义了一个委托类 MyDelegate 并重载了 createEditor 和 setEditorData 方法。在 createEditor 中,我们创建了一个 QLineEdit 编辑器,并返回给表格视图。在 setEditorData 中,我们获取了单元格中的数据,并将其修改为指定的字符串格式后,将其设置为编辑器的文本。这样,当用户双击单元格进入编辑状态时,编辑器中的文本就是我们指定的字符串格式。

接下来,我们需要将委托类应用到表格视图中:

myDelegate = MyDelegate()
myTableView.setItemDelegateForColumn(columnIndex, myDelegate)


在这个示例中,我们创建了一个 MyDelegate 实例,并将其应用到了指定列的单元格上。

注意:如果你需要在用户编辑单元格后将修改后的数据保存回模型中,请重载委托类中的 setModelData 方法。

参考GPT和自己的思路:您可以使用QStyledItemDelegate类来实现此目的。QStyledItemDelegate是一个委托类,用于在QTableView中编辑和显示单元格数据。

要显示指定的数据,您可以使用createEditor()函数来创建编辑器,并在其中设置指定的数据。在displayText()函数中,您可以返回要显示的文本,例如返回值只显示“456”。

以下是一个简单的示例代码,其中第一列的数据显示完整的字符串,而第二列只显示第二个分隔符后面的字符串。

class CustomDelegate : public QStyledItemDelegate
{
public:
    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {
        QLineEdit* editor = new QLineEdit(parent);
        if (index.column() == 1) {
            // 设置指定的数据
            QString text = index.model()->data(index, Qt::DisplayRole).toString();
            QStringList parts = text.split("-");
            if (parts.size() > 1) {
                editor->setText(parts[1]);
            }
        } else {
            editor->setText(index.model()->data(index, Qt::DisplayRole).toString());
        }
        return editor;
    }

    QString displayText(const QVariant& value, const QLocale& locale) const override
    {
        QString text = value.toString();
        if (index.column() == 1) {
            // 返回要显示的文本
            QStringList parts = text.split("-");
            if (parts.size() > 1) {
                return parts[1];
            }
        }
        return text;
    }
};

// 在QTableView中设置自定义委托
CustomDelegate* delegate = new CustomDelegate();
tableView->setItemDelegate(delegate);

在上述示例代码中,我们创建了一个名为CustomDelegate的自定义委托类,并覆盖了createEditor()和displayText()函数。在createEditor()函数中,我们检查列索引以确定如何设置编辑器中的文本。在displayText()函数中,我们返回要显示的文本。最后,在QTableView中设置自定义委托以使用CustomDelegate类来显示和编辑单元格数据。

该回答引用ChatGPT

如有疑问,可以回复我!

可以实现双击后单元格内显示指定的数据。要实现这个功能,你需要对 QTableView 的双击事件进行处理,并在编辑状态下设置指定的数据。以下是一个简单的例子说明如何实现:

首先,你需要继承 QStyledItemDelegate 并重写 createEditor() 方法以修改双击后显示的数据:


#include <QStyledItemDelegate>

class CustomDelegate : public QStyledItemDelegate {
    Q_OBJECT

public:
    CustomDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};

然后在 createEditor() 方法中,根据模型数据修改编辑器的默认值:


#include <QLineEdit>

QWidget *CustomDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    QLineEdit *editor = new QLineEdit(parent);
    QString originalText = index.data(Qt::DisplayRole).toString();
    QStringList splitText = originalText.split('-');
    if (splitText.count() == 2) {
        editor->setText(splitText.at(1));
    } else {
        editor->setText(originalText);
    }
    return editor;
}

最后,将自定义代理应用于你的 QTableView:

QTableView *tableView = new QTableView;
tableView->setModel(yourModel);
tableView->setItemDelegate(new CustomDelegate(tableView));

这样,当你双击单元格时,只会显示指定的数据。在这个例子中,它会显示“123-456”的“456”。注意这里只展示了简化版的实现,实际应用中还需要处理更多细节,如提交编辑后的数据等。

基于最新版ChatGPT4的回答,望采纳!!!有其他问题也可以询问我哦💕(最新版更智能,功能更加强大):
要实现双击单元格后显示指定数据,您可以通过重载 QTableView 的 mouseDoubleClickEvent 事件来实现。首先,需要在您的自定义 QTableView 类中重载 mouseDoubleClickEvent 方法。当检测到双击事件时,获取双击的单元格所在的行和列,然后根据需要修改单元格的数据。以下是一个简单的示例:

#include <QTableView>
#include <QMouseEvent>
#include <QStandardItemModel>

class CustomTableView : public QTableView {
    Q_OBJECT
public:
    explicit CustomTableView(QWidget *parent = nullptr);

protected:
    void mouseDoubleClickEvent(QMouseEvent *event) override;
};

CustomTableView::CustomTableView(QWidget *parent)
    : QTableView(parent) {
}

void CustomTableView::mouseDoubleClickEvent(QMouseEvent *event) {
    QModelIndex index = indexAt(event->pos());
    if (!index.isValid()) {
        return;
    }

    int row = index.row();
    int column = index.column();

    QStandardItemModel *model = qobject_cast<QStandardItemModel *>(this->model());
    if (!model) {
        return;
    }

    QStandardItem *item = model->item(row, column);
    if (!item) {
        return;
    }

    QString originalData = item->text();
    QStringList splitData = originalData.split("-");
    if (splitData.size() > 1) {
        item->setText(splitData.at(1));
    }

    QTableView::mouseDoubleClickEvent(event);
}


在上述示例中,我们创建了一个自定义的 QTableView 类,并重载了 mouseDoubleClickEvent 方法。在双击事件发生时,我们获取双击的单元格位置,并从模型中获取相应的 QStandardItem。然后,我们对原始数据进行处理,只保留“-”后面的部分,并将其设置为单元格的新数据。最后,调用 QTableView::mouseDoubleClickEvent(event) 以确保正常处理双击事件。

这样,在双击单元格时,会显示指定的数据,例如,“123-456”会变为“456”。您可以根据自己的需求对这个示例进行修改。

感谢各位,问题已解决

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^