我正在使用Qt Property Browser库作为记录编辑器。当用户完成对任何给定字段的编辑时,通过从编辑项目中删除焦点或按回车键,我希望被告知这一点,以便我可以进行更改,处理它并将其发送到REAL正在改变的项目。
不幸的是,我似乎只能找到propertyChanged和valueChanged信号,并且每次添加或删除任何数量的文本时都会触发它们,而不仅仅是在用户触发完成时。
如果无法获得此通知,我看不出它是如何成为可用组件的。当用户点击[ESC]时它甚至不会恢复,我当然需要能够实现!当然,我绝对没有做出我需要的信号,但我肯定找不到它。
有人知道吗?
在检查源代码后,制作行编辑器工厂的人做出了与textEdited连接而不是编辑完成的不幸决定。改变是一件相对简单的事情,除非有条理地使得扩展这个具有可扩展接口的编辑器工厂变得不可能!
所有我需要做的是覆盖createEditor函数,断开连接错误,连接更好的连接与之间的调用以从字符串编辑控件中获取字符串。但不是!!!我们不会让你那样做!我们将把所有会计资料放在一个你无法访问或调用的私有类中,而那些我们打算让你调用的部分将与它们被调用它们的事实紧密联系在一起。编辑控件,而不是其他任何东西。 ERGO,我们非常有效地让生活变得令人沮丧,我们无法想象。我们不是很棒吗?
我发现了更多。这些对象的标准Qt方法使用委托来控制我想要获得的行为。 Qt属性库会覆盖此行为并执行其他不是我正在尝试完成的操作。 QAbstractItemDelegate接口内部是一个setModelData函数,当用户提交其编辑时,它被附加到的视图调用;如果他们在没有提交的情况下销毁编辑器,就不会调用它。
下一个技巧是学习Qt模型/视图架构并修补库以正确的方式完成。这甚至可能只是简单地删除了破坏我试图获得的行为的重写存根。也许放弃使用这个系统代替简单地使用QtTreeView可能是一个更好的选择,尽管能够保留在不同类型的浏览器之间切换的能力会很好。
答案 0 :(得分:4)
所以,这是我提出的半屁股修复:
我在TreePropertyBrowser中的私有事件中添加了“commitItem(QModelIndex)”函数。然后我在调用setModelData()函数时从委托调用它。
然后找到该属性,调用我添加到AbstractBrowser的新函数来获取属性的工厂,然后告诉工厂“commitProperty(QtProperty *)”。
此函数在基数处为空虚拟,在LineEditFactory中我覆盖它以应用属性更改,从而生成valueChanged()信号。
通过这些更改,用户可以通过按ESC键退出编辑,如果他们通过点击RETURN,焦点更改等提交属性更改,我会收到通知。
目前仅适用于树版本。可能不会费心去完成剩下的工作。事实上,我可能会抛弃这个库,只是自己使用QTreeView。它的行为方式与我想要的一样,这件事必须被黑客攻击才能让行为回归。
哦,是的,您还必须删除LineEditFactory的createEditor()中与textChanged()信号的连接。
答案 1 :(得分:1)
前一段时间我遇到了同样的问题。我们需要知道任何QVariant编辑器何时完成编辑。诀窍是框架在您开始和停止编辑时创建和删除其小部件。所以,埋在EditorFactory类中,我连接到它创建的每个QWidget类型的QObject :: destroyed信号,并冒出一个新的propertyEditFinished信号,主应用程序可以捕获。
QtPropertyBrowser绝对是疯狂的,但重新实现整个事情也是一种痛苦。
答案 2 :(得分:1)
这个问题在Qt 5中已经不再适用于QtPropertyBrowser和朋友。我在Thadeaux's approach的行中为QtLineEditorFactory实现了editingFinished
信号,然后决定我不需要/想要这样做!也许为了减轻浪费时间的感觉,我附上了我的解决方案的代码差异,以防有人觉得它有用。
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;