Как повторно прикрепить QDockWidget к его родительскому QMainWindow? - PullRequest
1 голос
/ 13 марта 2019

Я пытался выяснить, можно ли закрепить QDockWidget в QSplitter, вот мой оригинальный вопрос .Однако, после долгих поисков, я обнаружил этот полезный пост , который ведет к другому посту, в котором говорится, что QDockWidgets можно закрепить только на QMainWindows.В полезном посте, на который я ссылался, был комментарий, который привел к этому решению в QtCenter.

То, что я сделал, взял этот код и добавил его в мое приложение.Однако я быстро обнаружил, что это работает только в одну сторону.Например, если у меня QMainWindow в моем QSplitter, я могу взять QDockWindow из QSplitter и прикрепить его к основному приложению.Тем не менее, я не могу повторно закрепить мой QSplitter QDockWindow обратно в QMainWindow QSplitter.

Затем я попытался создать еще один класс с именем MyWindow, так как подумал, что, возможно, мне просто нужно иметь возможность создать отдельный класс QMainWindow, который я затем смогу подключить через графический интерфейс и который будет иметь те же функции.как MainWindowClass.Однако это тоже не удалось.Вот мой код:

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;
    }
}

Закомментированные фрагменты кода - это то, что я изначально пытался сделать для подключенияих.Мой мыслительный процесс состоял в том, что MyWindow класс должен иметь свой собственный QDockWidget, однако, думая об этом, MainWindow класс - это тот, который на самом деле владеет QDockWidget, и я не совсем уверен, если переназначить родителя QMainWindow правильный путь или нет.

Что мне нужно сделать, чтобы заставить их повторно пристыковаться к исходному QMainWindow своего родителя?

РЕДАКТИРОВАТЬ :

Вот файл пользовательского интерфейса, если он кому-нибудь понадобится:

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>
...