Qt:编辑QTableView项目数据而不是编辑完成后发出信号?

Qt:编辑QTableView项目数据而不是编辑完成后发出信号?,qt,qtableview,qabstracttablemodel,Qt,Qtableview,Qabstracttablemodel,我有一个QTableView,它的模型中有一些基于QString的项。我在我的表模型中实现了setData,因此编辑工作正常(我可以更改单元格中的数据,调用setData来更新模型,并且表被正确更新) 当前,仅当用户完成编辑时(例如,在他们点击Enter或单击文本输入框外以完成文本输入后),才会调用setData。我希望在用户在文本编辑控件中键入/编辑时更新表的其他部分,而不是在完成这些操作并最终确定编辑的内容之后 我想要的一个简单示例是,下一个表格单元格显示已输入正在编辑的单元格的字符数,但在

我有一个QTableView,它的模型中有一些基于QString的项。我在我的表模型中实现了setData,因此编辑工作正常(我可以更改单元格中的数据,调用setData来更新模型,并且表被正确更新)

当前,仅当用户完成编辑时(例如,在他们点击Enter或单击文本输入框外以完成文本输入后),才会调用setData。我希望在用户在文本编辑控件中键入/编辑时更新表的其他部分,而不是在完成这些操作并最终确定编辑的内容之后

我想要的一个简单示例是,下一个表格单元格显示已输入正在编辑的单元格的字符数,但在用户键入/编辑单元格内容时执行此操作,而不是在编辑完成并调用setData之后


有什么我应该找的吗?谢谢

您可以对
QStyledItemDelegate
进行子类化,并在发生更改时提交数据,然后使用
QAbstractItemView::setDelegateForColumn
为视图设置该委托

