Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: HirurG. от Декабря 09, 2013, 15:43



Название: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 09, 2013, 15:43
Здравствуйте! У меня возникла задача переделать приложение, написанное с помощью Qt в библиотеку dll, которую можно было бы использовать в другом (не использующем Qt) проекте.
Другими словами, у меня есть класс, унаследованный от QWidget с интерфейсом приложения и некоторыми рабочими свойствами и  методами. Разработка ведётся в Microsoft Visual Studio 2010 + Qt Add-In (Qt 4.8.3).  Мастер создания Qt Library создаёт код, но я не совсем понимаю как с ним работать дальше и куда "прилепить" мой QWidget, чтобы потом можно было использовать его методы из экспортируемых функций.
Если кто-то сталкивался с похожей задачей и знает возможные пути решения буду признателен за подсказки.

P.S. не уверен насчёт правильного выбора раздела, но наверное это всё-таки относится к GUI


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Bepec от Декабря 09, 2013, 20:39
Поищи по форуме 2-4 темы уже было, одну создавал я. Там и примеры есть.


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Igors от Декабря 09, 2013, 20:56
но я не совсем понимаю как с ним работать дальше и куда "прилепить" мой QWidget, чтобы потом можно было использовать его методы из экспортируемых функций.
Да никуда в "не Qt приложении" т.к. использование QWidget предполагает наличие запущенного QApplication, которого нет в хосте без Qt.

Поищи по форуме 2-4 темы уже было, одну создавал я. Там и примеры есть.
Аккуратнее, юноша, не вводите человека в заблуждение  :)

Сам сейчас сращиваю "не Qt приложение" с "Qt окнами/диалогами", были позывы даже написать статейку - но здравый смысл победил  :)


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Old от Декабря 09, 2013, 21:30
Да никуда в "не Qt приложении" т.к. использование QWidget предполагает наличие запущенного QApplication, которого нет в хосте без Qt.
А в чем проблема создать экземпляр QApplication?


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Igors от Декабря 09, 2013, 21:41
А в чем проблема создать экземпляр QApplication?
Во многом

1)  Иметь возможность модифицировать хост
2)  Отследить чтобы экземпляр не изгадил меню - ну спасибо есть флаг macPlugin - но он не все решает
3) Синхронизировать события - капитальный геморрой

Хотя все это порешал - мечтаю когда текущая работа закончится, и смогу сделать хост нормальным Qt приложением


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Old от Декабря 09, 2013, 21:47
Во многом
А ну да, вы как всегда ваш частный случай обобщили на всех. :)

1)  Иметь возможность модифицировать хост
Это не обязательно.

2)  Отследить чтобы экземпляр не изгадил меню - ну спасибо есть флаг macPlugin - но он не все решает
В каком смысле "экземпляр не изгадил меню"? Экземпляр чего может изгадить меню и до какой степени?

