Изменение размера QGraphicsItem, чтобы занять все пространство в QGraphicsView, проблемы при изменении размера окна - PullRequest
1 голос
/ 25 октября 2010

У меня есть QGraphicsItem (на самом деле, QDeclarativeItem), и я хочу, чтобы он занимал все видимое пространство QGraphicsView (опять же, это фактически производный класс QDeclarativeView), к которому он был добавлен , Обычно вы можете использовать QDeclarativeView::setResizeMode(QDeclarativeView::SizeRootObjectToView) и QDeclarativeView автоматически изменят размер корневого объекта в соответствии с представлением.

У меня проблема в том, что я вручную создаю корневой виджет, используя

QDeclarativeComponent component(declarativeView->engine(), QUrl(qml));
QDeclarativeItem* object = qobject_cast<QDeclarativeItem*>(component.create());
if (object)
{
    declarativeView->scene()->addItem(object);
    ...

вместо того, чтобы QDeclarativeView делал это автоматически, вызывая setSource(). Причина, по которой я это делаю, заключается в том, что я хочу поменять сцену QML, когда происходят определенные события, но я не хочу разрушать предыдущую сцену. Вызов setSource() удаляет все элементы, которые были добавлены до вызова setSource(). Поэтому вместо этого я сам создаю «корневой объект» и вручную добавляю его в сцену.

Я использую Windows resizeEvent , чтобы изменить размер моего QDeclarativeItem, например:

void AppWindow::resizeEvent (QResizeEvent* event)
{
    QDeclarativeItem* object = sceneCache.value(sceneName, 0);
    if (object)
    {
        object->setWidth(declarativeView->viewport()->width());
        object->setHeight(declarativeView->viewport()->height());
    }
}

Это работает! Но это не очень красиво. Если вы быстро измените размер окна, QDeclarativeItem не будет изменен достаточно быстро, и вы кратко увидите серый фон, прежде чем он догонит и изменит его размер. Это также не очень гладко.

Это происходит только при изменении размера сложного элемента (в моем случае это виджет QWebKit). Он отлично работает для простых предметов. Однако дело в том, что если я позволю QDeclarativeView сделать это, у меня не возникнет ни одной из этих проблем: размер изменен правильно и плавно.

Я полагаю, что это не относится только к материалам QtDeclarative, а скорее к QGraphicsView, хотя, возможно, я ошибаюсь.

У кого-нибудь есть идеи?

Ответы [ 2 ]

3 голосов
/ 26 октября 2010

Я решил свои проблемы.

Проблема, похоже, связана с элементом WebView QML. Я отключил его для QGraphicsProxyWidget, зарегистрированного в C ++, с виджетом, установленным в нормальный QWebView, и все проблемы исчезли. Теперь он ведет себя именно так, как я ожидал от WebView.

Недостатком является то, что мне нужно вручную выставлять сигналы / слоты / свойства QWebView в QML. (РЕДАКТИРОВАТЬ: я решил это, имея свойство только для чтения с именем object, которое возвращает установленный виджет. Поскольку объекты QObject автоматически преобразуются в объекты, доступные в javascript, я могу получить доступ к веб-представлению, например, так: object.url = 'http://google.com'. Для удобства я также вызываю функцию init javascript на объекте QML, если он существует, поэтому я просто устанавливаю веб-представление там - прекрасно работает!)

Еще одно изменение, которое я сделал после того, как задал вопрос, - это переместить переключение «корневого объекта» из C ++ в сам QML, создав полноэкранный Rectangle с функцией JavaScript, вызываемой на C ++, которая использует Qt.createComponent () для загрузки " фактический файл QML и закрепите его с помощью anchors.fill. Таким образом, логика (и кеширование объектов) выполняется в QML вместо C ++, поэтому я могу просто установить setSource (), позволить Qt обрабатывать изменение размера и тому подобное, и я работаю исключительно в QML (для этой части приложения, в любом случае).

3 голосов
/ 25 октября 2010

Я не уверен, что это избавит от мерцания, но вы можете использовать fitInView в вашем resizeEvent():

declarativeView->fitInView(object, Qt::IgnoreAspectRatio);
...