QGIS API Documentation 3.34.0-Prizren (ffbdd678812)
Loading...
Searching...
No Matches
qgsmaptip.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaptips.cpp - Query a layer and show a maptip on the canvas
3 ---------------------
4 begin : October 2007
5 copyright : (C) 2007 by Gary Sherman
6 email : sherman @ mrcc dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15// QGIS includes
16#include "qgsfeatureiterator.h"
17#include "qgsmapcanvas.h"
18#include "qgsmaptool.h"
19#include "qgsvectorlayer.h"
20#include "qgsrasterlayer.h"
21#include "qgsexpression.h"
22#include "qgslogger.h"
23#include "qgssettings.h"
24#include "qgswebview.h"
25#include "qgswebframe.h"
26#include "qgsapplication.h"
27#include "qgsrenderer.h"
30#include "qgsrendercontext.h"
31#include "qgsmapcanvasutils.h"
32
33// Qt includes
34#include <QPoint>
35#include <QToolTip>
36#include <QSettings>
37#include <QLabel>
38#include <QDesktopServices>
39#if WITH_QTWEBKIT
40#include <QWebElement>
41#endif
42#include <QHBoxLayout>
43
44#include "qgsmaptip.h"
45
46
47const QString QgsMapTip::sMapTipTemplate = "<html>\n"
48 " <head>\n"
49 " <style>\n"
50 " body {\n"
51 " margin: 0;\n"
52 " font: %1pt \"%2\";\n"
53 " color: %3;\n"
54 " width: %4px;\n"
55 " }\n"
56 " #QgsWebViewContainer {\n"
57 " background-color: %5;\n"
58 " border: 1px solid %6;\n"
59 " display: inline-block;\n"
60 " margin: 0\n"
61 " }\n"
62 " #QgsWebViewContainerInner {\n"
63 " margin: 5px\n"
64 " }\n"
65 " </style>\n"
66 " </head>\n"
67 " <body>\n"
68 " <div id='QgsWebViewContainer'>\n"
69 " <div id='QgsWebViewContainerInner'>\n"
70 " %7\n"
71 " </div>\n"
72 " </div>\n"
73 " </body>\n"
74 "</html>\n";
75
76
78{
79 // Init the visible flag
80 mMapTipVisible = false;
81
82 mDelayedClearTimer.setSingleShot( true );
83 connect( &mDelayedClearTimer, &QTimer::timeout, this, [ = ]() {this->clear();} );
84}
85
87 QgsPointXY &mapPosition,
88 const QPoint &pixelPosition,
89 QgsMapCanvas *pMapCanvas )
90{
91 // Do the search using the active layer and the preferred label field for the
92 // layer. The label field must be defined in the layer configuration
93 // file/database. The code required to do this is similar to identify, except
94 // we only want the first qualifying feature and we will only display the
95 // field defined as the label field in the layer configuration file/database
96
97 // Do not render map tips if the layer is not visible
98 if ( !pMapCanvas->layers( true ).contains( pLayer ) )
99 {
100 return;
101 }
102
103 // Do not render a new map tip when the mouse hovers an existing one
104 if ( mWebView && mWebView->underMouse() )
105 {
106 return;
107 }
108
109 // Show the maptip on the canvas
110 QString tipText, lastTipText, tipHtml;
111
112 if ( ! mWebView )
113 {
114 mWebView = new QgsWebView( pMapCanvas );
115 // Make the webwiew transparent
116
117 // Setting the background color to 'transparent' does not play nice
118 // with webkit scrollbars, that are rendered as black rectangles (#54683)
119 QColor transparentColor = mWebView->palette().color( QPalette::Window );
120 transparentColor.setAlpha( 0 );
121 mWebView->setStyleSheet( QString( "background:%1;" ).arg( transparentColor.name( QColor::HexArgb ) ) );
122
123
124#if WITH_QTWEBKIT
125 mWebView->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );//Handle link clicks by yourself
126 mWebView->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
127 connect( mWebView, &QWebView::linkClicked, this, &QgsMapTip::onLinkClicked );
128 connect( mWebView, &QWebView::loadFinished, this, [ = ]( bool ) { resizeAndMoveToolTip(); } );
129#endif
130
131 mWebView->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
132 mWebView->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
133 mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
134
135 // Disable scrollbars, avoid random resizing issues
136 mWebView->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
137 mWebView->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
138
139 }
140
141 // Only supported layer types here:
142 switch ( pLayer->type() )
143 {
145 tipText = fetchFeature( pLayer, mapPosition, pMapCanvas );
146 break;
148 tipText = fetchRaster( pLayer, mapPosition, pMapCanvas );
149 break;
150 default:
151 break;
152 }
153
154 mMapTipVisible = !tipText.isEmpty();
155 if ( !mMapTipVisible )
156 {
157 clear();
158 return;
159 }
160
161 if ( tipText == lastTipText )
162 {
163 return;
164 }
165
166 // Compute offset from the cursor position
167 int cursorOffset = 0;
169 {
170 // The following calculations are taken
171 // from QgsApplication::getThemeCursor, and are used to calculate the correct cursor size
172 // for both hi-dpi and non-hi-dpi screens.
173 double scale = Qgis::UI_SCALE_FACTOR * QgsApplication::instance()->fontMetrics().height() / 32.0;
174 cursorOffset = static_cast< int >( std::ceil( scale * 32 ) );
175 }
176
177 // Ensures the map tip is never larger than the available space
178 const int MAX_WIDTH = std::max( pixelPosition.x(), pMapCanvas->width() - pixelPosition.x() ) - cursorOffset - 5;
179 const int MAX_HEIGHT = std::max( pixelPosition.y(), pMapCanvas->height() - pixelPosition.y() ) - 5;
180
181 mWebView->setMaximumSize( MAX_WIDTH, MAX_HEIGHT );
182
183 tipHtml = QgsMapTip::htmlText( tipText, MAX_WIDTH );
184
185 QgsDebugMsgLevel( tipHtml, 2 );
186
187 mPosition = pixelPosition;
188 mMapCanvas = pMapCanvas;
189 mWebView->setHtml( tipHtml );
190 lastTipText = tipText;
191
192#if !WITH_QTWEBKIT
193 resizeAndMoveToolTip();
194#endif
195
196}
197
198void QgsMapTip::resizeAndMoveToolTip()
199{
200#if WITH_QTWEBKIT
201 // Get the content size
202 const QWebElement container = mWebView->page()->mainFrame()->findFirstElement(
203 QStringLiteral( "#QgsWebViewContainer" ) );
204 const int width = container.geometry().width();
205 const int height = container.geometry().height();
206 mWebView->resize( width, height );
207#else
208 mWebView->adjustSize();
209#endif
210
211 int cursorOffset = 0;
212 // attempt to shift the tip away from the cursor.
214 {
215 // The following calculations are taken
216 // from QgsApplication::getThemeCursor, and are used to calculate the correct cursor size
217 // for both hi-dpi and non-hi-dpi screens.
218 double scale = Qgis::UI_SCALE_FACTOR * QgsApplication::instance()->fontMetrics().height() / 32.0;
219 cursorOffset = static_cast< int >( std::ceil( scale * 32 ) );
220 }
221
222 if ( mMapCanvas == nullptr )
223 {
224 mWebView->move( mPosition );
225 mWebView->show();
226 return;
227 }
228
229 // Check if there is enough space to the right of the cursor
230 int availableWidthRight = mMapCanvas->width() - mPosition.x() - cursorOffset;
231 int availableWidthLeft = mPosition.x() - cursorOffset;
232 int availableHeightBottom = mMapCanvas->height() - mPosition.y();
233 int availableHeightTop = mPosition.y();
234 int x, y;
235 // If there is enough space on the right, or more space on the right than on the left, move the map tip to the right of the cursor
236 if ( mWebView->width() < availableWidthRight || availableWidthRight > availableWidthLeft )
237 {
238 x = mPosition.x() + cursorOffset;
239 }
240 // Otherwise, move the map tip to the left of the cursor
241 else
242 {
243 x = mPosition.x() - mWebView->width() - cursorOffset;
244 }
245
246 // If there is enough space on the bottom, or more space on the bottom than on the top, move the map tip to the bottom of the cursor
247 if ( mWebView->height() < availableHeightBottom || availableHeightBottom > availableHeightTop )
248 {
249 y = mPosition.y();
250 }
251 // Otherwise, move the map tip to the top of the cursor
252 else
253 {
254 y = mPosition.y() - mWebView->height();
255 }
256 mWebView->move( x, y );
257 mWebView->show();
258}
259
260void QgsMapTip::clear( QgsMapCanvas *, int msDelay )
261{
262 if ( !mMapTipVisible )
263 {
264 return;
265 }
266
267 // Skip clearing the map tip if the user interacts with it or the timer still runs
268 if ( mDelayedClearTimer.isActive() || mWebView->underMouse() )
269 {
270 return;
271 }
272
273 if ( msDelay > 0 )
274 {
275 mDelayedClearTimer.start( msDelay );
276 return;
277 }
278 mWebView->setHtml( QString() );
279 mWebView->hide();
280
281 // Reset the visible flag
282 mMapTipVisible = false;
283}
284
285QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPointXY &mapPosition, QgsMapCanvas *mapCanvas )
286{
287 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
288 if ( !vlayer || !vlayer->isSpatial() || !vlayer->mapTipsEnabled() )
289 {
290 return QString();
291 }
292
293 if ( !layer->isInScaleRange( mapCanvas->mapSettings().scale() ) ||
294 ( mapCanvas->mapSettings().isTemporal() && !layer->temporalProperties()->isVisibleInTemporalRange( mapCanvas->temporalRange() ) ) )
295 {
296 return QString();
297 }
298
299 const double searchRadius = QgsMapTool::searchRadiusMU( mapCanvas );
300
301 QgsRectangle r;
302 r.setXMinimum( mapPosition.x() - searchRadius );
303 r.setYMinimum( mapPosition.y() - searchRadius );
304 r.setXMaximum( mapPosition.x() + searchRadius );
305 r.setYMaximum( mapPosition.y() + searchRadius );
306
307 r = mapCanvas->mapSettings().mapToLayerCoordinates( layer, r );
308
310 context.appendScope( QgsExpressionContextUtils::mapSettingsScope( mapCanvas->mapSettings() ) );
311 context.appendScope( QgsExpressionContextUtils::mapLayerPositionScope( r.center() ) );
312
313 const QString canvasFilter = QgsMapCanvasUtils::filterForLayer( mapCanvas, vlayer );
314 if ( canvasFilter == QLatin1String( "FALSE" ) )
315 {
316 return QString();
317 }
318
319 const QString mapTip = vlayer->mapTipTemplate();
320 QString tipString;
321 QgsExpression exp( vlayer->displayExpression() );
322 QgsFeature feature;
323
324 QgsFeatureRequest request;
325 request.setFilterRect( r );
327 if ( !canvasFilter.isEmpty() )
328 {
329 request.setFilterExpression( canvasFilter );
330 }
331
332 if ( mapTip.isEmpty() )
333 {
334 exp.prepare( &context );
335 request.setSubsetOfAttributes( exp.referencedColumns(), vlayer->fields() );
336 }
337
339 renderCtx.setExpressionContext( mapCanvas->createExpressionContext() );
341
342 bool filter = false;
343 std::unique_ptr< QgsFeatureRenderer > renderer;
344 if ( vlayer->renderer() )
345 {
346 renderer.reset( vlayer->renderer()->clone() );
347 renderer->startRender( renderCtx, vlayer->fields() );
348 filter = renderer->capabilities() & QgsFeatureRenderer::Filter;
349
350 const QString filterExpression = renderer->filter( vlayer->fields() );
351 if ( ! filterExpression.isEmpty() )
352 {
353 request.combineFilterExpression( filterExpression );
354 }
355 }
356 request.setExpressionContext( renderCtx.expressionContext() );
357
358 QgsFeatureIterator it = vlayer->getFeatures( request );
359 QElapsedTimer timer;
360 timer.start();
361 while ( it.nextFeature( feature ) )
362 {
363 context.setFeature( feature );
364
365 renderCtx.expressionContext().setFeature( feature );
366 if ( filter && renderer && !renderer->willRenderFeature( feature, renderCtx ) )
367 {
368 continue;
369 }
370
371 if ( !mapTip.isEmpty() )
372 {
373 tipString = QgsExpression::replaceExpressionText( mapTip, &context );
374 }
375 else
376 {
377 tipString = exp.evaluate( &context ).toString();
378 }
379
380 if ( !tipString.isEmpty() || timer.elapsed() >= 1000 )
381 {
382 break;
383 }
384 }
385
386 if ( renderer )
387 {
388 renderer->stopRender( renderCtx );
389 }
390
391 return tipString;
392}
393
394QString QgsMapTip::fetchRaster( QgsMapLayer *layer, QgsPointXY &mapPosition, QgsMapCanvas *mapCanvas )
395{
396 QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
397 if ( !rlayer || !rlayer->mapTipsEnabled() )
398 {
399 return QString();
400 }
401
402 if ( !layer->isInScaleRange( mapCanvas->mapSettings().scale() ) ||
403 ( mapCanvas->mapSettings().isTemporal() && !layer->temporalProperties()->isVisibleInTemporalRange( mapCanvas->temporalRange() ) ) )
404 {
405 return QString();
406 }
407
408 if ( rlayer->mapTipTemplate().isEmpty() )
409 {
410 return QString();
411 }
412
413 const QgsPointXY mappedPosition { mapCanvas->mapSettings().mapToLayerCoordinates( layer, mapPosition ) };
414
415 if ( ! layer->extent().contains( mappedPosition ) )
416 {
417 return QString();
418 }
419
421 context.appendScope( QgsExpressionContextUtils::mapSettingsScope( mapCanvas->mapSettings() ) );
422 context.appendScope( QgsExpressionContextUtils::mapLayerPositionScope( mappedPosition ) );
423 return QgsExpression::replaceExpressionText( rlayer->mapTipTemplate(), &context );
424}
425
426QString QgsMapTip::htmlText( const QString &text, int maxWidth )
427{
428
429 const QgsSettings settings;
430 const QFont defaultFont = qApp->font();
431 const int fontSize = defaultFont.pointSize();
432 const QString fontFamily = defaultFont.family();
433 const QString backgroundColor = QgsApplication::palette().base().color().name();
434 const QString strokeColor = QgsApplication::palette().shadow().color().name();
435 const QString textColor = QgsApplication::palette().toolTipText().color().name();
436 return sMapTipTemplate.arg( fontSize ).arg( fontFamily ).arg( textColor ).arg( maxWidth == -1 ? "" : QString::number( maxWidth ) ).arg( backgroundColor ).arg( strokeColor ).arg( text );
437}
438
439// This slot handles all clicks
440void QgsMapTip::onLinkClicked( const QUrl &url )
441{
442 QDesktopServices::openUrl( url );
443}
444
445
446QString QgsMapTip::vectorMapTipPreviewText( QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate, const QString &displayExpression )
447{
448 // Only spatial layers can have map tips
449 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
450 if ( !mapCanvas || !vlayer || !vlayer->isSpatial() )
451 return QString();
452
453 // If no map tip template or display expression is set, return an empty string
454 if ( mapTemplate.isEmpty() && displayExpression.isEmpty() )
455 return QString();
456
457 // Create an expression context
460
461 // Get the first feature if any, and add it to the expression context
462 QgsFeature previewFeature;
463 if ( vlayer->featureCount() > 0 )
464 {
465 QgsFeatureIterator it = vlayer->getFeatures( QgsFeatureRequest().setLimit( 1 ) );
466 it.nextFeature( previewFeature );
467 }
468 else
469 {
470 previewFeature = QgsFeature( vlayer->fields() );
471 }
472 context.setFeature( previewFeature );
473
474 // Generate the map tip text from the context and the mapTipTemplate/displayExpression
475 QString tipText;
476 if ( mapTemplate.isEmpty() )
477 {
478 QgsExpression exp( displayExpression );
479 exp.prepare( &context );
480 tipText = exp.evaluate( &context ).toString();
481 }
482 else
483 {
484 tipText = QgsExpression::replaceExpressionText( mapTemplate, &context );
485 }
486
487 // Insert the map tip text into the html template
488 return QgsMapTip::htmlText( tipText, mapCanvas->width() / 2 );
489
490}
491
492QString QgsMapTip::rasterMapTipPreviewText( QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate )
493{
494 QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
495 if ( !mapCanvas || !rlayer || mapTemplate.isEmpty() )
496 {
497 return QString();
498 }
499
500 // Create an expression context
503
504 // Get the position of the center of the layer, and add it to the expression context
505 const QgsPointXY mappedPosition { layer->extent().center() };
507
508 // Generate the map tip text from the context and the mapTipTemplate
509 const QString tipText = QgsExpression::replaceExpressionText( mapTemplate, &context );
510
511 // Insert the map tip text into the html template
512 return QgsMapTip::htmlText( tipText, mapCanvas->width() / 2 );
513}
@ Vector
Vector layer.
@ Raster
Raster layer.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:4086
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QgsExpressionContextScope * mapLayerPositionScope(const QgsPointXY &position)
Sets the expression context variables which are available for expressions triggered by moving the mou...
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
QVariant evaluate()
Evaluate the feature and return the result.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & combineFilterExpression(const QString &expression)
Modifies the existing filter expression to add an additional expression filter.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:56
static QString filterForLayer(QgsMapCanvas *canvas, QgsVectorLayer *layer)
Constructs a filter to use for selecting features from the given layer, in order to apply filters whi...
Map canvas is a class for displaying all GIS data types on a canvas.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
const QgsDateTimeRange & temporalRange() const
Returns map canvas datetime range.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers shown within the map canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
virtual bool isVisibleInTemporalRange(const QgsDateTimeRange &range) const
Returns true if the layer should be visible and rendered for the specified time range.
Base class for all map layer types.
Definition qgsmaplayer.h:74
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
virtual QgsRectangle extent() const
Returns the extent of the layer.
Qgis::LayerType type
Definition qgsmaplayer.h:81
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
bool mapTipsEnabled
Definition qgsmaplayer.h:85
QString mapTipTemplate
Definition qgsmaplayer.h:84
double scale() const
Returns the calculated map scale.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
void showMapTip(QgsMapLayer *thepLayer, QgsPointXY &mapPosition, const QPoint &pixelPosition, QgsMapCanvas *mpMapCanvas)
Show a maptip at a given point on the map canvas.
Definition qgsmaptip.cpp:86
static QString rasterMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate)
Returns the html that would be displayed in a maptip for a given layer.
static QString vectorMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate, const QString &displayExpression)
Returns the html that would be displayed in a maptip for a given layer.
QgsMapTip()
Default constructor.
Definition qgsmaptip.cpp:77
void clear(QgsMapCanvas *mpMapCanvas=nullptr, int msDelay=0)
Clear the current maptip if it exists.
static double searchRadiusMU(const QgsRenderContext &context)
Gets search radius in map units for given context.
A class to represent a 2D point.
Definition qgspointxy.h:59
double y
Definition qgspointxy.h:63
double x
Definition qgspointxy.h:62
Represents a raster layer.
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
QgsPointXY center() const
Returns the center point of the rectangle.
void setXMaximum(double x)
Set the maximum x value.
Contains information about the context of a rendering operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
This class is a composition of two QSettings instances:
Definition qgssettings.h:63
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
Represents a vector layer which manages a vector based data sets.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QString displayExpression
The QgsWebView class is a collection of stubs to mimic the API of QWebView on systems where the real ...
Definition qgswebview.h:66
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39