Skip to content

Commit 2f0060c

Browse files
committedMar 13, 2023
[layouts] Use a background thread to filter legend content by map
Avoids potentially massive UI hangs while working with layouts with filtered legends. Fixes #51233 Fixes #48326 Fixes #51455 Fixes #51452
1 parent 885c0b6 commit 2f0060c

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed
 

‎python/core/auto_generated/layout/qgslayoutitemlegend.sip.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ Returns the legend's renderer settings object.
630630

631631
virtual bool accept( QgsStyleEntityVisitorInterface *visitor ) const;
632632

633+
virtual bool isRefreshing() const;
634+
633635

634636
public slots:
635637

‎src/core/layout/qgslayoutitemlegend.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ QgsLayoutItemLegend::QgsLayoutItemLegend( QgsLayout *layout )
5252

5353
mTitle = mSettings.title();
5454

55+
connect( mLegendModel.get(), &QgsLayerTreeModel::hitTestStarted, this, [ = ] { emit backgroundTaskCountChanged( 1 ); } );
56+
connect( mLegendModel.get(), &QgsLayerTreeModel::hitTestCompleted, this, [ = ]
57+
{
58+
adjustBoxSize();
59+
emit backgroundTaskCountChanged( 0 );
60+
} );
61+
5562
// Connect to the main layertreeroot.
5663
// It serves in "auto update mode" as a medium between the main app legend and this one
5764
connect( mLayout->project()->layerTreeRoot(), &QgsLayerTreeNode::customPropertyChanged, this, &QgsLayoutItemLegend::nodeCustomPropertyChanged );
@@ -106,6 +113,14 @@ void QgsLayoutItemLegend::paint( QPainter *painter, const QStyleOptionGraphicsIt
106113
doUpdateFilterByMap();
107114
}
108115

116+
if ( mLayout )
117+
{
118+
if ( !mLayout->renderContext().isPreviewRender() && mLegendModel->hitTestInProgress() )
119+
{
120+
mLegendModel->waitForHitTestBlocking();
121+
}
122+
}
123+
109124
const int dpi = painter->device()->logicalDpiX();
110125
const double dotsPerMM = dpi / 25.4;
111126

@@ -1270,6 +1285,11 @@ bool QgsLayoutItemLegend::accept( QgsStyleEntityVisitorInterface *visitor ) cons
12701285
return visit( mLegendModel->rootGroup( ) );
12711286
}
12721287

1288+
bool QgsLayoutItemLegend::isRefreshing() const
1289+
{
1290+
return mLegendModel->hitTestInProgress();
1291+
}
1292+
12731293

12741294
// -------------------------------------------------------------------------
12751295

@@ -1279,6 +1299,7 @@ QgsLegendModel::QgsLegendModel( QgsLayerTree *rootNode, QObject *parent, QgsLayo
12791299
{
12801300
setFlag( QgsLayerTreeModel::AllowLegendChangeState, false );
12811301
setFlag( QgsLayerTreeModel::AllowNodeReorder, true );
1302+
setFlag( QgsLayerTreeModel::UseThreadedHitTest, true );
12821303
connect( this, &QgsLegendModel::dataChanged, this, &QgsLegendModel::refreshLegend );
12831304
}
12841305

@@ -1288,6 +1309,7 @@ QgsLegendModel::QgsLegendModel( QgsLayerTree *rootNode, QgsLayoutItemLegend *la
12881309
{
12891310
setFlag( QgsLayerTreeModel::AllowLegendChangeState, false );
12901311
setFlag( QgsLayerTreeModel::AllowNodeReorder, true );
1312+
setFlag( QgsLayerTreeModel::UseThreadedHitTest, true );
12911313
connect( this, &QgsLegendModel::dataChanged, this, &QgsLegendModel::refreshLegend );
12921314
}
12931315

‎src/core/layout/qgslayoutitemlegend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ class CORE_EXPORT QgsLayoutItemLegend : public QgsLayoutItem
589589
QgsExpressionContext createExpressionContext() const override;
590590
ExportLayerBehavior exportLayerBehavior() const override;
591591
bool accept( QgsStyleEntityVisitorInterface *visitor ) const override;
592+
bool isRefreshing() const override;
592593

593594
public slots:
594595

0 commit comments

Comments
 (0)
Please sign in to comment.