如何将QDockWidget重新停靠在其父QMainWindow上?

时间:2019-03-13 18:36:41

标签: c++ qt qwidget

我一直在尝试找出是否可以将QDockWidget停靠在QSplitter here is my original question中。但是,在进行大量挖掘之后,我发现this helpful post导致了另一条帖子,指出QDockWidgets只能停靠在QMainWindows上。在我链接的有用文章中,有一条评论导致QtCenter上的this solution

我所做的事情就是使用该代码并将其添加到我的应用程序中的。但是,我很快发现它只能以一种方式起作用。就像在QMainWindow中有一个QSplitter一样,我可以从QDockWindow中取出QSplitter并将其停靠在主应用程序上。但是,我无法将我的QSplitter的QDockWindow重新停靠在QSplitter的QMainWindow中。

然后我尝试创建另一个名为MyWindow的类,因为我发现也许我只需要能够创建一个单独的QMainWindow类,然后就可以通过GUI连接并具有相同的类了。用作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中?

编辑

这是任何人都需要的ui文件:

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>

0 个答案:

没有答案