2010-08-06 68 views
8

有没有什么办法,以确定是否有QTableView在当前单元格打开的编辑器?我需要处理以下情况:确定是否QTableView中有一个开放的编辑

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

我看看如何将目前的项目,可以得到关于该项目的委托,但我没有看到任何isEditMode()财产,我希望能找到。

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

回答

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,你可以让你知道什么注明委托是在发出信号。

+0

只是一个说明,我认为你的意思是* mutable *,而不是* volatile *。 – 2010-08-13 18:19:33

+0

@Caleb - 你说得对。改变 - 并感谢指出。 – 2010-08-13 19:16:26

+3

正如他在答复中指出,由弗洛里安Kusche,这不起作用,因为setModelData()如果编辑承诺只叫,但如果它的取消。 – emkey08 2014-03-29 12:53:48

3

连接到底层模型dataChanged信号

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

您可以检查电池其中数据已经改变比CURRENTINDEX相同

QModelIndex QAbstractItemView::currentIndex() const 

你可以不知道,如果当前单元格有直接打开的编辑器,但可以检查视图在QAbstractItemView中:: EditingState

State QAbstractItemView::state() const 

这应该足以做你想做的。

2

您可以继承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必须是一个整数而不是bool。

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

+0

不错。只是几个意见:更好地使用可变的int而不是int *。此外,没有必要在你提供的解决方案重新实现setEditorData()和setModelData(),所以你可以省略看看是否清晰。 – emkey08 2014-03-29 13:00:10

+0

是的,你是对的。可变整数会好一点。 – 2014-03-30 19:55:44

6

只是检查的

State QAbstractItemView::state() const 

返回值是否为

QTableView::EditingState 
+0

我不知道,如果其在该状态是足够的,以确定它是针对当前** **细胞 – Trompa 2016-01-04 15:37:06

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

,并在主窗口声明一个功能,以接收的指示信号...

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

然后终于在主窗口的构造连接它...

ComboBoxItemDelegate* cbid = new ComboBoxItemDelegate(ui->tableWidget); 
connect(cbid, &ComboBoxItemDelegate::OnComboEdit, this, &MainWindow::OnComboEidt); 
ui->tableWidget->setItemDelegateForColumn(0, cbid); 
1

如果您知道正在编辑的项目的索引,您可以致电indexWidget()并尝试施放它。如果它是有效的,你不仅知道你正在编辑,而且你还有你的编辑器小部件方便。

EditWidget *editWidget = qobject_cast<EditWidget*>(tableView->indexWidget(tableView->currentIndex())); 
if(editWidget) 
{ 
    //yep, ur editing bro 
} 
相关问题