Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Гурман от Июня 02, 2011, 20:12



Название: Плагин из приложения.
Отправлено: Гурман от Июня 02, 2011, 20:12
Есть некое приложение, нельзя сказать чтобы совсем маленькое, тысяч 30 строк. У него есть свое MainWindow:QMainWindow, в котором есть кучка "подокон", меню, тулбар и т.д. Теперь надо из этого приложения сделать плагин, чтобы его можно было подключать к другому приложению. Вот пока в раздумьях, как это лучше всего реализовать... Переписывать приложение, отказываться от MainWindow не с руки, это самый долгий путь, а время дорого. Поэтому вопрос - как поддержка плагинов в Qt 4.7 относится к тому, что в плагине может быть свое MainWindow? Допустимо ли это? Окно плагина обязательно должно присутствовать на экране одновременно с окном основного приложения (в частности, чтобы их можно было легко разнести на 2 монитора). Поэтому нельзя использовать окно основного приложения для размещения подокон плагина, да и технически это выглядело бы очень непросто.

Есть, конечно, вариант сделать общение между приложениями через IP, у такого варианта есть свои преимущества. Но есть и недостатки, причем более низкая скорость - самый существенный.

Кто какие идеи может подать? Принимаются к обсуждению любые варианты.


Название: Re: Плагин из приложения.
Отправлено: LisandreL от Июня 02, 2011, 21:26
При желании QMainWindow (и его наследников) можно использовать как обычные виджеты. Можно его вообще встроить в новое главное окно, как обычный виджет. Ну и как обычное окно тоже можно.


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 02, 2011, 21:49
a-ha... тогда должно все просто сразу заработать...


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 03, 2011, 13:25
BTW, начал проектировать, и вспомнилось - эх, а как хорошо было придумано в ОС BeOS... там приложение целиком можно было встраивать в другое приложение, и имелся механизм общения между приложениями, или внутри приложений, очень похожий на сигнал-слоты Qt, причем легко автоматизировалось встраивание и соединение приложений

то есть, например, делаешь Часы - они сами по себе работают на десктопе, но их можно перетащить (или скопировать) в окно, например редактора текстов - они становятся встроенными в редактор, и при клике на часы, например, передают текущее время в текст


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 06, 2011, 19:51
up

не выходит каменный цветок...

описан класс интерфейса:

Код:
class QApplication;

class _interface
{
public:
    virtual ~_interface();
    virtual void start_plugin( QApplication* );
};

Q_DECLARE_INTERFACE( _interface, "ru.home.plugin._interface/1.5")

объевлен такой класс:

Код:
#include <QObject>
#include "_interface.h"

class QApplication;

class main_plugin : public QObject, public _interface {
    Q_OBJECT
    Q_INTERFACES( _interface )

public:
    virtual ~main_plugin(){}
    virtual void start_plugin( QApplication * );
};

далее в коде реализации класса следующее (необходимые инклюды все на месте):

Код:
MainWindow *glpMainWindow;
void main_plugin::start_plugin( QApplication* a )
{
    glpMainWindow = new MainWindow( a );
    glpMainWindow->show();
    return;
}

Q_EXPORT_PLUGIN2( _interface, main_plugin )

начало .pro

Код:
TARGET = CI_FED15
TEMPLATE = lib
CONFIG += plugin dll

дальше в .pro все тоже самое, что было для самостоятельного бинариника

в результате получаю при сборке кучу ошибок типа vtable not found...

надо заметить, что пытаюсь собрать со статической версией Qt, в надежде, что в плагин будут включены нужные функции из QtGui и QtCore (больше ничего в нем не испольузется) - ну и потому, что статический Qt сейчас настроен и используется, приложение собиралось статически и все работало

может я перемудрил, и плагины в принципе работают только в варианте динамической сборки? кто-нибудь что-то подобное делал?




Название: Re: Плагин из приложения.
Отправлено: Mikhail от Июня 07, 2011, 07:24
Есть такое понятие как статические плагины.
И нормально работают.
Их надо откомпилировать статически, подключить в проектном файле, а затем например в main.cpp
импортировать.
Например так:

#ifdef STATICPLUGIN
#include <QtPlugin>
Q_IMPORT_PLUGIN(qPFilesBD)
Q_IMPORT_PLUGIN(qPCommunicationsPlugin)
Q_IMPORT_PLUGIN(qPTimersPlugin)
#endif


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 07, 2011, 12:42
может стоит и статическим этот плагин сделать, однако пока не понятно, в чем проблема при его сборке

