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 был на экране, который теперь выключен?