mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
New QgsFloatingWidget widget for easy creation of widgets which "float"
above a layout. Supports setting another widget as a anchor point for the widget, eg the floating widget could be set so that it's always placed to the top-right of the anchor widget.
This commit is contained in:
parent
f85d24e9c7
commit
5da25136a6
@ -79,6 +79,7 @@
|
||||
%Include qgsfilewidget.sip
|
||||
%Include qgsfiledownloader.sip
|
||||
%Include qgsfilterlineedit.sip
|
||||
%Include qgsfloatingwidget.sip
|
||||
%Include qgsfocuswatcher.sip
|
||||
%Include qgsformannotationitem.sip
|
||||
%Include qgsgenericprojectionselector.sip
|
||||
|
@ -226,6 +226,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgsfiledropedit.cpp
|
||||
qgsfilewidget.cpp
|
||||
qgsfilterlineedit.cpp
|
||||
qgsfloatingwidget.cpp
|
||||
qgsfocuswatcher.cpp
|
||||
qgsformannotationitem.cpp
|
||||
qgsgenericprojectionselector.cpp
|
||||
@ -393,6 +394,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgsfiledropedit.h
|
||||
qgsfilewidget.h
|
||||
qgsfilterlineedit.h
|
||||
qgsfloatingwidget.h
|
||||
qgsfocuswatcher.h
|
||||
qgsformannotationitem.h
|
||||
qgsgenericprojectionselector.h
|
||||
|
179
src/gui/qgsfloatingwidget.cpp
Normal file
179
src/gui/qgsfloatingwidget.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
/***************************************************************************
|
||||
qgsfloatingwidget.cpp
|
||||
---------------------
|
||||
begin : April 2016
|
||||
copyright : (C) Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsfloatingwidget.h"
|
||||
#include <QEvent>
|
||||
|
||||
|
||||
//
|
||||
// QgsFloatingWidget
|
||||
//
|
||||
|
||||
QgsFloatingWidget::QgsFloatingWidget( QWidget *parent )
|
||||
: QWidget( parent )
|
||||
, mAnchorWidget( nullptr )
|
||||
, mParentEventFilter( nullptr )
|
||||
, mAnchorEventFilter( nullptr )
|
||||
, mFloatAnchorPoint( BottomMiddle )
|
||||
, mAnchorWidgetAnchorPoint( TopMiddle )
|
||||
{
|
||||
if ( parent )
|
||||
{
|
||||
mParentEventFilter = new QgsFloatingWidgetEventFilter( parent );
|
||||
parent->installEventFilter( mParentEventFilter );
|
||||
connect( mParentEventFilter, SIGNAL( anchorPointChanged() ), this, SLOT( anchorPointChanged() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFloatingWidget::setAnchorWidget( QWidget *widget )
|
||||
{
|
||||
// remove existing event filter
|
||||
if ( mAnchorWidget )
|
||||
{
|
||||
mAnchorWidget->removeEventFilter( mAnchorEventFilter );
|
||||
delete mAnchorEventFilter;
|
||||
mAnchorEventFilter = nullptr;
|
||||
}
|
||||
|
||||
mAnchorWidget = widget;
|
||||
if ( mAnchorWidget )
|
||||
{
|
||||
mAnchorEventFilter = new QgsFloatingWidgetEventFilter( mAnchorWidget );
|
||||
mAnchorWidget->installEventFilter( mAnchorEventFilter );
|
||||
connect( mAnchorEventFilter, SIGNAL( anchorPointChanged() ), this, SLOT( anchorPointChanged() ) );
|
||||
}
|
||||
|
||||
anchorPointChanged();
|
||||
}
|
||||
|
||||
QWidget *QgsFloatingWidget::anchorWidget()
|
||||
{
|
||||
return mAnchorWidget;
|
||||
}
|
||||
|
||||
void QgsFloatingWidget::showEvent( QShowEvent *e )
|
||||
{
|
||||
anchorPointChanged();
|
||||
QWidget::showEvent( e );
|
||||
}
|
||||
|
||||
void QgsFloatingWidget::anchorPointChanged()
|
||||
{
|
||||
if ( mAnchorWidget )
|
||||
{
|
||||
QPoint anchorWidgetOrigin;
|
||||
|
||||
switch ( mAnchorWidgetAnchorPoint )
|
||||
{
|
||||
case TopLeft:
|
||||
anchorWidgetOrigin = QPoint( 0, 0 );
|
||||
break;
|
||||
case TopMiddle:
|
||||
anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, 0 );
|
||||
break;
|
||||
case TopRight:
|
||||
anchorWidgetOrigin = QPoint( mAnchorWidget->width(), 0 );
|
||||
break;
|
||||
case MiddleLeft:
|
||||
anchorWidgetOrigin = QPoint( 0, mAnchorWidget->height() / 2 );
|
||||
break;
|
||||
case Middle:
|
||||
anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, mAnchorWidget->height() / 2 );
|
||||
break;
|
||||
case MiddleRight:
|
||||
anchorWidgetOrigin = QPoint( mAnchorWidget->width(), mAnchorWidget->height() / 2 );
|
||||
break;
|
||||
case BottomLeft:
|
||||
anchorWidgetOrigin = QPoint( 0, mAnchorWidget->height() );
|
||||
break;
|
||||
case BottomMiddle:
|
||||
anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, mAnchorWidget->height() );
|
||||
break;
|
||||
case BottomRight:
|
||||
anchorWidgetOrigin = QPoint( mAnchorWidget->width(), mAnchorWidget->height() );
|
||||
break;
|
||||
}
|
||||
|
||||
anchorWidgetOrigin = mAnchorWidget->mapTo( parentWidget(), anchorWidgetOrigin );
|
||||
int anchorX = anchorWidgetOrigin.x();
|
||||
int anchorY = anchorWidgetOrigin.y();
|
||||
|
||||
switch ( mFloatAnchorPoint )
|
||||
{
|
||||
case TopLeft:
|
||||
break;
|
||||
case TopMiddle:
|
||||
anchorX = anchorX - width() / 2;
|
||||
break;
|
||||
case TopRight:
|
||||
anchorX = anchorX - width();
|
||||
break;
|
||||
case MiddleLeft:
|
||||
anchorY = anchorY - height() / 2;
|
||||
break;
|
||||
case Middle:
|
||||
anchorY = anchorY - height() / 2;
|
||||
anchorX = anchorX - width() / 2;
|
||||
break;
|
||||
case MiddleRight:
|
||||
anchorX = anchorX - width();
|
||||
anchorY = anchorY - height() / 2;
|
||||
break;
|
||||
case BottomLeft:
|
||||
anchorY = anchorY - height();
|
||||
break;
|
||||
case BottomMiddle:
|
||||
anchorX = anchorX - width() / 2;
|
||||
anchorY = anchorY - height();
|
||||
break;
|
||||
case BottomRight:
|
||||
anchorX = anchorX - width();
|
||||
anchorY = anchorY - height();
|
||||
break;
|
||||
}
|
||||
|
||||
// constrain x so that widget floats within parent widget
|
||||
anchorX = qBound( 0, anchorX, parentWidget()->width() - width() );
|
||||
|
||||
move( anchorX, anchorY );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// QgsFloatingWidgetEventFilter
|
||||
//
|
||||
|
||||
/// @cond PRIVATE
|
||||
QgsFloatingWidgetEventFilter::QgsFloatingWidgetEventFilter( QWidget *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool QgsFloatingWidgetEventFilter::eventFilter( QObject *object, QEvent *event )
|
||||
{
|
||||
Q_UNUSED( object );
|
||||
switch ( event->type() )
|
||||
{
|
||||
case QEvent::Move:
|
||||
case QEvent::Resize:
|
||||
emit anchorPointChanged();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///@endcond
|
130
src/gui/qgsfloatingwidget.h
Normal file
130
src/gui/qgsfloatingwidget.h
Normal file
@ -0,0 +1,130 @@
|
||||
/***************************************************************************
|
||||
qgsfloatingwidget.h
|
||||
-------------------
|
||||
begin : April 2016
|
||||
copyright : (C) Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSFLOATINGWIDGET_H
|
||||
#define QGSFLOATINGWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsFloatingWidget
|
||||
* A QWidget subclass for creating widgets which float outside of the normal Qt layout
|
||||
* system. Floating widgets use an "anchor widget" to determine how they are anchored
|
||||
* within their parent widget.
|
||||
* \note Added in version 2.16
|
||||
*/
|
||||
|
||||
class GUI_EXPORT QgsFloatingWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//! Reference points for anchoring widget position
|
||||
enum AnchorPoint
|
||||
{
|
||||
TopLeft, //!< Top-left of widget
|
||||
TopMiddle, //!< Top center of widget
|
||||
TopRight, //!< Top-right of widget
|
||||
MiddleLeft, //!< Middle left of widget
|
||||
Middle, //!< Middle of widget
|
||||
MiddleRight, //!< Middle right of widget
|
||||
BottomLeft, //!< Bottom-left of widget
|
||||
BottomMiddle, //!< Bottom center of widget
|
||||
BottomRight, //!< Bottom-right of widget
|
||||
};
|
||||
|
||||
QgsFloatingWidget( QWidget* parent = nullptr );
|
||||
|
||||
/** Sets the widget to "anchor" the floating widget to. The floating widget will be repositioned whenever the
|
||||
* anchor widget moves or is resized so that it maintains the same relative position to the anchor widget.
|
||||
* @param widget anchor widget. Both the floating widget and the anchor widget must share some common parent.
|
||||
* @see anchorWidget()
|
||||
*/
|
||||
void setAnchorWidget( QWidget* widget );
|
||||
|
||||
/** Returns the widget that the floating widget is "anchored" tto. The floating widget will be repositioned whenever the
|
||||
* anchor widget moves or is resized so that it maintains the same relative position to the anchor widget.
|
||||
* @see setAnchorWidget()
|
||||
*/
|
||||
QWidget* anchorWidget();
|
||||
|
||||
/** Returns the floating widget's anchor point, which corresponds to the point on the widget which should remain
|
||||
* fixed in the same relative position whenever the widget's parent is resized or moved.
|
||||
* @see setAnchorPoint()
|
||||
*/
|
||||
AnchorPoint anchorPoint() const { return mFloatAnchorPoint; }
|
||||
|
||||
/** Sets the floating widget's anchor point, which corresponds to the point on the widget which should remain
|
||||
* fixed in the same relative position whenever the widget's parent is resized or moved.
|
||||
* @param point anchor point
|
||||
* @see anchorPoint()
|
||||
*/
|
||||
void setAnchorPoint( AnchorPoint point ) { mFloatAnchorPoint = point; anchorPointChanged(); }
|
||||
|
||||
/** Returns the anchor widget's anchor point, which corresponds to the point on the anchor widget which
|
||||
* the floating widget should "attach" to. The floating widget should remain fixed in the same relative position
|
||||
* to this anchor widget whenever the widget's parent is resized or moved.
|
||||
* @see setAnchorWidgetPoint()
|
||||
*/
|
||||
AnchorPoint anchorWidgetPoint() const { return mAnchorWidgetAnchorPoint; }
|
||||
|
||||
/** Returns the anchor widget's anchor point, which corresponds to the point on the anchor widget which
|
||||
* the floating widget should "attach" to. The floating widget should remain fixed in the same relative position
|
||||
* to this anchor widget whenever the widget's parent is resized or moved.
|
||||
* @see setAnchorWidgetPoint()
|
||||
*/
|
||||
void setAnchorWidgetPoint( AnchorPoint point ) { mAnchorWidgetAnchorPoint = point; anchorPointChanged(); }
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent* e ) override;
|
||||
|
||||
private slots:
|
||||
|
||||
//! Repositions the floating widget to a changed anchor point
|
||||
void anchorPointChanged();
|
||||
|
||||
private:
|
||||
|
||||
QWidget* mAnchorWidget;
|
||||
QObject* mParentEventFilter;
|
||||
QObject* mAnchorEventFilter;
|
||||
AnchorPoint mFloatAnchorPoint;
|
||||
AnchorPoint mAnchorWidgetAnchorPoint;
|
||||
|
||||
};
|
||||
|
||||
/// @cond PRIVATE
|
||||
|
||||
class QgsFloatingWidgetEventFilter: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
QgsFloatingWidgetEventFilter( QWidget* parent = nullptr );
|
||||
|
||||
virtual bool eventFilter( QObject* object, QEvent* event ) override;
|
||||
|
||||
signals:
|
||||
|
||||
//! Emitted when the filter's parent is moved or resized
|
||||
void anchorPointChanged();
|
||||
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
#endif // QGSFLOATINGWIDGET_H
|
@ -49,6 +49,7 @@ ADD_PYTHON_TEST(PyQgsFeatureIterator test_qgsfeatureiterator.py)
|
||||
ADD_PYTHON_TEST(PyQgsField test_qgsfield.py)
|
||||
ADD_PYTHON_TEST(PyQgsFieldModel test_qgsfieldmodel.py)
|
||||
ADD_PYTHON_TEST(PyQgsFilterLineEdit test_qgsfilterlineedit.py)
|
||||
ADD_PYTHON_TEST(PyQgsFloatingWidget test_qgsfloatingwidget.py)
|
||||
ADD_PYTHON_TEST(PyQgsFontUtils test_qgsfontutils.py)
|
||||
ADD_PYTHON_TEST(PyQgsGeometryAvoidIntersections test_qgsgeometry_avoid_intersections.py)
|
||||
ADD_PYTHON_TEST(PyQgsGeometryGeneratorSymbolLayer test_qgsgeometrygeneratorsymbollayer.py)
|
||||
|
201
tests/src/python/test_qgsfloatingwidget.py
Normal file
201
tests/src/python/test_qgsfloatingwidget.py
Normal file
@ -0,0 +1,201 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for QgsFloatingWidget.
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
__author__ = 'Nyall Dawson'
|
||||
__date__ = '26/04/2016'
|
||||
__copyright__ = 'Copyright 2016, The QGIS Project'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
from PyQt.QtGui import QWidget, QGridLayout
|
||||
|
||||
import os
|
||||
|
||||
from qgis.gui import (
|
||||
QgsFloatingWidget
|
||||
)
|
||||
|
||||
from qgis.testing import start_app, unittest
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsFloatingWidget(unittest.TestCase):
|
||||
|
||||
def testAnchor(self):
|
||||
""" test setting anchor point for widget """
|
||||
main_frame = QWidget()
|
||||
gl = QGridLayout()
|
||||
main_frame.setLayout(gl)
|
||||
main_frame.setMinimumSize(800, 600)
|
||||
|
||||
anchor_widget = QWidget(main_frame)
|
||||
anchor_widget.setMinimumSize(300, 200)
|
||||
main_frame.layout().addWidget(anchor_widget, 1, 1)
|
||||
gl.setColumnStretch(0, 1)
|
||||
gl.setColumnStretch(1, 0)
|
||||
gl.setColumnStretch(2, 1)
|
||||
gl.setRowStretch(0, 1)
|
||||
gl.setRowStretch(1, 0)
|
||||
gl.setRowStretch(2, 1)
|
||||
|
||||
# 103 = WA_DontShowOnScreen (not available in PyQt)
|
||||
main_frame.setAttribute(103)
|
||||
main_frame.show()
|
||||
|
||||
fw = qgis.gui.QgsFloatingWidget(main_frame)
|
||||
fw.setMinimumSize(100, 50)
|
||||
fw.setAnchorWidget(anchor_widget)
|
||||
|
||||
tests = [{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 250, 'y': 200},
|
||||
{'anchorPoint': QgsFloatingWidget.TopMiddle, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 200, 'y': 200},
|
||||
{'anchorPoint': QgsFloatingWidget.TopRight, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 150, 'y': 200},
|
||||
{'anchorPoint': QgsFloatingWidget.MiddleLeft, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 250, 'y': 175},
|
||||
{'anchorPoint': QgsFloatingWidget.Middle, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 200, 'y': 175},
|
||||
{'anchorPoint': QgsFloatingWidget.MiddleRight, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 150, 'y': 175},
|
||||
{'anchorPoint': QgsFloatingWidget.BottomLeft, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 250, 'y': 150},
|
||||
{'anchorPoint': QgsFloatingWidget.BottomMiddle, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 200, 'y': 150},
|
||||
{'anchorPoint': QgsFloatingWidget.BottomRight, 'widgetAnchorPoint': QgsFloatingWidget.TopLeft, 'x': 150, 'y': 150},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.TopMiddle, 'x': 400, 'y': 200},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.TopRight, 'x': 550, 'y': 200},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.MiddleLeft, 'x': 250, 'y': 300},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.Middle, 'x': 400, 'y': 300},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.MiddleRight, 'x': 550, 'y': 300},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.BottomLeft, 'x': 250, 'y': 400},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.BottomMiddle, 'x': 400, 'y': 400},
|
||||
{'anchorPoint': QgsFloatingWidget.TopLeft, 'widgetAnchorPoint': QgsFloatingWidget.BottomRight, 'x': 550, 'y': 400}]
|
||||
|
||||
for t in tests:
|
||||
fw.setAnchorPoint(t['anchorPoint'])
|
||||
fw.setAnchorWidgetPoint(t['widgetAnchorPoint'])
|
||||
self.assertEqual(fw.pos().x(), t['x'])
|
||||
self.assertEqual(fw.pos().y(), t['y'])
|
||||
|
||||
def testMovingResizingAnchorWidget(self):
|
||||
""" test that moving or resizing the anchor widget updates the floating widget position """
|
||||
main_frame = QWidget()
|
||||
gl = QGridLayout()
|
||||
main_frame.setLayout(gl)
|
||||
main_frame.setMinimumSize(800, 600)
|
||||
|
||||
anchor_widget = QWidget(main_frame)
|
||||
anchor_widget.setFixedSize(300, 200)
|
||||
main_frame.layout().addWidget(anchor_widget, 1, 1)
|
||||
gl.setColumnStretch(0, 1)
|
||||
gl.setColumnStretch(1, 0)
|
||||
gl.setColumnStretch(2, 1)
|
||||
gl.setRowStretch(0, 1)
|
||||
gl.setRowStretch(1, 0)
|
||||
gl.setRowStretch(2, 1)
|
||||
|
||||
# 103 = WA_DontShowOnScreen (not available in PyQt)
|
||||
main_frame.setAttribute(103)
|
||||
main_frame.show()
|
||||
|
||||
fw = qgis.gui.QgsFloatingWidget(main_frame)
|
||||
fw.setMinimumSize(100, 50)
|
||||
fw.setAnchorWidget(anchor_widget)
|
||||
|
||||
fw.setAnchorPoint(QgsFloatingWidget.TopLeft)
|
||||
fw.setAnchorWidgetPoint(QgsFloatingWidget.TopLeft)
|
||||
|
||||
self.assertEqual(fw.pos().x(), 250)
|
||||
self.assertEqual(fw.pos().y(), 200)
|
||||
|
||||
# now resize anchor widget
|
||||
anchor_widget.setFixedSize(400, 300)
|
||||
# force layout recalculation
|
||||
main_frame.layout().invalidate()
|
||||
main_frame.layout().activate()
|
||||
self.assertEqual(fw.pos().x(), 200)
|
||||
self.assertEqual(fw.pos().y(), 150)
|
||||
|
||||
# now move anchor widget
|
||||
anchor_widget.move(100, 110)
|
||||
self.assertEqual(fw.pos().x(), 100)
|
||||
self.assertEqual(fw.pos().y(), 110)
|
||||
|
||||
def testResizingParentWidget(self):
|
||||
""" test resizing parent widget correctly repositions floating widget"""
|
||||
main_frame = QWidget()
|
||||
gl = QGridLayout()
|
||||
main_frame.setLayout(gl)
|
||||
main_frame.setMinimumSize(800, 600)
|
||||
|
||||
anchor_widget = QWidget(main_frame)
|
||||
anchor_widget.setFixedSize(300, 200)
|
||||
main_frame.layout().addWidget(anchor_widget, 1, 1)
|
||||
gl.setColumnStretch(0, 1)
|
||||
gl.setColumnStretch(1, 0)
|
||||
gl.setColumnStretch(2, 1)
|
||||
gl.setRowStretch(0, 1)
|
||||
gl.setRowStretch(1, 0)
|
||||
gl.setRowStretch(2, 1)
|
||||
|
||||
# 103 = WA_DontShowOnScreen (not available in PyQt)
|
||||
main_frame.setAttribute(103)
|
||||
main_frame.show()
|
||||
|
||||
fw = qgis.gui.QgsFloatingWidget(main_frame)
|
||||
fw.setMinimumSize(100, 50)
|
||||
fw.setAnchorWidget(anchor_widget)
|
||||
|
||||
fw.setAnchorPoint(QgsFloatingWidget.TopLeft)
|
||||
fw.setAnchorWidgetPoint(QgsFloatingWidget.TopLeft)
|
||||
|
||||
self.assertEqual(fw.pos().x(), 250)
|
||||
self.assertEqual(fw.pos().y(), 200)
|
||||
|
||||
# now resize parent widget
|
||||
main_frame.setFixedSize(1000, 800)
|
||||
# force layout recalculation
|
||||
main_frame.layout().invalidate()
|
||||
main_frame.layout().activate()
|
||||
self.assertEqual(fw.pos().x(), 350)
|
||||
self.assertEqual(fw.pos().y(), 300)
|
||||
|
||||
def testPositionConstrainedToParent(self):
|
||||
""" test that floating widget will be placed inside parent when possible """
|
||||
main_frame = QWidget()
|
||||
gl = QGridLayout()
|
||||
main_frame.setLayout(gl)
|
||||
main_frame.setMinimumSize(800, 600)
|
||||
|
||||
anchor_widget = QWidget(main_frame)
|
||||
anchor_widget.setFixedSize(300, 200)
|
||||
main_frame.layout().addWidget(anchor_widget, 1, 1)
|
||||
gl.setColumnStretch(0, 1)
|
||||
gl.setColumnStretch(1, 0)
|
||||
gl.setColumnStretch(2, 1)
|
||||
gl.setRowStretch(0, 1)
|
||||
gl.setRowStretch(1, 0)
|
||||
gl.setRowStretch(2, 1)
|
||||
|
||||
main_frame.setAttribute(103)
|
||||
main_frame.show()
|
||||
|
||||
fw = qgis.gui.QgsFloatingWidget(main_frame)
|
||||
fw.setMinimumSize(300, 50)
|
||||
fw.setAnchorWidget(anchor_widget)
|
||||
|
||||
fw.setAnchorPoint(QgsFloatingWidget.TopRight)
|
||||
fw.setAnchorWidgetPoint(QgsFloatingWidget.TopLeft)
|
||||
|
||||
# x-position should be 0, not -50
|
||||
self.assertEqual(fw.pos().x(), 0)
|
||||
|
||||
fw.setAnchorPoint(QgsFloatingWidget.TopLeft)
|
||||
fw.setAnchorWidgetPoint(QgsFloatingWidget.TopRight)
|
||||
|
||||
# x-position should be 500, not 600
|
||||
self.assertEqual(fw.pos().x(), 500)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user