Qtpropertybrowser и сигналы изменения значения

Я использую библиотеку браузера свойств Qt в качестве редактора записей. Когда пользователь завершил редактирование любого поля, удалив фокус из элемента редактирования или нажав клавишу enter, я хочу быть проинформирован об этом, чтобы я мог принять изменение, обработать его и отправить его в реальный элемент, который изменяется.

к сожалению, я, кажется, только в состоянии найти propertyChanged и valueChanged сигналы, и они срабатывают каждый раз, когда любое количество текста добавляется или удаляется, а не только когда пользователь запускает finish.

Не имея возможности получить это уведомление, я не вижу, как это может быть полезным компонентом. Он даже не возвращается, когда пользователь нажимает [ESC], который мне, безусловно, нужно иметь возможность реализовать! Конечно, я ошибаюсь насчет того, что нет абсолютно никакого сигнала, который делает то, что мне нужно, но я точно не могу его найти.

кто-нибудь знает?


после изучения исходного кода, люди, которые сделали редактор строки завод принял неудачное решение подключиться к textEdited, а не editingfined. Было бы относительно просто изменить, за исключением того, что довольно методично сделал невозможным расширение этой фабрики редактора, которая имеет расширяемый интерфейс!

все, что мне нужно сделать, это переопределить функцию createEditor, отключить плохое соединение, подключить лучшее соединение с вызовом между ними, чтобы получить строку из элемента управления редактирования строки. Но нет!!! Мы не я позволю тебе это сделать! Мы собираемся поместить все бухгалтерские материалы в частный класс, к которому вы не можете получить доступ или позвонить, и те части, которые мы позволим вам позвонить, будут тесно связаны с тем, что они вызываются элементом управления редактированием, а не чем-либо еще. Следовательно, мы сделали жизнь настолько невыносимо невозможной, насколько могли себе представить. Разве мы не гениальны?


Я узнал больше. Стандартный подход Qt для этих видов объекты используют делегаты для управления поведением, которое я пытаюсь получить. Библиотека свойств Qt переопределяет это поведение и делает что-то еще, что я не пытаюсь выполнить. Внутри интерфейса QAbstractItemDelegate находится функция setModelData, вызываемая представлением, к которому она прикреплена, когда пользователь фиксирует свои изменения; она не вызывается, когда они уничтожают редактор без фиксации.

следующим трюком будет изучение архитектуры Qt Model/View и латаю библиотеку, чтобы сделать все правильно. Это может быть даже не больше, чем просто удаление переопределяющих заглушек, которые разрушают поведение, которое я пытаюсь получить. Возможно также, что отказ от использования этой системы вместо простого использования QtTreeView может быть лучшим выбором, хотя было бы неплохо сохранить возможность переключения между различными видами браузера.

3 ответов


Итак, вот уже пол-задницы исправить я придумал:

Я добавил функцию" commitItem(QModelIndex) " к частной вещи в TreePropertyBrowser. Затем я вызываю это из делегата, когда вызывается функция setModelData ().

Это затем находит свойство, вызывает новую функцию, которую я добавил в AbstractBrowser, чтобы получить фабрику для свойства, а затем сообщает фабрике "commitProperty(QtProperty*)".

эта функция является пустой виртуальной в base и в LineEditFactory я переопределяю его, чтобы применить изменение свойства, которое генерирует сигнал valueChanged ().

с этими изменениями на месте пользователь может выйти из редактирования, нажав клавишу ESC,и я получаю уведомление, если они совершают изменение свойства, нажав RETURN, focus changing и т. д...

работает только для версии дерева на данный момент. Вероятно, не пытайся заставить остальных работать. На самом деле я скорее всего выброшу эту библиотеку. и просто используйте QTreeView сам. Он ведет себя так, как я хочу, эта вещь должна была быть взломана uber, чтобы вернуть поведение.

О да, вы также должны удалить соединение с сигналом textChanged () в createEditor () LineEditFactory.


Я столкнулся с этой же проблемой некоторое время назад. Нам нужно было знать, когда редактирование было закончено для любого из редакторов QVariant. Фокус в том, что платформа создает и удаляет свои виджеты при запуске и остановке редактирования. Итак, похороненный в классах EditorFactory, я подключился к QObject:: destroyed signal очень Каждый тип QWidget, который он создает, и пузырился новый сигнал propertyEditFinished, который может поймать основное приложение.

QtPropertyBrowser определенно сумасшедший, но это также больно все переосмысливать.


этот вопрос, вероятно, больше не актуален в Qt 5, который включил QtPropertyBrowser и friends. Я реализовал editingFinished сигнал для QtLineEditorFactory по строкам Thadeaux это, а затем решил, что мне не нужно / хочу делать это таким образом! Возможно, чтобы успокоить чувство потери времени, я прилагаю кодовое различие моего решения на случай, если кто-то сочтет его полезным.

    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;