حدد ما إذا كان QTableView لديه محرر مفتوح
-
26-09-2019 - |
سؤال
هل هناك أي طريقة لتحديد ما إذا كان أ 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);