سؤال

هل هناك أي طريقة لتحديد ما إذا كان أ QTableView لديه محرر مفتوح في الخلية الحالية؟ أحتاج إلى التعامل مع الموقف التالي:

  • ينقر مستخدم نقرًا مزدوجًا على خلية ويقوم بتحرير البيانات ، ولكن يترك الخلية في حالة "تحرير".
  • في جزء آخر من واجهة المستخدم ، يتم اتخاذ إجراء يغير الصف المحدد من النموذج الأساسي.
  • مرة أخرى على وجهة نظري ، أريد تحديد ما إذا كان الصف المحدد حديثًا هو نفس الصف المفتوح. إذا لم يكن الأمر كذلك ، فأنا بحاجة إلى اتخاذ إجراء. (مطالبة المستخدم؟ ارتكاب تلقائيًا؟ العودة؟)

أرى كيفية الحصول على العنصر الحالي ، ويمكنني الحصول على المندوب على هذا العنصر ، لكنني لا أرى أي شيء isEditMode() خاصية كنت آمل أن أجدها.

هل يستطيع احد توجيهي الي الوجهة الصحيحة؟

هل كانت مفيدة؟

المحلول

الفئة الفرعية مندوبتك بحيث يتضمن ملحقًا يخبرك عند التحرير:

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, ، يمكنك أن تنبعث من الإشارات حتى تعرف الحالة التي يوجد فيها المندوب.

نصائح أخرى

فقط تحقق مما إذا كانت قيمة الإرجاع

State QAbstractItemView::state () const

هو

QTableView::EditingState

الاتصال بالإشارة التي تم تنسيقها النموذجية الأساسية

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

يمكنك التحقق مما إذا كانت الخلية التي تتغير فيها البيانات هي نفسها من CurrentIndex

QModelIndex QAbstractItemView::currentIndex () const

لا يمكنك معرفة ما إذا كانت الخلية الحالية تحتوي على محرر مفتوح مستقيم ، ولكن يمكنك التحقق مما إذا كان العرض موجودًا في QabstractItemView :: EditingState

State QAbstractItemView::state () const

يجب أن يكون كافيا لفعل ما تريد.

يمكنك الفئة الفرعية 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-عضو. بدلاً من ذلك ، قم بإنشاء مؤشر إلى int واستخدام ذلك.

إذا كنت تعرف فهرس العنصر الذي يتم تحريره ، فيمكنك الاتصال indexWidget() ومحاولة إلقاءها. إذا كان ذلك صالحًا ، فأنت لا تعرف فقط أنك تحرر ، ولكن لديك أيضًا عنصر واجهة تحرير في متناول يديك.

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

فيما يلي فكرة ، من المفيد الحصول على عنصر واجهة التحرير/التحرير قبل بدء التحرير ...

ما عليك سوى انبعاث إشارة واستهلكها في Mainwindow ... هذا ما استخدمته للحصول على مربع التحرير والسرد في 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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top