Основная задача: создать плагин, динамически его загрузить, в плагине создать виджет и отобразить его на главной форме. На виджете присутствуют элементы управления, на которые надо реагировать в основной программе.
Интерфейс (interfaces.h), содержит интерфейсный класс "Высылателя сигналов" и собственно интерфейс плагина, выглядит так:
class INotifyer : public QObject
{
public:
virtual ~INotifyer() {}
virtual void setFreq(int value) = 0;
virtual void setAver(int value) = 0;
virtual QObject *instance() = 0;
};
class PMInterface
{
public:
virtual ~PMInterface() {} //виртуальный деструктор
virtual QWidget* CreateForm(QWidget *parent) = 0;
virtual INotifyer* notifyer() = 0;
};
Сам плагин содержит прилинкованую форму ui_widget.h, на которой расположены 2 лейбла и 2 спинбокса. В классе плагина реализованы обработчики события изменения содержимого спинбоксов. По наступлению событий высылаются сигналы, которые надо перехватить в основном приложении.
Заголовочник плагина (widget.h)
namespace Ui {
class Widget;
}
class Notifyer : public INotifyer
{
Q_OBJECT
friend class Widget;
public:
virtual QObject *instance() { return this; }
signals:
void setFreq(int value);
void setAver(int value);
};
class Widget : public QWidget, public PMInterface
{
Q_OBJECT
Q_INTERFACES(PMInterface) //и сам интерфейс оживил
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QWidget* CreateForm(QWidget *parent);
INotifyer* notifyer(); /*{
if (!m_Notifyer)
m_Notifyer = new Notifyer();
return m_Notifyer;
}*/
signals:
void setFreq(int value);
void setAver(int value);
public slots:
void on_doubleSpinBox_valueChanged(double arg1);
void on_spinBox_2_valueChanged(int arg1);
private:
Notifyer *m_Notifyer;
Ui::Widget *ui;
};
Реализация (widget.cpp):
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
m_Notifyer = 0;
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
QWidget* Widget::CreateForm(QWidget *parent)
{
QWidget* pForm = new Widget(parent);
pForm->show();
return pForm;
}
void Widget::on_doubleSpinBox_valueChanged(double arg1)
{
emit m_Notifyer->setFreq(arg1);
}
void Widget::on_spinBox_2_valueChanged(int arg1)
{
emit m_Notifyer->setAver(arg1);
}
INotifyer* Widget::notifyer() {
if (!m_Notifyer)
m_Notifyer = new Notifyer();
return m_Notifyer;
}
Q_EXPORT_PLUGIN2(PMPlugin, Widget)
Есть классическая загрузка:
QDir dir(qApp->applicationDirPath ());
dir.cdUp();
dir.cd("plugins");
QPluginLoader loader(dir.absoluteFilePath(dir.entryList(QDir::Files).at(0)));
QObject *pl=loader.instance();
PMInterface *pi=qobject_cast<PMInterface *>(pl);
if (!pi)
{
QMessageBox::critical(this,"ERRor",loader.errorString());
qApp->exit();
}
pi->CreateForm(ui->widget);
QObject* notif = pi->notifyer();
connect(notif,SIGNAL(setAver(int)),SLOT(SetAver(int)));
connect(notif,SIGNAL(setFreq(int)),SLOT(SetFreq(int)));
Всё бы хорошо и плагин подгружается и виджет на форме появляется и сигналы со слотами соединяются, но при изменении содержимого спинбоксов, я вываливаюсь в какой-то совершенно посторонний экземпляр класса Widget, где notif = 0 и соответственно выслать сигнал не получается. Голову сломал, не могу найти косяк...