class MyDelegate : public QStyledItemDelegate {
   QSignalMapper *mapper;
public:
   MyDelegate(QObject*parent = 0)
     : QStyledItemDelegate(parent)
     , mapper(new QSignalMapper(this))
   {
       connect(mapper, SIGNAL(mapped(QWidget*)), SIGNAL(commitData(QWidget*)));
   }
   QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option,
             const QModelIndex & index ) const
   {
       QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index);
       if(qobject_cast<QLineEdit*>(editor)) {
           connect(editor, SIGNAL(textChanged(QString)), mapper, SLOT(map()));
           mapper->setMapping(editor, editor);
       }
       return editor;
   }
};
类MyDelegate:公共QStyledItemDelegate{
QSignalMapper*映射器;
公众:
MyDelegate(QObject*parent=0)
:QStyledItemDelegate(父级)
,映射器(新QSignalMapper(本))
{
连接(映射器、信号(映射(QWidget*)、信号(commitData(QWidget*)));
}
QWidget*createEditor(QWidget*父项,常量QSTYLEOPTION视图项和选项,
常数QModelIndex和索引)常数
{
QWidget*editor=QStyledItemDelegate::createEditor(父项、选项、索引);
if(qobject_cast(编辑)){
连接(编辑器、信号(textChanged(QString))、映射器、插槽(map());
映射器->设置映射(编辑器,编辑器);
}
返回编辑器;
}
};

您可以子类化
QStyledItemDelegate
并在发生更改时提交数据,然后使用
qabstractemview::setDelegateForColumn
为视图设置该委托

class MyDelegate : public QStyledItemDelegate {
   QSignalMapper *mapper;
public:
   MyDelegate(QObject*parent = 0)
     : QStyledItemDelegate(parent)
     , mapper(new QSignalMapper(this))
   {
       connect(mapper, SIGNAL(mapped(QWidget*)), SIGNAL(commitData(QWidget*)));
   }
   QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option,
             const QModelIndex & index ) const
   {
       QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index);
       if(qobject_cast<QLineEdit*>(editor)) {
           connect(editor, SIGNAL(textChanged(QString)), mapper, SLOT(map()));
           mapper->setMapping(editor, editor);
       }
       return editor;
   }
};
类MyDelegate:公共QStyledItemDelegate{
QSignalMapper*映射器;
公众:
MyDelegate(QObject*parent=0)
:QStyledItemDelegate(父级)
,映射器(新QSignalMapper(本))
{
连接(映射器、信号(映射(QWidget*)、信号(commitData(QWidget*)));
}
QWidget*createEditor(QWidget*父项,常量QSTYLEOPTION视图项和选项,
常数QModelIndex和索引)常数
{
QWidget*editor=QStyledItemDelegate::createEditor(父项、选项、索引);
if(qobject_cast(编辑)){
连接(编辑器、信号(textChanged(QString))、映射器、插槽(map());
映射器->设置映射(编辑器,编辑器);
}
返回编辑器;
}
};
当我需要一个持久的解决方案时,@alexisdm提供的答案对我来说并不适用 由
QAbstractTableModel::setPersistentEditor(QModelIndex())
启用的编辑器

以下方法解决了此问题:

class Delegate : public QStyledItemDelegate 
{
    Q_OBJECT
public: 

    // ... omitted for brevity

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override 
    {
        auto *editor = static_cast<QLineEdit*>(
                            QStyledItemDelegate::createEditor(parent, option, index));
        if (editor) {
            connect(editor,
                    &QLineEdit::textChanged,
                    [=] (const QString &)
            {
                const_cast<Delegate*>(this)->commitData(editor);
            });
        }
        return editor;   
    }

    // ... omitted for brevity
};
类委托:公共QStyledItemDelegate
{
Q_对象
公众:
//…为简洁起见省略
QWidget*createEditor(QWidget*父项,常量QSTYLEOPTION视图项和选项,
常量QModelIndex和索引)常量覆盖
{
自动*编辑器=静态(
QStyledItemDelegate::createEditor(父项、选项、索引));
如果(编辑){
连接(编辑器,
&QLineEdit::textChanged,
[=](常量QString&)
{
const_cast(本)->commitData(编辑);
});
}
返回编辑器;
}
//…为简洁起见省略
};
我们只需从
this
中强制转换常量,并使其为编辑器提交数据

请注意,在lambda中,我们通过值
[=]
捕获
编辑器
变量,因为否则,当函数超出范围时,使用引用捕获将使
编辑器
的值未定义。

当我需要一个持久的解决方案时,@alexisdm提供的答案对我来说并不适用 由
QAbstractTableModel::setPersistentEditor(QModelIndex())
启用的编辑器

以下方法解决了此问题:

class Delegate : public QStyledItemDelegate 
{
    Q_OBJECT
public: 

    // ... omitted for brevity

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override 
    {
        auto *editor = static_cast<QLineEdit*>(
                            QStyledItemDelegate::createEditor(parent, option, index));
        if (editor) {
            connect(editor,
                    &QLineEdit::textChanged,
                    [=] (const QString &)
            {
                const_cast<Delegate*>(this)->commitData(editor);
            });
        }
        return editor;   
    }

    // ... omitted for brevity
};
类委托:公共QStyledItemDelegate
{
Q_对象
公众:
//…为简洁起见省略
QWidget*createEditor(QWidget*父项,常量QSTYLEOPTION视图项和选项,
常量QModelIndex和索引)常量覆盖
{
自动*编辑器=静态(
QStyledItemDelegate::createEditor(父项、选项、索引));
如果(编辑){
连接(编辑器,
&QLineEdit::textChanged,
[=](常量QString&)
{
const_cast(本)->commitData(编辑);
});
}
返回编辑器;
}
//…为简洁起见省略
};
我们只需从
this
中强制转换常量,并使其为编辑器提交数据

请注意,在lambda中,我们通过值
[=]
捕获
编辑器
变量,因为否则,当函数超出范围时,使用引用捕获将使
编辑器
的值未定义