Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: far-far от Ноябрь 13, 2009, 14:50



Название: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: far-far от Ноябрь 13, 2009, 14:50
Подскажите, решал ли кто-нибудь задачу: внедрение окна одного приложения внутрь другого. Нужно что-то подобное ActiveX, только мультиплатформенное.
Исходная задача такая. Есть "Главная программа" на подобие Eclipse, она должна для каждого вида документа запускать дочерние программы для просмотра/редактирования. При этом окна дочерних программ должны располагаться в пределах окна "Главной программы". И "Главная программа" и дочерние пишутся на QT.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: whirlwind от Ноябрь 13, 2009, 15:26
http://qt.nokia.com/doc/4.5/plugins-howto.html

Создать плагин с двумя методами. Один метод просто возвращает список поддерживаемых расширений файлов. Второй получает имя файла и отдает *QWidget -- окно с открытым файлом

Основная программа просто получает окна-виджеты и располагает их как надо.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: jack_r от Ноябрь 13, 2009, 15:40
Я пытался найти решение такой задачи, но не нашел непосредственного решения. Поэтому я применил те средства, что есть у Qt. Для этого в одно приложении я добавил контейнер для хранения окна внедряемого приложения. А на основе внедряемого приложения создал виджет. В моем случае на основе библиотек внедряемого приложения. И затем просто отображал в контейнере главного приложения виджет встраиваемого приложения. Контейнером может быть что угодно, в вашем случае подойдет QMdiArea.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: far-far от Ноябрь 13, 2009, 15:40
Согласен, можно использовать Qt-plugin. Возможно так и сделаю. Однако по Т.З. дочерние программы должны существовать в виде отдельных приложений, что бы их можно было независимо, от главного приложения, запускать. При использовании Qt-plugin придется реализовать всю функциональность в plugin, который будет одновременно использоваться и в главном приложении и в дочернем, которое будет просто обёрткой.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: far-far от Ноябрь 13, 2009, 15:49
Я пытался найти решение такой задачи, но не нашел непосредственного решения. Поэтому я применил те средства, что есть у Qt. Для этого в одно приложении я добавил контейнер для хранения окна внедряемого приложения. А на основе внедряемого приложения создал виджет. В моем случае на основе библиотек внедряемого приложения. И затем просто отображал в контейнере главного приложения виджет встраиваемого приложения. Контейнером может быть что угодно, в вашем случае подойдет QMdiArea.
На сколько я понял, вы на уровне исходных кодов использовали один и тот же виджет в двух разных приложения?
Мне хотелось бы обеспечить внедрение именно бинарного запускаемого файла.
Я частично решил задачу.
Сейчас я посылаю из главного приложения дочернему посредством вызова QProcess.write() для записи команд в консоль  дочернего приложения команды выравнивания окна относительно родительского.




Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: zenden от Ноябрь 13, 2009, 16:44
А как такое реализуют программы-фронтенды, к примеру  как SMPLayer встраивает в себя Mplayer??


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: jasf от Ноябрь 13, 2009, 16:50
А мне кажется, что проще заifdefить код под каждую из платформ.
В виндовс это реализовать, на сколько я помню, предельно просто. Получаем хэндл нужного окна и устанавливаем ему parent. Когда я этим игрался, мог кнопку пуск засунуть в панель быстрого запуска тотал коммандера :) ещё прикольно было засунуть окно milkdrop winampа (визуализатор) куда-нибудь. например на рабочий стол или в любой диалог. получался такой DreamScene под Xp :) теми же 2мя строками кода. Думаю под линуксом, маком такое API тоже есть. Платформ не так уж и много..


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: west от Ноябрь 14, 2009, 14:54
Прикольная задачка, под линукс у меня, кстати не особо получилось, только методами, типа как автор поста описал. Решал кто-нибудь тему под *nix? Если не жаль, скинте идею. (Я пытался через иксовые функции сделать)


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: BRE от Ноябрь 14, 2009, 15:48
Прикольная задачка, под линукс у меня, кстати не особо получилось, только методами, типа как автор поста описал. Решал кто-нибудь тему под *nix? Если не жаль, скинте идею. (Я пытался через иксовые функции сделать)
В KDE есть технология KPart, в GNOME - Bonobo.
http://ru.wikipedia.org/wiki/KParts


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: Alex Custov от Ноябрь 14, 2009, 16:13
Прикольная задачка, под линукс у меня, кстати не особо получилось, только методами, типа как автор поста описал. Решал кто-нибудь тему под *nix? Если не жаль, скинте идею. (Я пытался через иксовые функции сделать)
В KDE есть технология KPart, в GNOME - Bonobo.
http://ru.wikipedia.org/wiki/KParts

KParts это плагины, не подходит


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: Alex Custov от Ноябрь 14, 2009, 16:19
Прикольная задачка, под линукс у меня, кстати не особо получилось, только методами, типа как автор поста описал. Решал кто-нибудь тему под *nix? Если не жаль, скинте идею. (Я пытался через иксовые функции сделать)

Под иксы ВНЕЗАПНО решение такое же - через XReparentWindow. Там будут ещё ньюансы типа фокуса, поэтому разработана небольшая надстрока - XEmbed (http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html). В Qt есть классы для этого - QX11EmbedContainer, QX11EmbedWidget. Там тоже всё просто, и плагины будут существовать как отдельные приложения. Это сильно поможет для создания сверхнадёжных плагинных интерфейсов (падает плагин - программа прололжает работать, и даже может попробовать его перезапустить). В Chrome я думаю используется что-то подобное.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: andrew.k от Октябрь 28, 2010, 16:26
Прикольная задачка, под линукс у меня, кстати не особо получилось, только методами, типа как автор поста описал. Решал кто-нибудь тему под *nix? Если не жаль, скинте идею. (Я пытался через иксовые функции сделать)

