QtPropertyBrowser и значение измененных сигналов - PullRequest
6 голосов
/ 17 декабря 2010

Я использую библиотеку Qt Property Browser в качестве редактора записей.Когда пользователь завершит редактирование какого-либо данного поля, удалив фокус с элемента редактирования или нажав клавишу ввода, я хочу получить информацию об этом, чтобы я мог принять изменение, обработать его и отправить в РЕАЛЬНОЕизменяемый элемент.

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

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

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


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

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


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

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

Ответы [ 3 ]

4 голосов
/ 18 декабря 2010

Итак, вот половинчатое исправление, которое я придумал:

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

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

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

После внесения этих изменений пользователь может отказаться от редактирования, нажав клавишу ESC, и я получаю уведомление, если они фиксируют изменение свойства, нажимая RETURN, изменение фокуса и т. Д. *

Работает только длядревовидная версия на данный момент.Вероятно, не буду пытаться заставить остальных работать.Фактически, я, вероятно, собираюсь выбросить эту библиотеку и просто использовать QTreeView самостоятельно.Это ведет себя так, как я хочу, эта штука должна быть взломана, чтобы получить поведение НАЗАД.

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

1 голос
/ 18 апреля 2017

Этот вопрос, вероятно, больше не актуален в 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;
1 голос
/ 15 июня 2011

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

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

...