Название: Вопрос по реализации Отправлено: Nidxogg от Сентябрь 17, 2015, 18:36 Добрый день
Интересует совет как реализовать нужное поведение, может какой паттерн или все намного проще. Суть: Есть Qtприложение с плагинами. Главная форма MainWindow + QMdiArea в centralWidget. Приложению известен только интерфейс плагинов. В плагинах реализуются action-ы со слотами, создается меню, которое добавляется в menubar MainWindow. Собственно, результатом срабатывания action-а является создание окна-наследника QWidget. И вопрос, как вернуть через указатель на это окно после срабатывания action-а, чтобы добавить его к QMdiArea? :-\ Название: Re: Вопрос по реализации Отправлено: Racheengel от Сентябрь 18, 2015, 10:47 Сделать факторизацию через плагин, например, с интерфейсом типа
virtual QWidget* createWidget() { ... } и вызывать этот метод при обработке экшина. Название: Re: Вопрос по реализации Отправлено: Nidxogg от Сентябрь 18, 2015, 19:16 Сделать факторизацию через плагин, например, с интерфейсом типа То что указатель на виджет возвращается через интерфейс - это понятноvirtual QWidget* createWidget() { ... } и вызывать этот метод при обработке экшина. Аналогично я возвращаю указатель на меню после загрузки плагина Вопрос в том, как сообщить MainWindow, что нужно вызвать этот метод, если обработка экшена находится внутри плагина. И ещё вопрос, как отследить что окно закрылось и удалить его (не используя Qt::WA_DeleteOnClose). Вести какой-то контейнер указателей созданных окон внутри плагина? Название: Re: Вопрос по реализации Отправлено: Racheengel от Сентябрь 21, 2015, 11:58 Ваш плагин при загрузке должен как-то регистрироваться в приложении.
При регистрации сделайте связь экшена в плагине с методом приложения, которое будет вызывать createWidget(). Как вариант, обычным коннектом слотов-сигналов. По поводу 2 - можно через QWidget::closeEvent, например. Название: Re: Вопрос по реализации Отправлено: Nidxogg от Сентябрь 21, 2015, 18:29 Цитировать Ваш плагин при загрузке должен как-то регистрироваться в приложении. В результате срабатывания каждого экшена создается окно определенного типа (все они наследники одного базового класса)При регистрации сделайте связь экшена в плагине с методом приложения, которое будет вызывать createWidget(). Как вариант, обычным коннектом слотов-сигналов. Я правильно понимаю, что createWidget() будет просто возвращать указатель на уже созданное окно внутри плагина (в результате экшена), а не сообщать плагину что именно надо создать? (Это вообще Цитировать По поводу 2 - можно через QWidget::closeEvent, например. Имеете ввиду переопределить этот метод в MainWindow?Название: Re: Вопрос по реализации Отправлено: Racheengel от Сентябрь 22, 2015, 01:30 Я правильно понимаю, что createWidget() будет просто возвращать указатель на уже созданное окно внутри плагина (в результате экшена), а не сообщать плагину что именно надо создать? (Это вообще А какая разница приложению, как именно плагин создает окно? Главное, чтобы тип созданного окна поддерживался приложением, но ведь ваш плагин это и так гарантирует. Цитировать По поводу 2 - можно через QWidget::closeEvent, например. Имеете ввиду переопределить этот метод в MainWindow?[/quote] Я так понял, что вам надо, чтобы каждое окно сообщало о своем закрытии? Тогда в окне надо переопределить. Название: Re: Вопрос по реализации Отправлено: Nidxogg от Сентябрь 22, 2015, 18:44 Цитировать Я так понял, что вам надо, чтобы каждое окно сообщало о своем закрытии? Тогда в окне надо переопределить. Для сообщения я и так переопределил closeEvent (чтобы уведомлять о наличии несохраненных изменений)Надо именно корректно освободить выделенную память при закрытии. Сейчас использую флаг deleteonclose, просто интересуют ещё варианты. Я так понимаю в closeevent нельзя написать что-то вроде delete this? Цитировать А какая разница приложению, как именно плагин создает окно? Главное, чтобы тип созданного окна поддерживался приложением, но ведь ваш плагин это и так гарантирует. Просто интересуюсь, может быть есть другие вариантыПолучается, что в интерфейсе придется объявить виртуальный сигнал, сообщающий слоту в MainWindow, что необходимо запросить виджет? Или подключить сигналы от экшенов из возвращаемого интерфесом меню к слоту? Название: Re: Вопрос по реализации Отправлено: Racheengel от Сентябрь 22, 2015, 19:41 Цитировать Я так понимаю в closeevent нельзя написать что-то вроде delete this? Нельзя. Цитировать Сейчас использую флаг deleteonclose, просто интересуют ещё варианты. Да нормальный, вроде, вариант :) Цитировать Получается, что в интерфейсе придется объявить виртуальный сигнал, сообщающий слоту в MainWindow, что необходимо запросить виджет? Или подключить сигналы от экшенов из возвращаемого интерфесом меню к слоту? Ну так а разве экшены меню не плагином создаются? Они же пусть будут подключены к слоту в плагине, который делает окно. Или их можно делегировать в MainWindow, если необходимо по задаче. Название: Re: Вопрос по реализации Отправлено: Nidxogg от Сентябрь 22, 2015, 20:09 Цитировать Ну так а разве экшены меню не плагином создаются? Все уже так.Они же пусть будут подключены к слоту в плагине, который делает окно. Извиняюсь, если непонятно формулирую свои вопросы. Цитировать Или их можно делегировать в MainWindow, если необходимо по задаче. Изначальный вопрос, как сообщить MainWindow, что нужно запросить у плагина окно, которое уже было создано внутри плагина.Сначала были мысли сигнал в интерфейсе, связанный со слотом в MainWindow. Но мне почему-то такой вариант кажется не очень, какое-то "туда-сюда" получается. Название: Re: Вопрос по реализации Отправлено: Nidxogg от Сентябрь 23, 2015, 15:10 Сделал простенькое приложение, чтобы было понятно о чем речь
Проблема все та же, получить из плагина указатель на созданное окно Даже если прикрутить сигнал в интерфейс, все равно надо как-то узнать, из какого именного плагина он испущен Название: Re: Вопрос по реализации Отправлено: Racheengel от Сентябрь 23, 2015, 15:38 Тогда можно передать поинтер на MainWindow в функцию Initialize().
После этого плагин будет знать про главное окно и куда вставлять свои окна. Название: Re: Вопрос по реализации Отправлено: Nidxogg от Сентябрь 23, 2015, 15:47 Тогда можно передать поинтер на MainWindow в функцию Initialize(). Попробую так, спасибоПосле этого плагин будет знать про главное окно и куда вставлять свои окна. Просто предлагал, что плагин ничего не должен знать о том, где он вызывается |