QDockWidget не запоминает плавающий размер и местоположение при переключении IsFloat - PullRequest
0 голосов
/ 15 февраля 2019

QDockWidget имеет функцию, при которой вы можете дважды щелкнуть строку заголовка, и док переключится в плавающее окно и вернется в закрепленное состояние.Проблема в том, что если вы переместите и измените размер плавающего окна, а затем переключитесь обратно в док, а затем снова вернетесь в плавающее положение, ваше положение и размер будут потеряны.

Я искал решения для изменения размера и перемещения QDockWidgetи я взглянул на исходный код Qt для QDockWidget.Я создал небольшой подкласс 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 был на экране, который теперь выключен?

...