Jacob
Jacob

Reputation: 15

QQuickWidget's content disappears when parent's parent changes

I'm trying to build an application consisting of multiple QMdiSubWindows that each contain a QQuickWidget and can be moved between different QMdiAreas. I'm able to create subwindows and display QML content inside them, but this content disappears when the subwindow is moved to a new MDI area. Example code follows.

// Constructor
MySubWindow::MySubWindow(QQmlComponent* qml_component, QQmlEngine* engine,
  QWidget* parent, Qt::WindowFlags flags) : QMdiSubWindow(parent, flags) {
  // Add to MDI area
  initial_area->addSubWindow(this);

  // Create child QML widget
  auto* qml_widget = new QQuickWidget(engine, this);
  setWidget(qml_widget);

  // Add QML content
  auto* qml_obj = qobject_cast<QQuickItem*>(qml_component->create(engine->rootContext()));

  auto* root_item = qml_widget->quickWindow()->contentItem();
  qml_obj->setParent(root_item);
  qml_obj->setParentItem(root_item);

  // Show subwindow
  showMaximized();
}

// Move subwindow to a new MDI area
void MySubWindow::set_area(QMdiArea* new_area) {
  mdiArea()->removeSubWindow(this);
  new_area->addSubWindow(this);

  showMaximized();
}

I'm using a simple QML component that contains a colored rectangle to test. I can see the rectangle when MySubWindow is created, but I get a blank white window after set_area() is called. I've tried to reparent my QML object after the move to contentItem like shown in the constructor, but this causes a segfault. Any thoughts?

Upvotes: 0

Views: 98

Answers (1)

Jacob
Jacob

Reputation: 15

I'm not sure why, but I was able to fix the issue by switching from QQuickWidget to QQuickView. The modified code follows:

// Constructor
MySubWindow::MySubWindow(QQmlComponent* qml_component, QQmlEngine* engine,
  QWidget* parent, Qt::WindowFlags flags) : QMdiSubWindow(parent, flags) {
  // Add to MDI area
  initial_area->addSubWindow(this);

  // Create child QML widget
  auto* qml_view = new QQuickView();
  auto* qml_widget = QWidget::createWindowContainer(qml_view, this);
  setWidget(qml_widget);

  // Add QML content
  auto* qml_obj = qobject_cast<QQuickItem*>(qml_component->create(engine->rootContext()));

  auto* root_item = qml_view->contentItem();
  qml_obj->setParent(root_item);
  qml_obj->setParentItem(root_item);

  // Show subwindow
  showMaximized();
}

// Move subwindow to a new MDI area
void MySubWindow::set_area(QMdiArea* new_area) {
  mdiArea()->removeSubWindow(this);
  new_area->addSubWindow(this);

  showMaximized();
}

Upvotes: 0

Related Questions