I have been trying to figure out if you could dock a QDockWidget in a QSplitter, here is my original question. However, after doing a lot of digging around, I found this helpful post which lead to another post that stated that QDockWidgets can only be docked on QMainWindows. In the helpful post I linked, there was a comment that led to this solution on the QtCenter.
What I have done, is taken that code and added it to my application. However, I quickly found out that it only works one way. As in if I have a QMainWindow in my QSplitter, I can take the QDockWindow out of the QSplitter and dock it on the main application. However, I cannot re-dock my QSplitter's QDockWindow back into the QSplitter's QMainWindow.
I then tried to create another class called, MyWindow as I figured that maybe I just need to be able to create a seperate QMainWindow class that I can then connect through the GUI and has the same functions as the MainWindowClass. However that too has failed. Here is my code:
MyWindow.hpp
#ifndef MYWINDOW_HPP
#define MYWINDOW_HPP
#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include <QDockWidget>
class MyWindow : public QMainWindow
{
Q_OBJECT
public:
MyWindow(QWidget *child = nullptr);
QMainWindow* createNewWindow();
public slots:
void dragStarted(bool started);
void enterEvent(QEvent *event);
void dragEnded() { dw = nullptr; }
private:
QDockWidget* dw = nullptr;
};
#endif // MYWINDOW_HPP
MyWindow.cpp
#include "mywindow.hpp"
MyWindow::MyWindow(QWidget *child) : QMainWindow (child){}
QMainWindow* MyWindow::createNewWindow()
{
QMainWindow *newWindow = new QMainWindow(this);
newWindow->setWindowFlags(Qt::Widget);
return newWindow;
}
void MyWindow::dragStarted(bool started)
{
if(started)
{
if(QDockWidget* dock = qobject_cast<QDockWidget*>(sender()))
dw = dock;
else
dw = nullptr;
}
}
void MyWindow::enterEvent(QEvent *event)
{
if(dw && dw->parent() != this)
{
addDockWidget(Qt::RightDockWidgetArea, dw);
dw = nullptr;
}
}
MainWindow.hpp
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP
#include <QMainWindow>
#include <QWidget>
#include <QDockWidget>
#include "mywindow.hpp"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void dragStarted(bool started);
void enterEvent(QEvent *event);
void dragEnded() { dw = nullptr; }
private:
Ui::MainWindow *ui;
QDockWidget* dw = nullptr;
};
#endif // MAINWINDOW_HPP
MainWindow.cpp
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QWidget *child = nullptr;
MyWindow myWindow(child);
QMainWindow *leftWindow = myWindow.createNewWindow();
QMainWindow *rightWindow = myWindow.createNewWindow();
leftWindow->addDockWidget(Qt::LeftDockWidgetArea,ui->leftDock);
rightWindow->addDockWidget(Qt::RightDockWidgetArea,ui->rightDock);
ui->splitter->addWidget(leftWindow);
ui->splitter->addWidget(rightWindow);
//connect(ui->leftDock,SIGNAL(topLevelChanged(bool)),&myWindow,SLOT(dragStarted(bool)));
//connect(ui->rightDock,SIGNAL(topLevelChanged(bool)),&myWindow,SLOT(dragStarted(bool)));
connect(ui->leftDock,SIGNAL(topLevelChanged(bool)),this,SLOT(dragStarted(bool)));
connect(ui->rightDock,SIGNAL(topLevelChanged(bool)),this,SLOT(dragStarted(bool)));
//connect(ui->leftDock,SIGNAL(dockLocationChanged (Qt::DockWidgetArea)),&myWindow,SLOT(dragEnded()));
//connect(ui->rightDock,SIGNAL(dockLocationChanged (Qt::DockWidgetArea)),&myWindow,SLOT(dragEnded()));
connect(ui->leftDock,SIGNAL(dockLocationChanged (Qt::DockWidgetArea)),this,SLOT(dragEnded()));
connect(ui->rightDock,SIGNAL(dockLocationChanged (Qt::DockWidgetArea)),this,SLOT(dragEnded()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::dragStarted(bool started)
{
if(started)
{
if(QDockWidget* dock = qobject_cast<QDockWidget*>(sender()))
dw = dock;
else
dw = nullptr;
}
}
void MainWindow::enterEvent(QEvent *event)
{
if(dw && dw->parent() != this)
{
addDockWidget(Qt::RightDockWidgetArea, dw);
dw = nullptr;
}
}
The commented out pieces of code is what I originally tried to do in order to connect them. My thought process was that MyWindow class should have it's own QDockWidget, however when thinking about it, MainWindow class is the one that actually owns the QDockWidget and I am not really sure if re-assigning the parent QMainWindow is the right way to go or not.
What do I need to do in order to get them to re-dock to their original Parent's QMainWindow?
EDIT:
Here is the ui file should anyone need it:
MainWindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1144</width>
<height>802</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QSplitter" name="splitter">
<property name="geometry">
<rect>
<x>30</x>
<y>60</y>
<width>781</width>
<height>591</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>681</width>
<height>551</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="lineWidth">
<number>2</number>
</property>
<property name="midLineWidth">
<number>2</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1144</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<widget class="QDockWidget" name="leftDock">
<property name="maximumSize">
<size>
<width>524287</width>
<height>300</height>
</size>
</property>
<property name="windowTitle">
<string>Left Dock</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="rightDock">
<property name="maximumSize">
<size>
<width>524287</width>
<height>300</height>
</size>
</property>
<property name="windowTitle">
<string>Right Dock</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget_2">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Tab 1</string>
</attribute>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>