3) Синхронизировать события - капитальный геморрой
Синхронизировать между чем и чем?


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Bepec от Декабря 09, 2013, 22:11
Igors что вы ответите на работоспособную dll в не Qt приложении? Я зря что ли тут просиживал полмесяца и она у меня не работает, а так - притворяется? :D


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 10, 2013, 08:49
спасибо за отклики! в поиске нашёл только вот этот (http://www.prog.org.ru/index.php?topic=24492.msg174106;topicseen (http://www.prog.org.ru/index.php?topic=24492.msg174106;topicseen)) вариант. попытался реализовать его у себя - не компилится. может быть кто-нибудь поможет собрать минимальный работающий пример, чтобы можно было его дальше допиливать?
во вложении прикрепил свой "велосипед"


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Johnik от Декабря 10, 2013, 10:26
Цитировать
не компилится
что выдает?

Код:
private:
    Ui::SimpleWidgetDLL *ui;

это где описано?


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 10, 2013, 10:34
Цитировать
не компилится
что выдает?
кучу всего выдаёт:
Ошибка   3   error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   17
Ошибка   17   error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   17
Ошибка   12   error C2653: QDialog: не является именем класса или пространства имен   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   30
Ошибка   13   error C2653: QDialog: не является именем класса или пространства имен   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   35
Ошибка   26   error C2653: QDialog: не является именем класса или пространства имен   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   30
Ошибка   27   error C2653: QDialog: не является именем класса или пространства имен   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   35
Ошибка   1   error C2504: QDialog: не определен базовый класс   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   12
Ошибка   15   error C2504: QDialog: не определен базовый класс   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   12
Ошибка   10   error C2228: выражение слева от ".size" должно представлять класс, структуру или объединение   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   24   error C2228: выражение слева от ".size" должно представлять класс, структуру или объединение   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   2   error C2143: синтаксическая ошибка: отсутствие ";" перед "public"   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   17
Ошибка   16   error C2143: синтаксическая ошибка: отсутствие ";" перед "public"   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   17
Ошибка   5   error C2065: QList: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   23
Ошибка   19   error C2065: QList: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   23
Ошибка   7   error C2065: l: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   24
Ошибка   9   error C2065: l: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   21   error C2065: l: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   24
Ошибка   23   error C2065: l: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   11   error C2065: endl: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   25   error C2065: endl: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   8   error C2065: cout: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   22   error C2065: cout: необъявленный идентификатор   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   25
Ошибка   6   error C2062: тип "int" не требуется   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   23
Ошибка   20   error C2062: тип "int" не требуется   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   23
Ошибка   4   error C2061: синтаксическая ошибка: идентификатор "QWidget"   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   18
Ошибка   18   error C2061: синтаксическая ошибка: идентификатор "QWidget"   d:\projects\qt\examples\simplewidgetdll\simplewidgetdll\simplewidgetdll.h   18
Ошибка   14   error C1189: #error :  "The header file 'simplewidgetdll.h' doesn't include <QObject>."   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\GeneratedFiles\Debug\moc_simplewidgetdll.cpp   12
Ошибка   28   error C1083: Не удается открыть файл включение: QApplication: No such file or directory   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\simplewidgetdll.cpp   2


Цитировать
Код:
private:
    Ui::SimpleWidgetDLL *ui;
это где описано?
не совсем понял вопроса. я писал по аналогии с примером по ссылке выше, там было
Код:
private:
    Ui::Editor *ui;


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Johnik от Декабря 10, 2013, 10:40
Код:
private:
    Ui::SimpleWidgetDLL *ui;
такой код как правило генерирует QtDesigner, предполагаю, что интерфейс в примере, за основу который вы взяли, нарисован именно в designer'е

Цитировать
кучу всего выдаёт:
не пробовали сами ошибки исправлять? они элементарные, не включен файл, например...


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 10, 2013, 10:47
Цитировать
не пробовали сами ошибки исправлять? они элементарные, не включен файл, например...
конечно пробовал, но даже при добавлении #include <qDialog> начинает ругаться на эту строчку. Я не могу понять, почему qDialog.h не находится и возникает мысль, что я ошибся где-то раньше, но не знаю где.


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 10, 2013, 11:09
В общем почистил проект. Стало немного яснее, но всё равно компилятор ругается на заголовок функции
Код:
extern "C" WindowInterface* SIMPLEWIDGETDLL_EXPORT createInterface()
{
    int argc = 0;
    char **argv = 0;
    if(QApplication::instance() == 0)
        new QApplication(argc, argv);
 
    return new SimpleWidget;
}
пишет
error C2059: синтаксическая ошибка: __declspec(dllexport)   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\SimpleWidget.cpp   4

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


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Johnik от Декабря 10, 2013, 11:30
заменить (SimpleWidget.h):
Код:
extern "C" WindowInterface* SIMPLEWIDGETDLL_EXPORT createInterface();
на
Код:
extern "C" SIMPLEWIDGETDLL_EXPORT WindowInterface* createInterface();

заменить (SimpleWidget.cpp):
Код:
WindowInterface* SIMPLEWIDGETDLL_EXPORT createInterface()
на
Код:
WindowInterface* createInterface()


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 10, 2013, 11:38
заменить (SimpleWidget.h):
Код:
extern "C" WindowInterface* SIMPLEWIDGETDLL_EXPORT createInterface();
на
Код:
extern "C" SIMPLEWIDGETDLL_EXPORT WindowInterface* createInterface();

заменить (SimpleWidget.cpp):
Код:
WindowInterface* SIMPLEWIDGETDLL_EXPORT createInterface()
на
Код:
WindowInterface* createInterface()
спасибо! но теперь сыпет кучу ошибок "ссылка на неразрешённый внешний символ..." в файлах SimpeWidjet.obj и moc_SimpeWidjet.obj


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Johnik от Декабря 10, 2013, 11:59
не знаю как там в студии, но в QtCreator собралось нормально

и опять же, какой символ неразрешённый?


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 10, 2013, 12:03
там список из 65 пунктов, вот начало:
Предупреждение   1   warning MSB8012: TargetPath(D:\projects\Qt\Examples\SimpleWidgetDLL\Win32\Debug\simpleWidget.dll) не соответствует значению свойства выходного файла (D:\projects\Qt\Examples\SimpleWidgetDLL\Win32\Debug\SimpleWidgetDLL.dll) для Linker. Это может привести к неправильному построению проекта. Чтобы исправить это, убедитесь, что значения свойств $(OutDir), $(TargetName) и $(TargetExt) соответствуют значению, указанному в %(Link.OutputFile).   C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets   990
Предупреждение   2   warning MSB8012: TargetName(simpleWidget) не соответствует значению свойства выходного файла (SimpleWidgetDLL) для Linker. Это может привести к неправильному построению проекта. Чтобы исправить это, убедитесь, что значения свойств $(OutDir), $(TargetName) и $(TargetExt) соответствуют значению, указанному в %(Link.OutputFile).   C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets   992
Ошибка   3   error LNK2019: ссылка на неразрешенный внешний символ "__declspec(dllimport) public: void __thiscall QWidget::show(void)" (__imp_?show@QWidget@@QAEXXZ) в функции "public: virtual void __thiscall SimpleWidget::show(void)" (?show@SimpleWidget@@UAEXXZ)   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\moc_SimpleWidget.obj
Ошибка   66   error LNK2019: ссылка на неразрешенный внешний символ "__declspec(dllimport) public: void __thiscall QWidget::setWindowTitle(class QString const &)" (__imp_?setWindowTitle@QWidget@@QAEXABVQString@@@Z) в функции "public: void __thiscall Ui_SimpleWidget::retranslateUi(class QWidget *)" (?retranslateUi@Ui_SimpleWidget@@QAEXPAVQWidget@@@Z)   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\SimpleWidget.obj
Ошибка   65   error LNK2019: ссылка на неразрешенный внешний символ "__declspec(dllimport) public: void __thiscall QWidget::resize(int,int)" (__imp_?resize@QWidget@@QAEXHH@Z) в функции "public: void __thiscall Ui_SimpleWidget::setupUi(class QWidget *)" (?setupUi@Ui_SimpleWidget@@QAEXPAVQWidget@@@Z)   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\SimpleWidget.obj
Ошибка   5   error LNK2019: ссылка на неразрешенный внешний символ "__declspec(dllimport) public: virtual void * __thiscall QWidget::qt_metacast(char const *)" (__imp_?qt_metacast@QWidget@@UAEPAXPBD@Z) в функции "public: virtual void * __thiscall SimpleWidget::qt_metacast(char const *)" (?qt_metacast@SimpleWidget@@UAEPAXPBD@Z)   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\moc_SimpleWidget.obj
Ошибка   6   error LNK2019: ссылка на неразрешенный внешний символ "__declspec(dllimport) public: virtual int __thiscall QWidget::qt_metacall(enum QMetaObject::Call,int,void * *)" (__imp_?qt_metacall@QWidget@@UAEHW4Call@QMetaObject@@HPAPAX@Z) в функции "public: virtual int __thiscall SimpleWidget::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@SimpleWidget@@UAEHW4Call@QMetaObject@@HPAPAX@Z)   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\moc_SimpleWidget.obj
Ошибка   18   error LNK2019: ссылка на неразрешенный внешний символ "__declspec(dllimport) public: virtual __thiscall QWidget::~QWidget(void)" (__imp_??1QWidget@@UAE@XZ) в функции "public: virtual __thiscall SimpleWidget::~SimpleWidget(void)" (??1SimpleWidget@@UAE@XZ)   D:\projects\Qt\Examples\SimpleWidgetDLL\SimpleWidgetDLL\SimpleWidget.obj



Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Johnik от Декабря 10, 2013, 12:09
а добавили нужные пункты конфига Qt (в частности gui, widgets) в студии?


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Igors от Декабря 10, 2013, 12:33
1)  Иметь возможность модифицировать хост
Это не обязательно.
Если необязательно (создавать QApplication в плагине), то только модальные окна

