[英]Registering an extension in Qt Designer with no associated widget plugin
TL; DR
我想注冊一個Qt Designer擴展程序,但不想要任何窗口小部件插件,因此下列任何一種都可以解決我的問題:
QDesignerCustomWidgetInterface
情況下注冊擴展? 我正在為Qt Designer開發一組插件。 這些插件向設計人員公開了自定義窗口小部件。 所有小部件(幾十個)都繼承自一個通用類( CCommonWidget
),例如:
CCommonWidget
|-> CLabel
|-> CPushButton
...
CCommonWidget
為所有小部件定義一些通用屬性。 我想通過擴展(例如QDesignerTaskMenuExtension
)將它們公開給Qt Designer。
我從CLabel
插件中的測試開始。 這里有兩種相關的方法:
// Register the extensions in Qt Designer
void CLabelPlugin::initialize(QDesignerFormEditorInterface *formEditor)
{
if (m_initialized) return;
auto extensionManager = formEditor->extensionManager();
Q_ASSERT(extensionManager);
extensionManager->registerExtensions(new CLabelPluginFactory(extensionManager), Q_TYPEID(QDesignerTaskMenuExtension));
m_initialized = true;
}
// The factory creates the menu extension if the widget is a CLabel
QObject* CLabelPluginFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
{
if (iid != Q_TYPEID(QDesignerTaskMenuExtension)) return nullptr;
if (auto label = dynamic_cast<CLabel*>(object))
return new CLabelPluginMenu(label, parent);
return nullptr;
}
它運行得很完美,我打算將這個想法擴展到其余的插件中。 我沒有復制/粘貼代碼,而是從CCommonPlugin
開始的,讓每個人都可以從中繼承代碼。 為了使其盡可能可重用,我將createExtension
方法更改為:
QObject* CCommonPluginFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
{
if (iid != Q_TYPEID(QDesignerTaskMenuExtension)) return nullptr;
if (auto label = dynamic_cast<CCommonWidget*>(object))
return new CCommnPluginMenu(label, parent);
return nullptr;
}
在這里,我意識到,即使僅在插件( CLabelPlugin
)上注冊了擴展工廠,從CCommonWidget
繼承的任何其他小部件也會顯示菜單! (這是很明顯的,一旦我發現它,但是在我沒想到之前)。
現在,由於我不必更改所有插件(數十個),而只是創建一個新的虛擬普通插件 (注冊擴展工廠),因此變得更加容易。
我首先創建的虛擬插件:
class CPluginCommon : public QObject, public QDesignerCustomWidgetInterface {
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
explicit CPluginCommon( QObject* parent=0 );
public: // QDesignerCustomWidgetInterface
QWidget* createWidget( QWidget* parent ) { return nullptr; }
QString group() const { return QString(); }
QIcon icon() const { return QIcon(); }
QString includeFile() const { return QString(); }
bool isContainer() const { return false; }
QString name() const { return QString(); }
QString toolTip() const { return QString(); }
QString whatsThis() const { return QString(); }
virtual bool isInitialized() const override {
return m_initialized;
}
virtual void initialize(QDesignerFormEditorInterface *formEditor) override;
private:
bool m_initialized;
};
但是,在Qt Designer的小部件框中將顯示一個空白小部件。 我不需要空的小部件,我不需要小部件 !
另一個選擇是不使用此類插件,但我正在努力尋找一種無需 QDesignerCustomWidgetInterface
即可注冊擴展的QDesignerCustomWidgetInterface
,但我能找到的就是在QDesignerCustomWidgetInterface::initialize(QDesignerFormEditorInterface *formEditor)
獲得擴展管理器。使用formEditor->extensionManager()
)。
快速回答
要從小部件框中隱藏小部件,只需返回一個空的XML(這是未記錄的功能):
class CPluginCommon : public QObject, public QDesignerCustomWidgetInterface {
// ...
public:
QString domXml() const { return QString(); }
};
回顧Qt Designer插件管理器的代碼,我在QDesignerPluginManagerPrivate::addCustomWidget
方法中發現以下內容( c
是指向QDesignerCustomWidgetInterface
的指針)
const QString domXml = c->domXml();
if (!domXml.isEmpty()) { // Legacy: Empty XML means: Do not show up in widget box.
鑒於此,我看到domXml
的默認實現確實為通用窗口小部件返回了一個很小的XML片段:
virtual QString domXml() const
{
return QString::fromUtf8("<widget class=\"%1\" name=\"%2\"/>")
.arg(name()).arg(name().toLower());
}
為了完整QDesignerCustomWidgetInterface
,據我在Qt Designer插件管理器的源代碼中所見,沒有辦法加載不繼承自QDesignerCustomWidgetInterface
的插件:
// Load plugins into widget database and factory.
void QDesignerIntegration::initializePlugins(QDesignerFormEditorInterface *formEditor)
{
// load the plugins
WidgetDataBase *widgetDataBase = qobject_cast<WidgetDataBase*>(formEditor->widgetDataBase());
if (widgetDataBase) {
widgetDataBase->loadPlugins();
}
if (WidgetFactory *widgetFactory = qobject_cast<WidgetFactory*>(formEditor->widgetFactory())) {
widgetFactory->loadPlugins();
}
if (widgetDataBase) {
widgetDataBase->grabDefaultPropertyValues();
}
}
哪里
void WidgetDataBase::loadPlugins()
{
// ...
// 2) create a list plugins
ItemList pluginList;
const QDesignerPluginManager *pm = m_core->pluginManager();
foreach(QDesignerCustomWidgetInterface* c, pm->registeredCustomWidgets())
pluginList += createCustomWidgetItem(c, pm->customWidgetData(c));
// ...
}
void WidgetFactory::loadPlugins()
{
m_customFactory.clear();
QDesignerPluginManager *pluginManager = m_core->pluginManager();
QList<QDesignerCustomWidgetInterface*> lst = pluginManager->registeredCustomWidgets();
foreach (QDesignerCustomWidgetInterface *c, lst) {
m_customFactory.insert(c->name(), c);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.