QtPropertyBrowser и значение измененных сигналов
Я использую библиотеку Qt Property Browser в качестве редактора записей. Когда пользователь завершит редактирование какого-либо данного поля, удалив фокус с элемента редактирования или нажав клавишу ввода, я хочу получить информацию об этом, чтобы я мог принять изменение, обработать его и отправить в РЕАЛЬНОЕ предмет, который меняется
К сожалению, мне кажется, что я могу только найти сигналы propertyChanged и valueChanged, и они срабатывают каждый раз, когда добавляется или удаляется любое количество текста, а не только когда пользователь запускает финиш.
Не имея возможности получить это уведомление, я не понимаю, как это может быть полезным компонентом. Он даже не возвращается, когда пользователь нажимает [ESC], что я, безусловно, должен иметь возможность реализовать! Конечно, я ошибаюсь, что абсолютно НЕТ сигнала, который делает то, что мне нужно, но я точно не могу его найти.
Кто-нибудь знает?
Изучив исходный код, люди, которые создали фабрику линейного редактора, приняли неудачное решение соединиться с textEdited, а не редактировать Finish. Изменить это было бы относительно просто, за исключением того, что из-за методического подхода невозможно расширить эту фабрику редакторов, которая имеет расширяемый интерфейс!
ВСЕ, что мне нужно сделать, это переопределить функцию createEditor, отключить плохое соединение, подключить лучшее соединение с вызовом между ними, чтобы вывести строку из элемента управления редактирования строки. Но нет!!! Мы не позволим вам сделать это! Мы собираемся поместить все бухгалтерские материалы в закрытый класс, к которому вы не можете получить доступ или позвонить, и те части, которые мы собираемся позволить вам позвонить, будут тесно связаны с тем фактом, что их вызывают редактировать контроль, а не что-нибудь еще. ЭРГО, мы довольно эффективно сделали жизнь настолько разочаровывающей, насколько мы могли себе представить. Разве мы не блестящие?
Я узнал больше. Стандартный подход Qt для таких объектов использует делегаты для управления поведением, которое я пытаюсь получить. Библиотека свойств Qt переопределяет это поведение и делает что-то еще, что НЕ то, чего я пытаюсь достичь. Внутри интерфейса QAbstractItemDelegate находится функция setModelData, которая вызывается представлением, к которому она присоединена, когда пользователь фиксирует свои изменения; он не вызывается, когда они уничтожают редактор без фиксации.
Следующим трюком будет изучение архитектуры Qt Model/View и исправление библиотеки, чтобы сделать это правильно. Это может даже составить не более чем простое удаление основных заглушек, которые разрушают поведение, которое я пытаюсь получить. Возможно также, что отказ от использования этой системы вместо простого использования QtTreeView может быть лучшим выбором, хотя было бы неплохо сохранить возможность переключения между различными типами браузеров.
3 ответа
Итак, вот половина исправления, которое я придумал:
Я добавил функцию commitItem(QModelIndex) к приватной вещи в TreePropertyBrowser. Затем я вызываю это из делегата, когда вызывается функция setModelData().
Затем он находит свойство, вызывает новую функцию, которую я добавил в AbstractBrowser, чтобы извлечь фабрику для свойства, а затем сообщает фабрике "commitProperty(QtProperty*)".
Эта функция является пустым виртуальным в базе, и в LineEditFactory я перезаписываю ее, чтобы применить изменение свойства, которое генерирует сигнал valueChanged().
После внесения этих изменений пользователь может отказаться от редактирования, нажав клавишу ESC, и я получу уведомление, если они передадут изменение свойства, нажав RETURN, изменение фокуса и т. Д.
На данный момент работает только для древовидной версии. Вероятно, не буду пытаться заставить остальных работать. Фактически, я, вероятно, собираюсь выбросить эту библиотеку и просто использовать QTreeView самостоятельно. Это ведет себя так, как я хочу, эту вещь нужно было взломать, чтобы получить поведение НАЗАД.
О да, вам также нужно удалить соединение с сигналом textChanged() в createEditor() LineEditFactory.
Я столкнулся с этой же проблемой некоторое время назад. Нам нужно было знать, когда редактирование было закончено для любого из редакторов QVariant. Хитрость в том, что фреймворк создает и удаляет свои виджеты при запуске и остановке редактирования. Итак, скрывшись в классах EditorFactory, я подключился к сигналу QObject::destroy практически для каждого создаваемого им типа QWidget и добавил новый сигнал propertyEditFinished, который может поймать основное приложение.
QtPropertyBrowser определенно сумасшедший, но также трудно переопределить все это.
Этот вопрос, вероятно, больше не актуален в Qt 5, которая включает QtPropertyBrowser и его друзей. Я реализовал editingFinished
подайте сигнал для QtLineEditorFactory в соответствии с подходом Тадо, а затем решили, что мне не нужно / не нужно делать это таким образом! Возможно, чтобы избавиться от чувства напрасной траты моего времени, я прилагаю код различий в своем решении на случай, если кто-то посчитает его полезным.
Index: src/qteditorfactory.cpp
===================================================================
--- src/qteditorfactory.cpp (revision 737)
+++ src/qteditorfactory.cpp (working copy)
@@ -1076,7 +1076,6 @@
}
-
/*!
\class QtLineEditFactory
@@ -1094,7 +1093,6 @@
{
d_ptr = new QtLineEditFactoryPrivate();
d_ptr->q_ptr = this;
-
}
/*!
@@ -1121,6 +1119,10 @@
this, SLOT(slotEchoModeChanged(QtProperty *, int)));
connect(manager, SIGNAL(readOnlyChanged(QtProperty*, bool)),
this, SLOT(slotReadOnlyChanged(QtProperty *, bool)));
+
+ // c.s. Added 4/12/2017
+ connect(this, SIGNAL(propertyEditingFinished(QtProperty*, const QString&)),
+ manager, SIGNAL(propertyEditingFinished(QtProperty*, const QString&)));
}
/*!
@@ -1131,7 +1133,6 @@
QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager,
QtProperty *property, QWidget *parent)
{
-
QLineEdit *editor = d_ptr->createEditor(property, parent);
editor->setEchoMode((EchoMode)manager->echoMode(property));
editor->setReadOnly(manager->isReadOnly(property));
@@ -1146,9 +1147,49 @@
this, SLOT(slotSetValue(const QString &)));
connect(editor, SIGNAL(destroyed(QObject *)),
this, SLOT(slotEditorDestroyed(QObject *)));
- return editor;
+
+ // c.s. Added 4/12/2017
+ connect(editor, SIGNAL(editingFinished()), SLOT(handleEditingFinished()));
+ return editor;
}
+
+
+// c.s. Added 4/12/2017
+void QtLineEditFactory::handleEditingFinished()
+{
+ auto keys = d_ptr->m_editorToProperty.keys();
+ QLineEdit *le = qobject_cast<QLineEdit*>(sender());
+ if (!le)
+ return;
+
+ disconnect(le, SIGNAL(editingFinished()), this, SLOT(handleEditingFinished()));
+
+ QtProperty *property = 0;
+
+ const QMap<QLineEdit *, QtProperty *>::ConstIterator ecend =
+ d_ptr->m_editorToProperty.constEnd();
+ for (QMap<QLineEdit *, QtProperty *>::ConstIterator itEditor =
+ d_ptr->m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ {
+ if (itEditor.key() == le)
+ {
+ property = itEditor.value();
+ if (!property)
+ return;
+
+ QtStringPropertyManager *manager = propertyManager(property);
+
+ if (!manager)
+ return;
+
+ QString s = manager->value(property);
+ manager->setValue(property, s); // make sure it has the last value
+ emit propertyEditingFinished(property, s);
+ }
+ }
+}
+
/*!
\internal
@@ -1165,6 +1206,9 @@
disconnect(manager, SIGNAL(readOnlyChanged(QtProperty*, bool)),
this, SLOT(slotReadOnlyChanged(QtProperty *, bool)));
+ // c.s. Added 4/12/2017
+ disconnect(this, SIGNAL(propertyEditingFinished(QtProperty*, const QString&)),
+ manager, SIGNAL(propertyEditingFinished(QtProperty*, const QString&)));
}
// QtDateEditFactory
Index: src/qteditorfactory.h
===================================================================
--- src/qteditorfactory.h (revision 737)
+++ src/qteditorfactory.h (working copy)
@@ -183,6 +183,14 @@
QWidget *createEditor(QtStringPropertyManager *manager, QtProperty *property,
QWidget *parent);
void disconnectPropertyManager(QtStringPropertyManager *manager);
+
+// c.s. Added 4/12/2017
+Q_SIGNALS:
+ void propertyEditingFinished(QtProperty*, const QString&); // signal editing done in line_editor is finished
+
+protected slots:
+ void handleEditingFinished(); // similar to QLineEdit
+
private:
QtLineEditFactoryPrivate *d_ptr;
Q_DECLARE_PRIVATE(QtLineEditFactory)
Index: src/qtpropertymanager.h
===================================================================
--- src/qtpropertymanager.h (revision 737)
+++ src/qtpropertymanager.h (working copy)
@@ -200,6 +200,9 @@
void echoModeChanged(QtProperty *property, const int);
void readOnlyChanged(QtProperty *property, bool);
+ // c.s. Added 4/12/2017
+ void propertyEditingFinished(QtProperty *, const QString &val);
+
protected:
QString valueText(const QtProperty *property) const;
QString displayText(const QtProperty *property) const;