В каком смысле "экземпляр не изгадил меню"? Экземпляр чего может изгадить меню и до какой степени?
До полной. В OSX приложение ставит свой меню бар когда активируется (одно меню вверху для всех). Когда QApplication создается, оно выставляет свой бар


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: HirurG. от Декабря 10, 2013, 12:56
Ну уже что-то вырисовывается (во всех смыслах :) ). Видимо я забыл при создании проекта включить чекбокс GUI library. Создал новый проект, где всё компилится, но опять проблема  :(
QWidget (а точнее его рамка) рисуется, но кнопка, которую я разместил внутри для примера, не видна.
В общем, пока буду разбираться. Если есть что добавить, пишите, пожалуйста.


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Old от Декабря 10, 2013, 14:28
только модальные окна
Ну так большего и не надо.
Для чего держать постоянно открытым окно, которое хостовому приложению совершенно не нужно и он не знает, что с ним делать?


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Igors от Декабря 10, 2013, 14:44
только модальные окна
Ну так большего и не надо.
Для чего держать постоянно открытым окно, которое хостовому приложению совершенно не нужно и он не знает, что с ним делать?
Ну плюсы и минусы модальности всем известны. Самое интересное что и немодальное окно отрабатывает успешно, хотя QAppliation::exec НЕ вызывается  :)


Название: Re: Создание библиотеки dll c GUI на Qt.
Отправлено: Old от Декабря 10, 2013, 14:57
Самое интересное что и немодальное окно отрабатывает успешно
Ну и что? Для чего оно нужно без поддержки хоста?

хотя QAppliation::exec НЕ вызывается  :)
Не обязательно запускать QAppliation::exec, что бы обслуживать очередь сообщений.