簡體   English   中英

在沒有關聯的窗口小部件插件的Qt Designer中注冊擴展

[英]Registering an extension in Qt Designer with no associated widget plugin

TL; DR

我想注冊一個Qt Designer擴展程序,但不想要任何窗口小部件插件,因此下列任何一種都可以解決我的問題:

  • 如何在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM