如何停靠弹出窗口?

时间:2016-04-01 20:20:09

标签: c++ qt

我有一个包含3个主要小部件的应用程序。我也有一个弹出窗口QDockWidget。我试图让QDockWidget停靠在底部小部件的右半部分,但正如您在下图中看到的那样,我可以停靠窗口的唯一位置是在应用程序的边缘。我怎样才能使QDockWidget窗口占据底部小部件的右半部分?

enter image description here

此外,有没有办法让QDockWidget在打开应用程序时已经停靠,而不是在自己的窗口中单独打开它?

编辑:使用下面的@ Bertrand的答案,这是我最后做的事情:

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

1 个答案:

答案 0 :(得分:6)

您可以将QDockWidget停靠在QMainWindow或其他QDockWidget上。

要获得所需的布局,请在主窗口的右侧嵌入一个子QMainWindow,并将其用作带有setWindowFlags(Qt :: Widget)的QWidget:

#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