Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add detachable areas (QDockWidget) to a QML application

How do I add detachable areas to a QML ApplicationWindow?

Take the following application (Tiled) as an example. It has multiple detachable areas. In the first image all areas are attached, while in the second one area is in the process of being detached/reattached:

enter image description here

From C++ this can be realized with QDockWidget (see this question). But is there a solution with QML?

like image 956
Appleshell Avatar asked Jun 01 '14 00:06

Appleshell


People also ask

What is dock widget?

Detailed Description. QDockWidget provides the concept of dock widgets, also know as tool palettes or utility windows. Dock windows are secondary windows placed in the dock widget area around the central widget in a QMainWindow.

How do I create a QML application?

Creating and Running QML Projects For simple UI files such as this one, select File > New File or Project > Application (Qt Quick) > Qt Quick Application - Empty from within Qt Creator. Pressing the green Run button runs the application. You should see the text Hello, World! in the center of a red rectangle.

What is QML GUI?

QML (Qt Modeling Language) is a user interface markup language. It is a declarative language (similar to CSS and JSON) for designing user interface–centric applications.


3 Answers

As one possible solution you can create custom QDialog, use inside it QQuickView with desired qml stuff loaded from appropriate qml file. Communication with your main qml window and dialog will be done through Q_PROPERTY and Q_INVOKABLE defines in your custom dialog.

The pointer to your QDialog instance, for example, can be propagated to the QML as context property with help of QQmlContext::setContextProperty.

like image 114
Max Go Avatar answered Oct 21 '22 18:10

Max Go


I made a simple working example. You can find it here. There must be enough comments for you to sort it out.

I used dynamic creation of objects like that:

  • dynamically create component(DetachableItem.qml) and assign it to property(not necessary, but it is easier to find it)
  • create connection for this component's attached property, where I can call some function when it changes;
  • move the item into another window pushing the object into it's data property
  • move it back the same way - pushing it to data property of main window and hiding separate window.

Feel free to ask question or proposing some improvements. I am interested in any suggestions how to improve it!

UPD: I updated the example with new commit where I got rid of dynamic objects creation. If you are still interested in dynamic object creation, you can checkout to this commit

like image 45
Maxim Skvortsov Avatar answered Oct 21 '22 19:10

Maxim Skvortsov


Just an idea on how to achieve such behaviour. Have a look at the Window QML class and dynamic object creation to actually create a window by request.

Some (UNTESTED) pseudo-code, just to give an idea "DockWindow.qml":

import QtQuick 2.0
import QtQuick.Window 2.2

Rectangle {
 id: dockWidget

 property Window window: null
 property Item embedIn: null
 parent: window ? window : embedIn
 readonly property bool detached: window

 function detach() {
  if (!window) {
   window = Qt.createQmlObject('
    import QtQuick.Window 2.2
    Window { flags: …; }
    ', dockWidget, "dockWidget");
  }
 }

 function close() {
  if (window) {
   window.close();
  }
 }
}

Note: This code will not work out of the box and probably leads to a dependency loop on the "parent" property!

like image 1
Nils Fenner Avatar answered Oct 21 '22 20:10

Nils Fenner