如何在Qt中插件和主应用程序之间进行通信?

时间:2015-06-21 05:47:56

标签: c++ qt

我需要让我的绘图板应用程序及其几何图形插件(绘制矩形,圆形等)相互通信: 当加载.so文件时,主应用程序将获得一个具体的工厂来实例图形类和一个按钮(将在主应用程序中加载以表示此图)。单击按钮时,应用程序可以绘制此图。

我愚蠢地实施了这个:

主应用程序有一个QString来识别客户选择的数字。  我在工厂中存储了一个指向此QString的QString *point,并编写如下代码:

QPushButton *CircleFactory::MyButton()
{
    QPushButton *drawCircleBut = new QPushButton;
    drawCircleBut->setIcon(QIcon(":/shape/circle"));
    connect(drawCircleBut, SIGNAL(clicked()), this, SLOT(changeShape()));
    return drawCircleBut;
}

void CircleFactory::changeShape()
{
    *point = ID_LABEL;
}

我相信必须有更好的方法来解决这个问题......请给我一些建议或意见。

2 个答案:

答案 0 :(得分:0)

最简单的解决方案是利用QObject的属性系统:

QPushButton * CircleFactory::MyButton()
{
  QScopedPointer<QPushButton> button(new QPushButton);
  button->setIcon(QIcon(":/shape/circle"));
  button->setProperty("identity", ID_LABEL);
  return button->take();
}

然后,在连接到这些按钮的任何插槽中,您都可以轻松检查其身份;

void Foo::buttonClicked() {
  qDebug() << "clicked on:" << sender()->property("identity");
}

这样就可以避免使用全局变量。

我怀疑按钮是否需要以这种方式识别自己。我担心的是你使用按钮的标识然后以某种方式返回圆圈对象或正确的插件。

相反,圆形工厂应该提供一个已连接到正确插槽的按钮。如果这不可能,您将不得不进一步解释您的&#34;绘图板应用程序的设计和预期功能&#34;。正如您可能想象的那样,这样的应用程序应该如何运作并不明显 - 对您来说显而易见的事情对其他人来说并不明显。

答案 1 :(得分:0)

另一个解决方案是扩展几何图形插件界面,以便只有插件才能知道它们的形状是如何被调用的,以及如果它被表示为QIcon它的样子。应用本身对圆形或矩形一无所知。

#include <QString>

class GeometricPluginInterface
{
public:
   GeometricPluginInterface() {}
   virtual ~GeometricPluginInterface() {}

   virtual QString name() const = 0;
   virtual QIcon icon() const = 0;

};

启动应用程序后,您可以将所有已加载的插件存储在QList中(例如QList<GeometricPluginInterface*> m_plugins;)。 如果您使用按钮填充UI,则可以遍历列表并为每个插件创建QPushButton,并使用从插件本身获得的图标。您可以通过lambda(自C ++ 11)将代码的clicked信号连接到插槽。

foreach (GeometricPluginInterface *plugin, m_plugins) {
   QPushButton *button = new QPushButton;
   button->setIcon(plugin->icon());
   connect(button, &QPushButton::clicked,
           [this, plugin] {
      geometryButtonClicked(plugin->name());
   });
   ui->buttonLayout->addWidget(button);
}

void GeometricPluginInterface::geometryButtonClicked(const QString &geometryName)
{
   qDebug() << "Geometry clicked: " << geometryName;
}