切换IsFloat时,QDockWidget不记得浮动大小和位置

时间:2019-02-15 04:06:19

标签: location size floating qdockwidget

QDockWidget具有一项功能,您可以双击标题栏,并且停靠栏将切换到浮动窗口并返回其停靠状态。问题是,如果您移动浮动窗口并调整其大小,然后切换回停靠栏,然后又重新回到浮动窗口,则会丢失位置和大小。

我一直在寻找用于调整和移动QDockWidget大小的解决方案,并且已经研究了QDockWidget的Qt源代码。我创建了一个QDockWidget的小子类,该子类似乎可以解决该问题。它会覆盖mouseDoubleClick,调整事件大小和移动事件,过滤掉Qt不必要的“随机”调整大小和位置,并将有关屏幕,位置和大小的信息存储在我存储在QSettings中的结构中,以确保会话之间的持久性。

// header
#include <QDockWidget>
#include "global.h"
class DockWidget : public QDockWidget
{
    Q_OBJECT
public:
    DockWidget(const QString &title, QWidget *parent = nullptr);
    QSize sizeHint() const;
    void rpt(QString s);
    struct DWLoc {
        int screen;
        QPoint pos;
        QSize size;
    };
    DWLoc dw;
    bool ignore;
protected:
    bool event(QEvent *event);
    void resizeEvent(QResizeEvent *event);
    void moveEvent(QMoveEvent *event);
};


// cpp
#include "dockwidget.h"

DockWidget::DockWidget(const QString &title, QWidget *parent)
    : QDockWidget(title, parent)
{
    ignore = false;
}

bool DockWidget::event(QEvent *event)
{
    if (event->type() == QEvent::MouseButtonDblClick) {
        ignore = true;
        setFloating(!isFloating());
        if (isFloating()) {
            // move and size to previous state
            QRect screenres = QApplication::desktop()->screenGeometry(dw.screen);
            move(QPoint(screenres.x() + dw.pos.x(), screenres.y() + dw.pos.y()));
            ignore = false;
            adjustSize();
        }
        ignore = false;
        return true;
    }
    QDockWidget::event(event);
    return true;
}

void DockWidget::resizeEvent(QResizeEvent *event)
{
    if (ignore) {
        return;
    }
    if (isFloating()) {
        dw.screen = QApplication::desktop()->screenNumber(this);
        QRect r = geometry();
        QRect a = QApplication::desktop()->screen(dw.screen)->geometry();
        dw.pos = QPoint(r.x() - a.x(), r.y() - a.y());
        dw.size = event->size();
    }
}

QSize DockWidget::sizeHint() const
{
    return dw.size;
}

void DockWidget::moveEvent(QMoveEvent *event)
{
    if (ignore || !isFloating()) return;
    dw.screen = QApplication::desktop()->screenNumber(this);
    QRect r = geometry();
    QRect a = QApplication::desktop()->screen(dw.screen)->geometry();
    dw.pos = QPoint(r.x() - a.x(), r.y() - a.y());
    dw.size = QSize(r.width(), r.height());
}

虽然这似乎可行,但有没有更简单的方法来实现这一目标?如果QDockWidget位于现在关闭的屏幕上怎么办?

0 个答案:

没有答案