首页 > 解决方案 > 从模型中访问委托的输入值

问题描述

我正在使用带有自QTableView定义QAbstractTableModelQItemDelegate. 我需要在用户编辑代理编辑器时访问它的内容,经过几次尝试,我找不到任何令人满意的东西。

确实,我已经尝试了几件事。
第一:尝试createEditor通过定义的属性访问委托的当前输入(通过创建)QItemDelegate但是......似乎不存在。这就是为什么我尝试添加一个QWidget* editor属性并将其设置在createEditor.
不幸的是,QItemDelegate'screateEditor应该是 const,这使我无法在那里设置我的属性(并且由于我无法控制调用的内容createEditor,因此我无法在之前或之后执行此操作)。

我真的不知道在这里做什么。实际上,我还需要知道用户何时开始(或停止)编辑单元格内容,我最终通过创建两个const信号 (editingStartededitingStopped) 实现了这一点。我可能可以创建一个const editorOpened(QWidget*)信号,但它只是感觉很糟糕和丑陋......

我不敢相信没有任何“官方”可以实现我想要做的事情,因此这个问题。如果我从一开始就错了,我很高兴知道。如果您有其他想法,请提出建议。

编辑:这是一个最小的工作示例

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"

#include <QTableView>
#include "mytableview.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    auto tableView = new MyTableView(this);
    setCentralWidget(tableView);
}

MainWindow::~MainWindow()
{
}

MyItemDelegate.h

#ifndef MYITEMDELEGATE_H
#define MYITEMDELEGATE_H

#include <QItemDelegate>
#include <QLineEdit>
#include <QStandardItemModel>

class MyItemDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    MyItemDelegate(QObject* parent);

    virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
    virtual void onCloseEditor();

    virtual ~MyItemDelegate() = default;

signals:
    // Const signals trick
    void editingStarted() const;
    void editingFinished() const;
    void editorOpened(const QWidget*) const;
};

#endif // MYITEMDELEGATE_H

MyItemDelegate.cpp

#include "myitemdelegate.h"

MyItemDelegate::MyItemDelegate(QObject* parent) : QItemDelegate(parent)
{
    connect(this, &QItemDelegate::closeEditor, this, &MyItemDelegate::onCloseEditor);
}

QWidget* MyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    auto lineEdit = new QLineEdit(parent);
    emit editingStarted();
    emit editorOpened(lineEdit);
    return lineEdit;
}

void MyItemDelegate::onCloseEditor()
{
    emit editingFinished();
}

MyTableView.h

#ifndef MYTABLEVIEW_H
#define MYTABLEVIEW_H

#include <QTableView>
#include <QDebug>
#include "myitemdelegate.h"

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

signals:

public slots:
};

#endif // MYTABLEVIEW_H

MyTableView.cpp

#include "mytableview.h"

MyTableView::MyTableView(QWidget *parent) : QTableView(parent)
{
    MyItemDelegate* delegate = new MyItemDelegate(this);
    QStandardItemModel* model = new QStandardItemModel(this);
    setItemDelegate(delegate);
    setModel(model);

    QList<QList<QStandardItem*>> items;
    for(int i = 0; i < 10; i++)
    {
        items << QList<QStandardItem*>();
        for (int j = 'A'; j < 'E'; j++)
            items[i] << new QStandardItem(QString("%1,%2").arg(i).arg(static_cast<char>(j)));
    }

    for (const auto& row : items)
        model->appendRow(row);

    connect(delegate, &MyItemDelegate::editingStarted, []() {
        qDebug() << "Editing started";
    });

    connect(delegate, &MyItemDelegate::editingFinished, []() {
        qDebug() << "Editing finished";
    });

    connect(delegate, &MyItemDelegate::editorOpened, [](const QWidget* editor) {
        auto lineEdit = qobject_cast<const QLineEdit*>(editor);
        connect(lineEdit, &QLineEdit::textChanged, [](const QString& text) {
            qDebug() << text;
        });
    });
}

主文件

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

示例输出

标签: qtdelegatesqabstractitemmodel

解决方案


以下解决方案可能适合您的需求。我刚刚在委托中定义了一个新信号,并在拥有委托的类中连接到它。

MyItemDelegate.h

#ifndef MYITEMDELEGATE_H
#define MYITEMDELEGATE_H

#include <QStyledItemDelegate>

class MyItemDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    MyItemDelegate(QObject* parent);

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;

    virtual ~MyItemDelegate() = default;

signals:
    void valueChanged(const QString&);
};

#endif // MYITEMDELEGATE_H

MyItemDelegate.cpp

#include "myitemdelegate.h"
#include <QLineEdit>

MyItemDelegate::MyItemDelegate(QObject* parent) : QStyledItemDelegate(parent)
{
}

QWidget* MyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    auto lineEdit = new QLineEdit(parent);
    connect(lineEdit, &QLineEdit::textChanged, this, &MyItemDelegate::valueChanged);
    return lineEdit;
}

MyTableView.cpp

#include "mytableview.h"
#include <QStandardItemModel>

MyTableView::MyTableView(QWidget *parent) : QTableView(parent)
{
    MyItemDelegate* delegate = new MyItemDelegate(this);
    QStandardItemModel* model = new QStandardItemModel(this);
    setItemDelegate(delegate);
    setModel(model);

    QList<QList<QStandardItem*>> items;
    for(int i = 0; i < 10; i++)
    {
        items << QList<QStandardItem*>();
        for (int j = 'A'; j < 'E'; j++)
            items[i] << new QStandardItem(QString("%1,%2").arg(i).arg(static_cast<char>(j)));
    }

    for (const auto& row : items)
        model->appendRow(row);

    connect(delegate, &MyItemDelegate::valueChanged, [](auto v) { qDebug() << v; });
}

推荐阅读