Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dock a pop-out window?

Tags:

c++

qt

I have an application that has 3 main widgets. I also have a pop-out QDockWidget. I'm trying to get the QDockWidget to dock into the right half of the bottom widget, but as you can see in the image below, the only places I can dock the window are on the edges of the application. How can I make it so that the QDockWidget window takes up the right half of the bottom widget?

enter image description here

Also, is there a way to have a QDockWidget be already docked upon opening the application instead of having it open separately in its own window?

EDIT: Using @Bertrand's answer below, here's what I wound up doing:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();


private:
  Ui::MainWindow *ui;
  void on_actionRestore_layout_triggered();
  QMainWindow* m_rightSideWindow;
  QDockWidget* m_dockWidget1;
  QDockWidget* m_dockWidget2;
  QDockWidget* m_dockWidget3;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QtWidgets>

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow),
  m_rightSideWindow(NULL),
  m_dockWidget1(NULL),
  m_dockWidget2(NULL),
  m_dockWidget3(NULL)
{
  ui->setupUi(this);
  QSplitter *splitter = new QSplitter(this);
      splitter->setOrientation(Qt::Horizontal);
      QTreeView* leftSideWidget = new QTreeView(this);

      m_rightSideWindow = new QMainWindow(this);
      m_rightSideWindow->setWindowFlags(Qt::Widget);
      m_rightSideWindow->layout()->setContentsMargins(3, 3, 3, 3);

      splitter->addWidget(leftSideWidget);
      splitter->addWidget(m_rightSideWindow);

      m_dockWidget1 = new QDockWidget("Dock 1", this);
      m_rightSideWindow->addDockWidget(Qt::TopDockWidgetArea, m_dockWidget1);
      m_dockWidget1->setTitleBarWidget(new QWidget()); // remove title bar
      m_dockWidget1->setAllowedAreas(Qt::NoDockWidgetArea); // do not allow to dock
      QTextEdit* textEdit1 = new QTextEdit(this); // put any QWidget derived class inside
      m_dockWidget1->setWidget(textEdit1);

      m_dockWidget2 = new QDockWidget("Dock 2", this);
      m_rightSideWindow->addDockWidget(Qt::BottomDockWidgetArea, m_dockWidget2);
      m_dockWidget2->setTitleBarWidget(new QWidget());
      m_dockWidget2->setAllowedAreas(Qt::NoDockWidgetArea);
      QTextEdit* textEdit2 = new QTextEdit(this);
      m_dockWidget2->setWidget(textEdit2);

      m_dockWidget3 = new QDockWidget("Dock 3", this);
      m_rightSideWindow->addDockWidget(Qt::BottomDockWidgetArea, m_dockWidget3);
      QTextEdit* textEdit3 = new QTextEdit(this);
      m_dockWidget3->setWidget(textEdit3);

      setCentralWidget(splitter);
}

MainWindow::~MainWindow()
{
  delete ui;
}

void MainWindow::on_actionRestore_layout_triggered()
{
    QList<QDockWidget*> list = findChildren<QDockWidget*>();
    foreach(QDockWidget* dock, list)
    {
        if(dock->isFloating())
            dock->setFloating(false);
        m_rightSideWindow->removeDockWidget(dock);
        if (dock == m_dockWidget1)
            m_rightSideWindow->addDockWidget(Qt::TopDockWidgetArea, m_dockWidget1);
        else
            m_rightSideWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
        dock->setVisible(true);
    }
    m_rightSideWindow->splitDockWidget(m_dockWidget2, m_dockWidget3, Qt::Horizontal);
}
like image 338
earth Avatar asked Apr 01 '16 20:04

earth


People also ask

How do you dock a floating window?

To dock a floating window, do one of the following: Double-click the window's title bar. Open the shortcut menu by selecting and holding (or right-clicking) the window's title bar or selecting the window's icon in the upper-right corner, and then select Dock.

What is window docking?

An on-screen window that is fixed in position to the rest of the application windows. Contrast with floating window.


1 Answers

You can dock a QDockWidget on a QMainWindow or another QDockWidget.

To get the desired layout embed a sub QMainWindow on the right side of your main window, and use it as a QWidget with setWindowFlags(Qt::Widget):

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QtWidgets>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QSplitter *splitter = new QSplitter(this);
    splitter->setOrientation(Qt::Horizontal);
    QTreeView* leftSideWidget = new QTreeView(this);

    m_rightSideWindow = new QMainWindow(this);
    m_rightSideWindow->setWindowFlags(Qt::Widget);
    m_rightSideWindow->layout()->setContentsMargins(3, 3, 3, 3);

    splitter->addWidget(leftSideWidget);
    splitter->addWidget(m_rightSideWindow);

    m_dockWidget1 = new QDockWidget("Dock 1", this);
    m_rightSideWindow->addDockWidget(Qt::TopDockWidgetArea, m_dockWidget1);
    m_dockWidget1->setTitleBarWidget(new QWidget()); // remove title bar
    m_dockWidget1->setAllowedAreas(Qt::NoDockWidgetArea); // do not allow to dock
    QTextEdit* textEdit1 = new QTextEdit(this); // put any QWidget derived class inside
    m_dockWidget1->setWidget(textEdit1);

    m_dockWidget2 = new QDockWidget("Dock 2", this);
    m_rightSideWindow->addDockWidget(Qt::BottomDockWidgetArea, m_dockWidget2);
    m_dockWidget2->setTitleBarWidget(new QWidget());
    m_dockWidget2->setAllowedAreas(Qt::NoDockWidgetArea);
    QTextEdit* textEdit2 = new QTextEdit(this);
    m_dockWidget2->setWidget(textEdit2);

    m_dockWidget3 = new QDockWidget("Dock 3", this);
    m_rightSideWindow->addDockWidget(Qt::BottomDockWidgetArea, m_dockWidget3);
    QTextEdit* textEdit3 = new QTextEdit(this);
    m_dockWidget3->setWidget(textEdit3);

    setCentralWidget(splitter);

}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_actionRestore_layout_triggered()
{
    QList<QDockWidget*> list = findChildren<QDockWidget*>();
    foreach(QDockWidget* dock, list)
    {
        if(dock->isFloating())
            dock->setFloating(false);
        m_rightSideWindow->removeDockWidget(dock);
        if (dock == m_dockWidget1)
            m_rightSideWindow->addDockWidget(Qt::TopDockWidgetArea, m_dockWidget1);
        else
            m_rightSideWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
        dock->setVisible(true);
    }
    m_rightSideWindow->splitDockWidget(m_dockWidget2, m_dockWidget3, Qt::Horizontal);
}

enter image description here

like image 151
Bertrand Avatar answered Nov 14 '22 21:11

Bertrand