【问题标题】:How to dock a pop-out window?如何停靠弹出窗口?
【发布时间】:2016-04-02 23:49:56
【问题描述】:

我有一个包含 3 个主要小部件的应用程序。我还有一个弹出窗口QDockWidget。我试图让QDockWidget 停靠在底部小部件的右半部分,但如下图所示,我可以停靠窗口的唯一位置是应用程序的边缘。如何使QDockWidget 窗口占据底部小部件的右半部分?

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

编辑:使用下面@Bertrand 的回答,这就是我最终要做的事情:

ma​​inwindow.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

ma​​inwindow.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);
}

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    您可以将 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);
    }
    

    【讨论】:

    • 这是一个绝妙的答案。谢谢你花时间写它。一个问题:m_rightSideWindow 应该声明为 (error: 'm_rightSideWindow' was not declared in this scope) 的类型是什么?
    • 没关系。我想到了。有关详细信息,请参阅我原始答案的编辑部分。
    • @orbit 抱歉,我没有给出#include 文件。你做到了! :-)
    • 谢谢。你的回答很有帮助。您是否知道除了能够将其停靠到底部小部件的一半之外,我还可以如何保留原始图像中显示的功能(我可以将其停靠到最右侧的全长)?我想给用户选择。现在,我可以将Dock3 停靠在Dock1Dock2 旁边,但我无法将它停靠在应用程序的整个右侧高度。
    • @orbit 尝试用 2 个水平 QMainWindows 分割主窗口中心区域。
    猜你喜欢
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多