и что-то я недопонял, что такое "статический плагин" - это плагин, который всегда должен быть, без него приложение не загрузится для выполнения? или как это?

у меня плагин делается из приложения, причем может быть его 2 варианта - инженерный, используется заказчиком, включает всякие средства, нужные для разработки, или поставочный, его заказчик будет поставлять своим клиентам, там эти средства будут отсутствовать, то есть, в инженерной версии должна быть одна dll, а в поставочной одноименная, с такими же интерфейсами, но внутри другая - такой плагин может быть статическим?

и еще при этом надо иметь возможность собирать по-старому самостоятельное приложение, причем статической сборкой с Qt... такой вот пирожок

ЗЫ: с динамическими библиотеками Qt получилось собрать .dll плагина, теперь надо посмотреть, как он будет вызываться...


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 07, 2011, 15:53
не работает... все собирается, плагин ложится куда надо, приложение собирается, сделал в нем загрузку плагина по Шлее,

Код:
    QDir dir( QApplication::applicationDirPath() );
    QPluginLoader PluginLoader( dir.absoluteFilePath("pluginapp.dll") );
    QObject* pluginapp = qobject_cast<QObject*>( PluginLoader.instance() );

pluginapp == NULL...  :(

куда копать, не понятно...



Название: Re: Плагин из приложения.
Отправлено: BRE от Июня 07, 2011, 15:59
куда копать, не понятно...
Что вернет этот метод?
QString QPluginLoader::errorString () const


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 07, 2011, 16:03
возвращает "Unknown error"  ???

поле PluginLoader->did_load == false, все остальные поля == NULL


Название: Re: Плагин из приложения.
Отправлено: BRE от Июня 07, 2011, 16:11
возвращает "Unknown error"  ???
В каком месте ты вызываешь этот метод?


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 07, 2011, 16:16
Код:
    QDir dir( QApplication::applicationDirPath() );
    QPluginLoader PluginLoader( dir.absoluteFilePath("CI_FED15.dll") );
    QString errstr = PluginLoader.errorString();
    QObject* CI_FED = qobject_cast<QObject*>( PluginLoader.instance() );

если так

Код:
    QDir dir( QApplication::applicationDirPath() );
    QPluginLoader PluginLoader( dir.absoluteFilePath("CI_FED15.dll") );
    QObject* CI_FED = qobject_cast<QObject*>( PluginLoader.instance() );
    QString errstr = PluginLoader.errorString();

тоже самое

проверил, файл плагина доступен по маршруту, все нормально, но плагин почему-то не грузится


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 07, 2011, 20:50
cделал еще один плагин, пустышку, точно по Шлее - не работает, та же беда, не грузится, ошибка неизвестна...  :(

попытался так:

Код:
    a->addLibraryPath( a->applicationDirPath() );
    QPluginLoader PluginLoader( "EmptyPlugin.dll" /*abspath*/ );
    QObject* CI_FED = qobject_cast<QObject*>( PluginLoader.instance() );

эффект тот же

тупик...


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 07, 2011, 22:45
выяснил, что не устанавливается имя плагина

Код:
    QPluginLoader PluginLoader( "EmptyPlugin.dll" );
    // или
    QPluginLoader PluginLoader();
    PluginLoader.setFileName( "EmptyPlugin.dll" );
    QString plugname = PluginLoader.fileName();

plugname == NULL, бред какой-то...  ???


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 08, 2011, 16:30
перепробовал разные способы задать PluginLoader имя файла плагина - и с полным маршрутом напрямую, и с разными наклонами слэша и всяко разно - не берет имя ни в какую

буду писать багрепорт, но хорошо бы, чтобы кто-нибудь тоже проверил


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 08, 2011, 17:19
Фухх... нашел в чем проблема. Из-за интерференции статической и динамической версий Qt, если проекты в разных каталогах, пришлось ранее склеить ветки проектов вместе. И у выполнимого файла в настройках проекта осталась настройка Qt in PATH, а это статический. Заметил только что, приложение слишком большого размера собирается. Переключил на динамический - все заработало. И плагин, сделанный из приложения, тоже заработал.


Название: Re: Плагин из приложения.
Отправлено: iks от Июня 11, 2011, 09:38
Сегодня ответил на подобное http://www.prog.org.ru/index.php?topic=18321.msg124013#new может пригодится


Название: Re: Плагин из приложения.
Отправлено: Гурман от Июня 12, 2011, 16:17
посмотрим... пока что все получилось и вопросов на эту тему нет