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;
Другие вопросы по тегам