从模型访问委托人的输入值

时间:2019-06-11 10:01:50

标签: qt delegates qabstractitemmodel

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

确实,我已经尝试了几件事。
首先:尝试通过createEditor中定义的属性访问委托的当前输入(通过QItemDelegate创建),但是...似乎不存在。这就是为什么我尝试添加QWidget* editor属性并将其设置在createEditor中的原因。
不幸的是,QItemDelegate的{​​{1}}应该是const,这使我无法在此处设置属性(而且由于我无法控制调用createEditor的内容,因此我无法做它之前或之后)。

我真的不知道该怎么办。实际上,我还需要知道用户何时开始(或停止)编辑单元格内容,最终我通过创建两个createEditor信号(consteditingStarted)来实现。我可能会创建一个editingStopped const信号,但是感觉很糟糕而且很丑...

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

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

MainWindow.h

editorOpened(QWidget*)

MainWindow.cpp

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

#endif // MAINWINDOW_H

MyItemDelegate.h

#include "mainwindow.h"

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

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

MainWindow::~MainWindow()
{
}

MyItemDelegate.cpp

#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

MyTableView.h

#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.cpp

#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

main.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;
        });
    });
}

Example output

1 个答案:

答案 0 :(得分:0)

以下解决方案可能符合您的需求。我只是在委托内部定义了一个新信号,并在拥有该委托的类中将其连接到该信号。

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; });
}