9

有什么方法可以确定QTableView当前单元格中是否有打开的编辑器?我需要处理以下情况:

  • 用户双击单元格并编辑数据,但使单元格处于“编辑”状态
  • 在 UI 的另一部分,执行更改基础模型的选定行的操作。
  • 回到我的观点,我想确定新选择的行是否与打开的行相同。如果没有,我需要采取行动。(提示用户?自动提交?还原?)

我知道如何获取当前项目,并且可以获得该项目的委托,但我没有看到任何isEditMode()我希望找到的属性。

有人可以指出我正确的方向吗?

4

6 回答 6

10

只检查返回值是否为

State QAbstractItemView::state () const

QTableView::EditingState
于 2014-03-13T14:04:16.873 回答
3

连接到底层模型 dataChanged 信号

void QAbstractItemModel::dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight )

您可以检查数据已更改的单元格是否与 currentIndex 相同

QModelIndex QAbstractItemView::currentIndex () const

您无法直接知道当前单元格是否有打开的编辑器,但可以检查视图是否在 QAbstractItemView::EditingState

State QAbstractItemView::state () const

做你想做的应该足够了。

于 2012-12-11T10:32:14.787 回答
3

您可以子类化QTableView以便能够访问该state()功能,不幸的是,该功能受到保护。但是,我没有尝试过。

如果您已经有一个QStyledItemDelegate子类,您可以使用它来跟踪当前是否打开了一个编辑器。但是,您不能只使用setEditorData/ setModelData,因为setModelData当用户取消编辑时不会被调用。相反,您可以跟踪编辑器本身的创建和销毁。

class MyItemDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    MyItemDelegate( QObject* parent = nullptr );
    ~MyItemDelegate();

    QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
    void setEditorData( QWidget* editor, const QModelIndex& index ) const;
    void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;

    bool isEditorOpen() const   { return *m_editorCount > 0; }

protected:
    int* m_editorCount;

protected slots:
    void onEditorDestroyed( QObject* obj );
};

执行:

MyItemDelegate::MyItemDelegate( QObject* parent ) :
    QStyledItemDelegate( parent )
{
    m_editorCount = new int;
    *m_editorCount = 0;
}

MyItemDelegate::~MyItemDelegate()
{
    delete m_editorCount;
}

QWidget* MyItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    // create an editor, can be changed as needed
    QWidget* editor = QStyledItemDelegate::createEditor( parent, option, index );

    connect( editor, SIGNAL(destroyed(QObject*)), SLOT(onEditorDestroyed(QObject*)));
    printf( "editor %p created\n", (void*) editor );
    (*m_editorCount)++;

    return editor;
}

void MyItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    ...
}

void MyItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    ...
}

void MyItemDelegate::onEditorDestroyed( QObject* obj )
{
    printf( "editor %p destroyed\n", (void*) obj );
    (*m_editorCount)--;
}

在某些情况下,例如当使用光标键移动到树中的下一个项目时,Qt 将首先创建新编辑器,然后销毁旧编辑器。因此,m_editorCount必须是整数而不是布尔值。

不幸的是,createEditor()是一个const函数。因此,您不能创建int-member。相反,创建一个指向 an 的指针int并使用它。

于 2013-08-29T12:01:02.407 回答
2

将您的委托子类化,以便它包含一个访问器,该访问器在编辑时告诉您:

void MyDelegate::setEditorData ( QWidget * editor, const QModelIndex & index ) const {
    // _isEditing  will have to be mutable because this method is const
    _isEditing = true; 
    QStyledItemDelegate::setEditorData(editor, index);
}

void MyDelegate::setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const {
    QStyledItemDelegate::setModelData(editor, model, index);
    _isEditing = false;
}

bool MyDelegate::isEditing() const { return _isEditing; }

然后,您可以检查委托以查看发生了什么。或者和/或如果您不喜欢mutable,您可以发出信号,以便您知道代表处于什么状态。

于 2010-08-06T20:52:59.460 回答
1

如果您知道正在编辑的项目的索引,则可以调用indexWidget()并尝试投射它。如果它有效,您不仅知道您正在编辑,而且您的编辑器小部件也很方便。

EditWidget *editWidget = qobject_cast<EditWidget*>(tableView->indexWidget(tableView->currentIndex()));
if(editWidget)
{
    //yep, ur editing bro
}
于 2016-12-31T08:45:45.497 回答
0

这是一个想法,在编辑开始之前获取编辑/组合小部件甚至很有帮助......

只需发出一个信号并在主窗口中使用它......这就是我在编辑之前在 QTableWidget 中使用的一个组合框......

首先在 ComoBoxItemDelegate 中创建一个信号...

signals:
   void OnComboEdit(QComboBox* pCombo) const;

然后在 createEditor 方法中发出信号...

QWidget* ComboBoxItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    // Create the combobox and populate it
    QComboBox* cb = new QComboBox(parent);
    emit OnComboEdit(cb);
    return cb;
}

并在 MainWindow 中声明一个函数来接收信号...

void MainWindow::OnComboEidt(QComboBox *pCB) const
{
    qDebug() << "Combo Eidt Singal Received";
}

然后最后在 MainWindow 的构造函数中连接它......

ComboBoxItemDelegate* cbid = new ComboBoxItemDelegate(ui->tableWidget);
connect(cbid, &ComboBoxItemDelegate::OnComboEdit, this, &MainWindow::OnComboEidt);
ui->tableWidget->setItemDelegateForColumn(0, cbid);
于 2016-09-08T03:34:50.373 回答