Под иксы ВНЕЗАПНО решение такое же - через XReparentWindow. Там будут ещё ньюансы типа фокуса, поэтому разработана небольшая надстрока - XEmbed (http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html). В Qt есть классы для этого - QX11EmbedContainer, QX11EmbedWidget. Там тоже всё просто, и плагины будут существовать как отдельные приложения. Это сильно поможет для создания сверхнадёжных плагинных интерфейсов (падает плагин - программа прололжает работать, и даже может попробовать его перезапустить). В Chrome я думаю используется что-то подобное.
Удалось получить нужный результат?


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: vertus от Октябрь 19, 2011, 08:38
Мне удалось используя QX11EmbedContainer и QX11EmbedWidget.

В итоге когда надо приложение встраивается внутрь другого интерфейса, а когда надо запускается отдельным окном.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: andrew.k от Октябрь 19, 2011, 20:24
А не дашь свой проект посмотреть? Если там нет ничего секретного и он небольшой.
У меня тоже получилось но у меня не работал QTextEdit или кто-то такой (многострочный редактор).
Он никак не мог получить фокус, как я не старался. Остальные контроллы вроде работали.
Основные.

Мне до сих проблема интересна.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: vertus от Октябрь 20, 2011, 09:48
А не дашь свой проект посмотреть? Если там нет ничего секретного и он небольшой.
У меня тоже получилось но у меня не работал QTextEdit или кто-то такой (многострочный редактор).
Он никак не мог получить фокус, как я не старался. Остальные контроллы вроде работали.
Основные.

Мне до сих проблема интересна.

Да, такая проблема есть. Решается переводом фокуса при активизации виджета котейнера setFocus(Qt::TabFocusReason).

Дело в том, что xembed поддерживает перевод фокуса только по tab.

Проект дать не могу. Могу дать шаблон, как делать, но тебе это не нужно походу.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: andrew.k от Октябрь 20, 2011, 10:27
Шаблон он рабочий? Если да, то можно, посмотрю как у тебя получилось.

На сколько я помню я делал ему setFocus () без параметра и это не помогало. Попробую с параметром.
И tab не передавал ему фокус.
А у тебя не так что ли?


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: vertus от Октябрь 20, 2011, 11:28
Просто setFocus не катит, т.к., как я уже говорил, embed'ы поддерживают переключение фокуса только по tab.

Единственное в чем проблема, нужно всегда при активизации QX11EmbedContainer передавать фокус по tab. Т.е. если открыл окно с embed а потом перевел фокус на другое, при возвращении embed нужно снова передавать TabFocusReason.

Не, шаблон тоже не рабочий. На работе все сложно.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: vertus от Октябрь 20, 2011, 11:35
andrew.k, приведи свой код, я скажу, где подправить.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: andrew.k от Октябрь 20, 2011, 11:52
Т.е. передавать фокус по табу надо всему контейнеру и тогда в нем все контроллы будут работать?
А таб на клавиатуре нажатый будет работать?

Еще, а мышиные события куда поступают? Может их можно как-то транслировать? Через сокет передать например. не пробовал?

Мой тестовый проект еще поискать надо ) год уж прошел)
Найду выложу.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: vertus от Октябрь 20, 2011, 12:22
Т.е. передавать фокус по табу надо всему контейнеру и тогда в нем все контроллы будут работать?

Да.

Цитировать
А таб на клавиатуре нажатый будет работать?

Да.

Цитировать
Еще, а мышиные события куда поступают? Может их можно как-то транслировать? Через сокет передать например. не пробовал?

Не совсем понимаю о чём ты. Мышиные события естественно поступают, иначе как бы на встроенном виджете можно было бы нажимать кнопки, менять фокус (когда установил для контейнера TabFocusReason).
В связи с этим каким-то специальным образом отлавливать мышиные события не приходилось.


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: andrew.k от Октябрь 20, 2011, 14:04
Просто у меня как было. После встраивания все контоллы работали как надо. И таб работал и фокус между ними переходил.
Кроме многострочного редактора. Щелчки мышкой на нем ни к чему не приводили.
А как это сопрягается с другими контролами на форме в которую встраиваешь.
Например есть кнопки на самой форме, плюс ниже встроенная другая форма.
Как фокус переходит между ними?


Название: Re: Внедрение интерфейса одного приложения внутрь другого.
Отправлено: vertus от Октябрь 20, 2011, 14:08
Просто у меня как было. После встраивания все контоллы работали как надо. И таб работал и фокус между ними переходил.
Кроме многострочного редактора. Щелчки мышкой на нем ни к чему не приводили.
А как это сопрягается с другими контролами на форме в которую встраиваешь.
Например есть кнопки на самой форме, плюс ниже встроенная другая форма.
Как фокус переходит между ними?

Цитировать
When a widget has been embedded and the container receives tab focus, focus is passed on to the widget. When the widget reaches the end of its focus chain, focus is passed back to the container.

Т.е. до тех пор пока tab-ом не пройдешь все фокусные элементы на встраиваемом widget'е, фокус будет находиться в QX11EmbedContainer (опять таки, при условии передачи фокуса ему по TabFocusReason).