gpt4 book ai didi

c++ - 在没有关联的小部件插件的情况下在 Qt Designer 中注册扩展

转载 作者:行者123 更新时间:2023-11-28 01:42:42 25 4
gpt4 key购买 nike

长话短说

我想注册一个 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 的widget 框中显示了一个空白的widget。我不想要一个空的小部件,我想要没有小部件!

另一种选择是不使用这些类型的插件,但我正在努力寻找一种方法来注册扩展没有 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());
}

为了完整起见,据我在 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);
}
}

关于c++ - 在没有关联的小部件插件的情况下在 Qt Designer 中注册扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46524285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com