mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-08 00:05:09 -04:00
[api] Make QgsLayerTreeView proxy handling more flexible
Allow use of custom QgsLayerTreeProxyModel subclasses
This commit is contained in:
parent
6c63043138
commit
1fbddb214d
@ -7,12 +7,13 @@ try:
|
|||||||
except (NameError, AttributeError):
|
except (NameError, AttributeError):
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
QgsLayerTreeViewMenuProvider.__abstract_methods__ = ['createContextMenu']
|
QgsLayerTreeProxyModel.__virtual_methods__ = ['nodeShown']
|
||||||
QgsLayerTreeViewMenuProvider.__group__ = ['layertree']
|
|
||||||
except (NameError, AttributeError):
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
QgsLayerTreeProxyModel.__overridden_methods__ = ['filterAcceptsRow']
|
QgsLayerTreeProxyModel.__overridden_methods__ = ['filterAcceptsRow']
|
||||||
QgsLayerTreeProxyModel.__group__ = ['layertree']
|
QgsLayerTreeProxyModel.__group__ = ['layertree']
|
||||||
except (NameError, AttributeError):
|
except (NameError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
QgsLayerTreeViewMenuProvider.__abstract_methods__ = ['createContextMenu']
|
||||||
|
QgsLayerTreeViewMenuProvider.__group__ = ['layertree']
|
||||||
|
except (NameError, AttributeError):
|
||||||
|
pass
|
||||||
|
@ -75,6 +75,13 @@ shown).
|
|||||||
virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const;
|
virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const;
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool nodeShown( QgsLayerTreeNode *node ) const;
|
||||||
|
%Docstring
|
||||||
|
Returns ``True`` if the specified ``node`` should be shown.
|
||||||
|
|
||||||
|
.. versionadded:: 4.0
|
||||||
|
%End
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -118,6 +125,19 @@ Constructor for QgsLayerTreeView
|
|||||||
%Docstring
|
%Docstring
|
||||||
Overridden :py:func:`~QgsLayerTreeView.setModel` from base class. Only
|
Overridden :py:func:`~QgsLayerTreeView.setModel` from base class. Only
|
||||||
:py:class:`QgsLayerTreeModel` is an acceptable model.
|
:py:class:`QgsLayerTreeModel` is an acceptable model.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This method automatically creates a :py:class:`QgsLayerTreeProxyModel` to use as a proxy.
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setModel( QgsLayerTreeModel *model, QgsLayerTreeProxyModel *proxyModel );
|
||||||
|
%Docstring
|
||||||
|
Sets the ``model`` and ``proxyModel`` for the view.
|
||||||
|
|
||||||
|
Use this method when a custom proxy model is required.
|
||||||
|
|
||||||
|
.. versionadded:: 4.0
|
||||||
%End
|
%End
|
||||||
|
|
||||||
QgsLayerTreeModel *layerTreeModel() const;
|
QgsLayerTreeModel *layerTreeModel() const;
|
||||||
|
@ -7,12 +7,13 @@ try:
|
|||||||
except (NameError, AttributeError):
|
except (NameError, AttributeError):
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
QgsLayerTreeViewMenuProvider.__abstract_methods__ = ['createContextMenu']
|
QgsLayerTreeProxyModel.__virtual_methods__ = ['nodeShown']
|
||||||
QgsLayerTreeViewMenuProvider.__group__ = ['layertree']
|
|
||||||
except (NameError, AttributeError):
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
QgsLayerTreeProxyModel.__overridden_methods__ = ['filterAcceptsRow']
|
QgsLayerTreeProxyModel.__overridden_methods__ = ['filterAcceptsRow']
|
||||||
QgsLayerTreeProxyModel.__group__ = ['layertree']
|
QgsLayerTreeProxyModel.__group__ = ['layertree']
|
||||||
except (NameError, AttributeError):
|
except (NameError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
QgsLayerTreeViewMenuProvider.__abstract_methods__ = ['createContextMenu']
|
||||||
|
QgsLayerTreeViewMenuProvider.__group__ = ['layertree']
|
||||||
|
except (NameError, AttributeError):
|
||||||
|
pass
|
||||||
|
@ -75,6 +75,13 @@ shown).
|
|||||||
virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const;
|
virtual bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const;
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool nodeShown( QgsLayerTreeNode *node ) const;
|
||||||
|
%Docstring
|
||||||
|
Returns ``True`` if the specified ``node`` should be shown.
|
||||||
|
|
||||||
|
.. versionadded:: 4.0
|
||||||
|
%End
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -118,6 +125,19 @@ Constructor for QgsLayerTreeView
|
|||||||
%Docstring
|
%Docstring
|
||||||
Overridden :py:func:`~QgsLayerTreeView.setModel` from base class. Only
|
Overridden :py:func:`~QgsLayerTreeView.setModel` from base class. Only
|
||||||
:py:class:`QgsLayerTreeModel` is an acceptable model.
|
:py:class:`QgsLayerTreeModel` is an acceptable model.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This method automatically creates a :py:class:`QgsLayerTreeProxyModel` to use as a proxy.
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setModel( QgsLayerTreeModel *model, QgsLayerTreeProxyModel *proxyModel );
|
||||||
|
%Docstring
|
||||||
|
Sets the ``model`` and ``proxyModel`` for the view.
|
||||||
|
|
||||||
|
Use this method when a custom proxy model is required.
|
||||||
|
|
||||||
|
.. versionadded:: 4.0
|
||||||
%End
|
%End
|
||||||
|
|
||||||
QgsLayerTreeModel *layerTreeModel() const;
|
QgsLayerTreeModel *layerTreeModel() const;
|
||||||
|
@ -91,6 +91,15 @@ void QgsLayerTreeView::setModel( QAbstractItemModel *model )
|
|||||||
if ( !treeModel )
|
if ( !treeModel )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto proxyModel = new QgsLayerTreeProxyModel( treeModel, this );
|
||||||
|
proxyModel->setShowPrivateLayers( mShowPrivateLayers );
|
||||||
|
proxyModel->setHideValidLayers( mHideValidLayers );
|
||||||
|
|
||||||
|
setModel( treeModel, proxyModel );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsLayerTreeView::setModel( QgsLayerTreeModel *treeModel, QgsLayerTreeProxyModel *proxyModel )
|
||||||
|
{
|
||||||
if ( mMessageBar )
|
if ( mMessageBar )
|
||||||
connect( treeModel, &QgsLayerTreeModel::messageEmitted, this, [this]( const QString &message, Qgis::MessageLevel level = Qgis::MessageLevel::Info, int duration = 5 ) {
|
connect( treeModel, &QgsLayerTreeModel::messageEmitted, this, [this]( const QString &message, Qgis::MessageLevel level = Qgis::MessageLevel::Info, int duration = 5 ) {
|
||||||
Q_UNUSED( duration )
|
Q_UNUSED( duration )
|
||||||
@ -99,8 +108,7 @@ void QgsLayerTreeView::setModel( QAbstractItemModel *model )
|
|||||||
|
|
||||||
treeModel->addTargetScreenProperties( QgsScreenProperties( screen() ) );
|
treeModel->addTargetScreenProperties( QgsScreenProperties( screen() ) );
|
||||||
|
|
||||||
mProxyModel = new QgsLayerTreeProxyModel( treeModel, this );
|
mProxyModel = proxyModel;
|
||||||
|
|
||||||
connect( mProxyModel, &QAbstractItemModel::rowsInserted, this, &QgsLayerTreeView::modelRowsInserted );
|
connect( mProxyModel, &QAbstractItemModel::rowsInserted, this, &QgsLayerTreeView::modelRowsInserted );
|
||||||
connect( mProxyModel, &QAbstractItemModel::rowsRemoved, this, &QgsLayerTreeView::modelRowsRemoved );
|
connect( mProxyModel, &QAbstractItemModel::rowsRemoved, this, &QgsLayerTreeView::modelRowsRemoved );
|
||||||
|
|
||||||
@ -108,8 +116,6 @@ void QgsLayerTreeView::setModel( QAbstractItemModel *model )
|
|||||||
new ModelTest( mProxyModel, this );
|
new ModelTest( mProxyModel, this );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mProxyModel->setShowPrivateLayers( mShowPrivateLayers );
|
|
||||||
mProxyModel->setHideValidLayers( mHideValidLayers );
|
|
||||||
QTreeView::setModel( mProxyModel );
|
QTreeView::setModel( mProxyModel );
|
||||||
|
|
||||||
connect( treeModel->rootGroup(), &QgsLayerTreeNode::expandedChanged, this, &QgsLayerTreeView::onExpandedChanged );
|
connect( treeModel->rootGroup(), &QgsLayerTreeNode::expandedChanged, this, &QgsLayerTreeView::onExpandedChanged );
|
||||||
|
@ -96,9 +96,14 @@ class GUI_EXPORT QgsLayerTreeProxyModel : public QSortFilterProxyModel
|
|||||||
protected:
|
protected:
|
||||||
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
|
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
|
||||||
|
|
||||||
private:
|
/**
|
||||||
bool nodeShown( QgsLayerTreeNode *node ) const;
|
* Returns TRUE if the specified \a node should be shown.
|
||||||
|
*
|
||||||
|
* \since QGIS 4.0
|
||||||
|
*/
|
||||||
|
virtual bool nodeShown( QgsLayerTreeNode *node ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
QgsLayerTreeModel *mLayerTreeModel = nullptr;
|
QgsLayerTreeModel *mLayerTreeModel = nullptr;
|
||||||
QString mFilterText;
|
QString mFilterText;
|
||||||
bool mShowPrivateLayers = false;
|
bool mShowPrivateLayers = false;
|
||||||
@ -138,9 +143,22 @@ class GUI_EXPORT QgsLayerTreeView : public QTreeView
|
|||||||
explicit QgsLayerTreeView( QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
explicit QgsLayerTreeView( QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||||
~QgsLayerTreeView() override;
|
~QgsLayerTreeView() override;
|
||||||
|
|
||||||
//! Overridden setModel() from base class. Only QgsLayerTreeModel is an acceptable model.
|
/**
|
||||||
|
* Overridden setModel() from base class. Only QgsLayerTreeModel is an acceptable model.
|
||||||
|
*
|
||||||
|
* \note This method automatically creates a QgsLayerTreeProxyModel to use as a proxy.
|
||||||
|
*/
|
||||||
void setModel( QAbstractItemModel *model ) override;
|
void setModel( QAbstractItemModel *model ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the \a model and \a proxyModel for the view.
|
||||||
|
*
|
||||||
|
* Use this method when a custom proxy model is required.
|
||||||
|
*
|
||||||
|
* \since QGIS 4.0
|
||||||
|
*/
|
||||||
|
void setModel( QgsLayerTreeModel *model, QgsLayerTreeProxyModel *proxyModel );
|
||||||
|
|
||||||
//! Gets access to the model casted to QgsLayerTreeModel
|
//! Gets access to the model casted to QgsLayerTreeModel
|
||||||
QgsLayerTreeModel *layerTreeModel() const;
|
QgsLayerTreeModel *layerTreeModel() const;
|
||||||
|
|
||||||
|
@ -22,7 +22,11 @@ from qgis.core import (
|
|||||||
QgsMarkerSymbol,
|
QgsMarkerSymbol,
|
||||||
QgsMapLayerLegend,
|
QgsMapLayerLegend,
|
||||||
)
|
)
|
||||||
from qgis.gui import QgsLayerTreeView, QgsLayerTreeViewDefaultActions
|
from qgis.gui import (
|
||||||
|
QgsLayerTreeView,
|
||||||
|
QgsLayerTreeViewDefaultActions,
|
||||||
|
QgsLayerTreeProxyModel,
|
||||||
|
)
|
||||||
import unittest
|
import unittest
|
||||||
from qgis.testing import start_app, QgisTestCase
|
from qgis.testing import start_app, QgisTestCase
|
||||||
|
|
||||||
@ -814,6 +818,24 @@ class TestQgsLayerTreeView(QgisTestCase):
|
|||||||
view.selectedLegendNodes(), [legend_nodes[0], legend_nodes[2]]
|
view.selectedLegendNodes(), [legend_nodes[0], legend_nodes[2]]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_set_model_and_proxy(self):
|
||||||
|
root = QgsLayerTree()
|
||||||
|
model = QgsLayerTreeModel(root)
|
||||||
|
view = QgsLayerTreeView()
|
||||||
|
|
||||||
|
view.setModel(model)
|
||||||
|
self.assertEqual(view.layerTreeModel(), model)
|
||||||
|
# a proxy should have been auto-created
|
||||||
|
self.assertIsInstance(view.model(), QgsLayerTreeProxyModel)
|
||||||
|
|
||||||
|
# set an explicit proxy
|
||||||
|
root2 = QgsLayerTree()
|
||||||
|
model2 = QgsLayerTreeModel(root2)
|
||||||
|
my_proxy = QgsLayerTreeProxyModel(model2, None)
|
||||||
|
view.setModel(model2, my_proxy)
|
||||||
|
self.assertEqual(view.layerTreeModel(), model2)
|
||||||
|
self.assertEqual(view.model(), my_proxy)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user