Russian Qt Forum

Qt => Вопросы новичков => Тема начата: PinkPanther от Февраль 20, 2015, 20:45



Название: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: PinkPanther от Февраль 20, 2015, 20:45
Здравствуйте, коллеги. Сразу 3 вопроса:
1) Идеология работы фреймворка. Допустим, я создал интерфейс, в котором предусмотрено место для динамически создаваемых виджетов. Пусть это будет вкладка, к которой прицеплен QWidget, на который, соответственно, вешается динамически созданный QVBoxLayout (QVBoxLayout *vbl = new QVBoxLayout). По ходу работы программы я создаю динамические объекты, вроде QLabel *xxx = new QLabel(tr("abc...")), и вставляю их в QVBoxLayout, или сразу прикрепляю к vbl, указывая его адрес при создании... Через какое-то время весь этот набор объектов становится ненужным, а для новых я просто создаю новый QHBoxLayout, и прикрепляю его к QWidget-у вкладки. Вопрос: старые объекты будут удалены из памяти сборщиком мусора, или их нужно удалять явным образом (delete xxx, yyy, zzz,.. vbl)? Как сделать, чтобы ставшие ненужными объекты не занимали память, чтобы сборщик мусора их вычищал максимально оперативно?
2) QWebView работает в отдельном потоке, или в основном потоке приложения? Мое приложение активно использует этот виджет, все сигналы обрабатываются, к нему подключена переписанная QWebPage, он исполняет скрипты JS, сетевой менеджер использует прокси. К сожалению, активное использование QWebView иногда приводит к крэшу приложения, как на конкретных страницах, так и совершенно неожиданно. Есть ли какие-то рекомендации, как обезопасить приложение от капризов QWebView? Эта же проблема (крэш приложения) возникала еще во времена 4-й версии Qt, в  совсем примитивном приложении. Каким образом серфинг в QWebView может приводить к крэшу?
3) К QNetworkAccessManager можно подключить QNetworkProxy, и работать через прокси. Все чудно, объект прокси заполняется, подключается, и QWebView работает через проксю. К сожалению, не нашел информации, как отключить этот класс... Как заставить QNetworkAccessManager перестать пользоваться прокси, и снова начать работать с сетью напрямую?


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: gil9red от Февраль 20, 2015, 22:33
1) Сборщика мусора нет


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: Johnik от Февраль 20, 2015, 23:21
3) попробуйте: networkAccessManager.setProxy(QNetworkProxy())


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: PinkPanther от Февраль 21, 2015, 14:32
gil9red, Johnik, спасибо!


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: PinkPanther от Март 08, 2015, 00:27
Для информации:

> Как заставить QNetworkAccessManager перестать пользоваться прокси, и снова начать работать с сетью напрямую?

Подключить прокси NoProxy
proxy.setType(QNetworkProxy::NoProxy);


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: Igors от Март 08, 2015, 07:20
По ходу работы программы я создаю динамические объекты, вроде QLabel *xxx = new QLabel(tr("abc...")), и вставляю их в QVBoxLayout, или сразу прикрепляю к vbl, указывая его адрес при создании... Через какое-то время весь этот набор объектов становится ненужным, а для новых я просто создаю новый QHBoxLayout, и прикрепляю его к QWidget-у вкладки. Вопрос: старые объекты будут удалены из памяти сборщиком мусора, или их нужно удалять явным образом (delete xxx, yyy, zzz,.. vbl)? Как сделать, чтобы ставшие ненужными объекты не занимали память, чтобы сборщик мусора их вычищал максимально оперативно?
Как уже сказали, сборщика нет, причем не в Qt или классе, а вообще в языке. Обычная техника - при создании виджетов назначать им одного парента, которого потом удалить, все child виджеты удалятся автоматычно.


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: popper от Март 08, 2015, 22:37
Добавлю. При вызове QLayout::addWidget() лайаут становится владельцем виджета и ответственным за его удаление


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: PinkPanther от Март 08, 2015, 22:54
Спасибо, коллеги.

А вот вопрос: как разместить объект с нулевым пэрентом (чтобы не возникло проблем с его удалением при живом основном GUI) где-нибудь... ну, скажем, на вкладке таба, или в QMainWindow, просто по координатам? То есть создать виджет динамически, указать координаты, напичкать данными, показать-поработать, в нужный момент спрятать и удалить? Или это можно сделать только через добавление в лейаут?

Остальные вопросы топика вроде разрешились. На повестке дня сложная задача устранения утечки памяти при работе с QWebView.


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: Igors от Март 09, 2015, 10:18
Добавлю. При вызове QLayout::addWidget() лайаут становится владельцем виджета и ответственным за его удаление
По-моему Вы ошибаетесь, addWidget не меняет родителя, и можно грохнуть лайаут, содержимое не удалится.

А вот вопрос: как разместить объект с нулевым пэрентом (чтобы не возникло проблем с его удалением при живом основном GUI) где-нибудь... ну, скажем, на вкладке таба, или в QMainWindow, просто по координатам? То есть создать виджет динамически, указать координаты, напичкать данными, показать-поработать, в нужный момент спрятать и удалить? Или это можно сделать только через добавление в лейаут?
Виджет с нулевым парентом автоматычно становится top-level окном, вряд ли Вас это устроит. Можно просто создать QWidget с парентом вкладка таба, и к нему цеплять др виджеты, они будут скрыты или удалены вместе с этим QWidget. Можно использовать QStackedLayout. В общем это заботы из разряда легких и приятных     


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: PinkPanther от Март 09, 2015, 10:23
Спасибо, Igors!
С размещением теперь все понятно.


Название: Re: Три общих вопроса: сборщик мусора, QWebView и QNetworkProxy
Отправлено: popper от Март 09, 2015, 16:50
Добавлю. При вызове QLayout::addWidget() лайаут становится владельцем виджета и ответственным за его удаление
По-моему Вы ошибаетесь, addWidget не меняет родителя, и можно грохнуть лайаут, содержимое не удалится.

Да, я не совсем правильно написал - владельцем будет виджет, на котором установлен лайаут. Вот что написано в документации:
Цитировать
When you use a layout, you do not need to pass a parent when constructing the child widgets. The layout will automatically reparent the widgets (using QWidget::setParent()) so that they are children of the widget on which the layout is installed.