QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsvariantutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvariantutils.h
3 ------------------
4 Date : January 2022
5 Copyright : (C) 2022 Nyall Dawson
6 Email : nyall dot dawson at gmail 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
16#include "qgsvariantutils.h"
17
18#include "qgsapplication.h"
19#include "qgslogger.h"
21
22#include <QBitArray>
23#include <QBitmap>
24#include <QBrush>
25#include <QColor>
26#include <QDate>
27#include <QDateTime>
28#include <QIcon>
29#include <QImage>
30#include <QLine>
31#include <QPixmap>
32#include <QQuaternion>
33#include <QRect>
34#include <QString>
35#include <QTime>
36#include <QUuid>
37#include <QVector2D>
38#include <QVector3D>
39#include <QVector4D>
40
41using namespace Qt::StringLiterals;
42
43QString QgsVariantUtils::typeToDisplayString( QMetaType::Type type, QMetaType::Type subType )
44{
45 switch ( type )
46 {
47 case QMetaType::Type::UnknownType:
48 break;
49 case QMetaType::Type::Bool:
50 return QObject::tr( "Boolean" );
51 case QMetaType::Type::Int:
52 return QObject::tr( "Integer (32 bit)" );
53 case QMetaType::Type::UInt:
54 return QObject::tr( "Integer (unsigned 32 bit)" );
55 case QMetaType::Type::LongLong:
56 return QObject::tr( "Integer (64 bit)" );
57 case QMetaType::Type::ULongLong:
58 return QObject::tr( "Integer (unsigned 64 bit)" );
59 case QMetaType::Type::Double:
60 return QObject::tr( "Decimal (double)" );
61 case QMetaType::Type::QChar:
62 return QObject::tr( "Character" );
63 case QMetaType::Type::QVariantMap:
64 return QObject::tr( "Map" );
65 case QMetaType::Type::QVariantList:
66 {
67 switch ( subType )
68 {
69 case QMetaType::Type::Int:
70 return QObject::tr( "Integer List" );
71 case QMetaType::Type::LongLong:
72 return QObject::tr( "Integer (64 bit) List" );
73 case QMetaType::Type::Double:
74 return QObject::tr( "Decimal (double) List" );
75 default:
76 return QObject::tr( "List" );
77 }
78 }
79 case QMetaType::Type::QString:
80 return QObject::tr( "Text (string)" );
81 case QMetaType::Type::QStringList:
82 return QObject::tr( "String List" );
83 case QMetaType::Type::QByteArray:
84 return QObject::tr( "Binary Object (BLOB)" );
85 case QMetaType::Type::QBitArray:
86 return QObject::tr( "Bit Array" );
87 case QMetaType::Type::QDate:
88 return QObject::tr( "Date" );
89 case QMetaType::Type::QTime:
90 return QObject::tr( "Time" );
91 case QMetaType::Type::QDateTime:
92 return QObject::tr( "Date & Time" );
93 case QMetaType::Type::QUrl:
94 return QObject::tr( "URL" );
95 case QMetaType::Type::QLocale:
96 return QObject::tr( "Locale" );
97 case QMetaType::Type::QRect:
98 case QMetaType::Type::QRectF:
99 return QObject::tr( "Rectangle" );
100 case QMetaType::Type::QSize:
101 case QMetaType::Type::QSizeF:
102 return QObject::tr( "Size" );
103 case QMetaType::Type::QLine:
104 case QMetaType::Type::QLineF:
105 return QObject::tr( "Line" );
106 case QMetaType::Type::QPoint:
107 case QMetaType::Type::QPointF:
108 return QObject::tr( "Point" );
109 case QMetaType::Type::QRegularExpression:
110 return QObject::tr( "Regular Expression" );
111 case QMetaType::Type::QVariantHash:
112 return QObject::tr( "Hash" );
113 case QMetaType::Type::QEasingCurve:
114 return QObject::tr( "Easing Curve" );
115 case QMetaType::Type::QUuid:
116 return QObject::tr( "UUID" );
117 case QMetaType::Type::QModelIndex:
118 case QMetaType::Type::QPersistentModelIndex:
119 return QObject::tr( "Model Index" );
120 case QMetaType::Type::QFont:
121 return QObject::tr( "Font" );
122 case QMetaType::Type::QPixmap:
123 return QObject::tr( "Pixmap" );
124 case QMetaType::Type::QBrush:
125 return QObject::tr( "Brush" );
126 case QMetaType::Type::QColor:
127 return QObject::tr( "Color" );
128 case QMetaType::Type::QPalette:
129 return QObject::tr( "Palette" );
130 case QMetaType::Type::QImage:
131 return QObject::tr( "Image" );
132 case QMetaType::Type::QPolygon:
133 case QMetaType::Type::QPolygonF:
134 return QObject::tr( "Polygon" );
135 case QMetaType::Type::QRegion:
136 return QObject::tr( "Region" );
137 case QMetaType::Type::QBitmap:
138 return QObject::tr( "Bitmap" );
139 case QMetaType::Type::QCursor:
140 return QObject::tr( "Cursor" );
141 case QMetaType::Type::QKeySequence:
142 return QObject::tr( "Key Sequence" );
143 case QMetaType::Type::QPen:
144 return QObject::tr( "Pen" );
145 case QMetaType::Type::QTextLength:
146 return QObject::tr( "Text Length" );
147 case QMetaType::Type::QTextFormat:
148 return QObject::tr( "Text Format" );
149 case QMetaType::Type::QMatrix4x4:
150 return QObject::tr( "Matrix" );
151 case QMetaType::Type::QTransform:
152 return QObject::tr( "Transform" );
153 case QMetaType::Type::QVector2D:
154 case QMetaType::Type::QVector3D:
155 case QMetaType::Type::QVector4D:
156 return QObject::tr( "Vector" );
157 case QMetaType::Type::QQuaternion:
158 return QObject::tr( "Quaternion" );
159 case QMetaType::Type::QIcon:
160 return QObject::tr( "Icon" );
161 case QMetaType::Type::QSizePolicy:
162 return QObject::tr( "Size Policy" );
163
164 default:
165 break;
166 }
167 return QString();
168}
169
170QString QgsVariantUtils::typeToDisplayString( QVariant::Type type, QVariant::Type subType )
171{
173}
174
175bool QgsVariantUtils::isNull( const QVariant &variant, bool silenceNullWarnings )
176{
177#ifndef QGISDEBUG
178 ( void )silenceNullWarnings;
179#endif
180
181 if ( variant.isNull() || !variant.isValid() )
182 return true;
183
184 switch ( variant.userType() )
185 {
186 case QMetaType::Type::UnknownType:
187 case QMetaType::Type::Bool:
188 case QMetaType::Type::Int:
189 case QMetaType::Type::UInt:
190 case QMetaType::Type::LongLong:
191 case QMetaType::Type::ULongLong:
192 case QMetaType::Type::Double:
193 case QMetaType::Type::QVariantMap:
194 case QMetaType::Type::QVariantList:
195 case QMetaType::Type::QStringList:
196 case QMetaType::Type::QUrl:
197 case QMetaType::Type::QLocale:
198 case QMetaType::Type::QRegularExpression:
199 case QMetaType::Type::QVariantHash:
200 case QMetaType::Type::QEasingCurve:
201 case QMetaType::Type::QModelIndex:
202 case QMetaType::Type::QPersistentModelIndex:
203
204 return false;
205
206 case QMetaType::Type::QDate:
207 if ( variant.toDate().isNull() )
208 {
209 if ( !silenceNullWarnings )
210 {
211 QgsDebugError( u"NULL QDateTime was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
212 }
213 return true;
214 }
215 return false;
216 case QMetaType::Type::QTime:
217 if ( variant.toTime().isNull() )
218 {
219 if ( !silenceNullWarnings )
220 {
221 QgsDebugError( u"NULL QTime was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
222 }
223 return true;
224 }
225 return false;
226 case QMetaType::Type::QDateTime:
227 if ( variant.toDate().isNull() )
228 {
229 if ( !silenceNullWarnings )
230 {
231 QgsDebugError( u"NULL QDate was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
232 }
233 return true;
234 }
235 return false;
236 case QMetaType::Type::QChar:
237 if ( variant.toChar().isNull() )
238 {
239 if ( !silenceNullWarnings )
240 {
241 QgsDebugError( u"NULL QChar was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
242 }
243 return true;
244 }
245 return false;
246 case QMetaType::Type::QString:
247 if ( variant.toString().isNull() )
248 {
249 if ( !silenceNullWarnings )
250 {
251 QgsDebugError( u"NULL QString was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
252 }
253 return true;
254 }
255 return false;
256 case QMetaType::Type::QByteArray:
257 if ( variant.toByteArray().isNull() )
258 {
259 if ( !silenceNullWarnings )
260 {
261 QgsDebugError( u"NULL QByteArray was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
262 }
263 return true;
264 }
265 return false;
266 case QMetaType::Type::QBitArray:
267 if ( variant.toBitArray().isNull() )
268 {
269 if ( !silenceNullWarnings )
270 {
271 QgsDebugError( u"NULL QBitArray was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
272 }
273 return true;
274 }
275 return false;
276 case QMetaType::Type::QRect:
277 if ( variant.toRect().isNull() )
278 {
279 if ( !silenceNullWarnings )
280 {
281 QgsDebugError( u"NULL QRect was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
282 }
283 return true;
284 }
285 return false;
286 case QMetaType::Type::QRectF:
287 if ( variant.toRectF().isNull() )
288 {
289 if ( !silenceNullWarnings )
290 {
291 QgsDebugError( u"NULL QRectF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
292 }
293 return true;
294 }
295 return false;
296 case QMetaType::Type::QSize:
297 if ( variant.toSize().isNull() )
298 {
299 if ( !silenceNullWarnings )
300 {
301 QgsDebugError( u"NULL QSize was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
302 }
303 return true;
304 }
305 return false;
306 case QMetaType::Type::QSizeF:
307 if ( variant.toSizeF().isNull() )
308 {
309 if ( !silenceNullWarnings )
310 {
311 QgsDebugError( u"NULL QSizeF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
312 }
313 return true;
314 }
315 return false;
316 case QMetaType::Type::QLine:
317 if ( variant.toLine().isNull() )
318 {
319 if ( !silenceNullWarnings )
320 {
321 QgsDebugError( u"NULL QLine was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
322 }
323 return true;
324 }
325 return false;
326 case QMetaType::Type::QLineF:
327 if ( variant.toLineF().isNull() )
328 {
329 if ( !silenceNullWarnings )
330 {
331 QgsDebugError( u"NULL QLineF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
332 }
333 return true;
334 }
335 return false;
336 case QMetaType::Type::QPoint:
337 if ( variant.toPoint().isNull() )
338 {
339 if ( !silenceNullWarnings )
340 {
341 QgsDebugError( u"NULL QPoint was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
342 }
343 return true;
344 }
345 return false;
346 case QMetaType::Type::QPointF:
347 if ( variant.toPointF().isNull() )
348 {
349 if ( !silenceNullWarnings )
350 {
351 QgsDebugError( u"NULL QPointF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
352 }
353 return true;
354 }
355 return false;
356 case QMetaType::Type::QUuid:
357 if ( variant.toUuid().isNull() )
358 {
359 if ( !silenceNullWarnings )
360 {
361 QgsDebugError( u"NULL QUuid was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
362 }
363 return true;
364 }
365 return false;
366 case QMetaType::Type::QPixmap:
367 if ( variant.value< QPixmap >().isNull() )
368 {
369 if ( !silenceNullWarnings )
370 {
371 QgsDebugError( u"NULL QPixmap was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
372 }
373 return true;
374 }
375 return false;
376 case QMetaType::Type::QImage:
377 if ( variant.value< QImage >().isNull() )
378 {
379 if ( !silenceNullWarnings )
380 {
381 QgsDebugError( u"NULL QImage was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
382 }
383 return true;
384 }
385 return false;
386 case QMetaType::Type::QRegion:
387 if ( variant.value< QRegion >().isNull() )
388 {
389 if ( !silenceNullWarnings )
390 {
391 QgsDebugError( u"NULL QRegion was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
392 }
393 return true;
394 }
395 return false;
396 case QMetaType::Type::QBitmap:
397 if ( variant.value< QBitmap >().isNull() )
398 {
399 if ( !silenceNullWarnings )
400 {
401 QgsDebugError( u"NULL QBitmap was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
402 }
403 return true;
404 }
405 return false;
406 case QMetaType::Type::QIcon:
407 if ( variant.value< QIcon >().isNull() )
408 {
409 if ( !silenceNullWarnings )
410 {
411 QgsDebugError( u"NULL QIcon was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
412 }
413 return true;
414 }
415 return false;
416 case QMetaType::Type::QVector2D:
417 if ( variant.value< QVector2D >().isNull() )
418 {
419 if ( !silenceNullWarnings )
420 {
421 QgsDebugError( u"NULL QVector2D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
422 }
423 return true;
424 }
425 return false;
426 case QMetaType::Type::QVector3D:
427 if ( variant.value< QVector3D >().isNull() )
428 {
429 if ( !silenceNullWarnings )
430 {
431 QgsDebugError( u"NULL QVector3D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
432 }
433 return true;
434 }
435 return false;
436 case QMetaType::Type::QVector4D:
437 if ( variant.value< QVector4D >().isNull() )
438 {
439 if ( !silenceNullWarnings )
440 {
441 QgsDebugError( u"NULL QVector4D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
442 }
443 return true;
444 }
445 return false;
446 case QMetaType::Type::QQuaternion:
447 if ( variant.value< QQuaternion >().isNull() )
448 {
449 if ( !silenceNullWarnings )
450 {
451 QgsDebugError( u"NULL QQuaternion was stored in a QVariant -- stop it! Always use an invalid QVariant() instead."_s );
452 }
453 return true;
454 }
455 return false;
456
457 case QMetaType::Type::QColor:
458 case QMetaType::Type::QFont:
459 case QMetaType::Type::QBrush:
460 case QMetaType::Type::QPolygon:
461 case QMetaType::Type::QPalette:
462 case QMetaType::Type::QCursor:
463 case QMetaType::Type::QKeySequence:
464 case QMetaType::Type::QPen:
465 case QMetaType::Type::QTextLength:
466 case QMetaType::Type::QPolygonF:
467 case QMetaType::Type::QTextFormat:
468 case QMetaType::Type::QTransform:
469 case QMetaType::Type::QMatrix4x4:
470 case QMetaType::Type::QSizePolicy:
471 case QMetaType::Type::User:
472 default:
473 break;
474 }
475
476 return false;
477}
478
479bool QgsVariantUtils::isNumericType( QMetaType::Type metaType )
480{
481 switch ( metaType )
482 {
483 case QMetaType::Type::Int:
484 case QMetaType::Type::UInt:
485 case QMetaType::Type::LongLong:
486 case QMetaType::Type::ULongLong:
487 case QMetaType::Type::Double:
488 case QMetaType::Type::Float:
489 case QMetaType::Type::Short:
490 case QMetaType::Type::UShort:
491 case QMetaType::Type::Char:
492 case QMetaType::Type::UChar:
493 case QMetaType::Type::SChar:
494 return true;
495 default:
496 return false;
497 }
498}
499
500QMetaType::Type QgsVariantUtils::variantTypeToMetaType( QVariant::Type variantType )
501{
502 // variant types can be directly mapped to meta types
503 return static_cast< QMetaType::Type >( variantType );
504}
505
506QVariant::Type QgsVariantUtils::metaTypeToVariantType( QMetaType::Type metaType )
507{
508 // NOLINTBEGIN(bugprone-branch-clone)
509 switch ( metaType )
510 {
511 // exact mapping, these are identical:
512 case QMetaType::Bool:
513 case QMetaType::Int:
514 case QMetaType::UInt:
515 case QMetaType::LongLong:
516 case QMetaType::ULongLong:
517 case QMetaType::Double:
518 case QMetaType::QChar:
519 case QMetaType::QVariantMap:
520 case QMetaType::QVariantList:
521 case QMetaType::QString:
522 case QMetaType::QStringList:
523 case QMetaType::QByteArray:
524 case QMetaType::QBitArray:
525 case QMetaType::QDate:
526 case QMetaType::QTime:
527 case QMetaType::QDateTime:
528 case QMetaType::QUrl:
529 case QMetaType::QLocale:
530 case QMetaType::QRect:
531 case QMetaType::QRectF:
532 case QMetaType::QSize:
533 case QMetaType::QSizeF:
534 case QMetaType::QLine:
535 case QMetaType::QLineF:
536 case QMetaType::QPoint:
537 case QMetaType::QPointF:
538 case QMetaType::QRegularExpression:
539 case QMetaType::QVariantHash:
540 case QMetaType::QEasingCurve:
541 case QMetaType::QUuid:
542 case QMetaType::QModelIndex:
543 case QMetaType::QPersistentModelIndex:
544 case QMetaType::QFont:
545 case QMetaType::QPixmap:
546 case QMetaType::QBrush:
547 case QMetaType::QColor:
548 case QMetaType::QPalette:
549 case QMetaType::QImage:
550 case QMetaType::QPolygon:
551 case QMetaType::QRegion:
552 case QMetaType::QBitmap:
553 case QMetaType::QCursor:
554 case QMetaType::QKeySequence:
555 case QMetaType::QPen:
556 case QMetaType::QTextLength:
557 case QMetaType::QTextFormat:
558 case QMetaType::QTransform:
559 case QMetaType::QMatrix4x4:
560 case QMetaType::QVector2D:
561 case QMetaType::QVector3D:
562 case QMetaType::QVector4D:
563 case QMetaType::QQuaternion:
564 case QMetaType::QPolygonF:
565 case QMetaType::QIcon:
566 case QMetaType::QSizePolicy:
567 case QMetaType::UnknownType:
568 case QMetaType::User:
569 return static_cast< QVariant::Type >( metaType );
570
571 // lossy, not exact mappings. We prefer to "expand" types
572 // to avoid truncation
573 case QMetaType::Long:
574 return QVariant::Type::LongLong;
575
576 case QMetaType::ULong:
577 return QVariant::Type::ULongLong;
578
579 case QMetaType::Char:
580 case QMetaType::Char16:
581 case QMetaType::Char32:
582 case QMetaType::Short:
583 case QMetaType::SChar:
584 return QVariant::Type::Int;
585
586 case QMetaType::UShort:
587 case QMetaType::UChar:
588 return QVariant::Type::UInt;
589
590 case QMetaType::Float:
591#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
592 case QMetaType::Float16:
593#endif
594 return QVariant::Type::Double;
595
596 // no mapping possible:
597 case QMetaType::Nullptr:
598 case QMetaType::QCborSimpleType:
599 case QMetaType::Void:
600 case QMetaType::VoidStar:
601 case QMetaType::QVariant:
602 case QMetaType::QJsonValue:
603 case QMetaType::QJsonObject:
604 case QMetaType::QJsonArray:
605 case QMetaType::QJsonDocument:
606 case QMetaType::QCborValue:
607 case QMetaType::QCborArray:
608 case QMetaType::QCborMap:
609 case QMetaType::QObjectStar:
610 case QMetaType::QVariantPair:
611 case QMetaType::QByteArrayList:
612 case QMetaType::QColorSpace:
613 break;
614
615 default:
616 break;
617 }
618 // NOLINTEND(bugprone-branch-clone)
619 return QVariant::Type::UserType;
620}
621
622bool QgsVariantUtils::isUnsetAttributeValue( const QVariant &variant )
623{
624 return variant.userType() == qMetaTypeId< QgsUnsetAttributeValue >();
625}
626
627QVariant QgsVariantUtils::createNullVariant( QMetaType::Type metaType )
628{
629 return QVariant( QMetaType( metaType ) );
630}
631
632QString QgsVariantUtils::displayString( const QVariant &variant, int precision )
633{
634
635 auto _displayString = [ ]( const QVariant & variant, int precision ) -> QString
636 {
637
638 if ( QgsVariantUtils::isNull( variant ) )
639 {
641 }
642
643 // Special treatment for numeric types if group separator is set or decimalPoint is not a dot
644 if ( variant.userType() == QMetaType::Type::Double )
645 {
646 // Locales with decimal point != '.' or that require group separator: use QLocale
647 if ( QLocale().decimalPoint() != '.' ||
648 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
649 {
650 if ( precision > 0 )
651 {
652 if ( -1 < variant.toDouble() && variant.toDouble() < 1 )
653 {
654 return QLocale().toString( variant.toDouble(), 'g', precision );
655 }
656 else
657 {
658 return QLocale().toString( variant.toDouble(), 'f', precision );
659 }
660 }
661 else
662 {
663 // Precision is not set, let's guess it from the
664 // standard conversion to string
665 const QString str( variant.toString() );
666 const int dotPosition( static_cast<int>( str.indexOf( '.' ) ) );
667 int precision;
668 if ( dotPosition < 0 && str.indexOf( 'e', 0, Qt::CaseInsensitive ) < 0 )
669 {
670 precision = 0;
671 return QLocale().toString( variant.toDouble(), 'f', precision );
672 }
673 else
674 {
675 if ( dotPosition < 0 ) precision = 0;
676 else precision = static_cast<int>( str.length() ) - dotPosition - 1;
677
678 if ( -1 < variant.toDouble() && variant.toDouble() < 1 )
679 {
680 return QLocale().toString( variant.toDouble(), 'g', precision );
681 }
682 else
683 {
684 return QLocale().toString( variant.toDouble(), 'f', precision );
685 }
686 }
687 }
688 }
689 // Default for doubles with precision
690 else if ( precision > 0 )
691 {
692 if ( -1 < variant.toDouble() && variant.toDouble() < 1 )
693 {
694 return QString::number( variant.toDouble(), 'g', precision );
695 }
696 else
697 {
698 return QString::number( variant.toDouble(), 'f', precision );
699 }
700 }
701 }
702 // Other numeric types than doubles
703 else if ( QgsVariantUtils::isNumericType( static_cast< QMetaType::Type >( variant.userType() ) ) &&
704 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
705 {
706 bool ok;
707 const qlonglong converted( variant.toLongLong( &ok ) );
708 if ( ok )
709 return QLocale().toString( converted );
710 }
711 else if ( variant.userType() == QMetaType::Type::QByteArray )
712 {
713 return QObject::tr( "BLOB" );
714 }
715
716 // Fallback if special rules do not apply
717 return variant.toString();
718 };
719
720 if ( variant.userType() == QMetaType::Type::QStringList || variant.userType() == QMetaType::Type::QVariantList )
721 {
722 QString result;
723 const QVariantList list = variant.toList();
724 for ( const QVariant &var : list )
725 {
726 if ( !result.isEmpty() )
727 {
728 result.append( ';' );
729 }
730 result.append( _displayString( var, precision ) );
731 }
732 return result;
733 }
734 else
735 {
736 return _displayString( variant, precision );
737 }
738}
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.
static QString displayString(const QVariant &variant, int precision=-1)
Returns a localized representation of value with the given precision, if precision is -1 then precisi...
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QString typeToDisplayString(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType)
Returns a user-friendly translated string representing a QVariant type.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
static bool isNumericType(QMetaType::Type metaType)
Returns true if the specified metaType is a numeric type.
static bool isUnsetAttributeValue(const QVariant &variant)
Check if the variant is a QgsUnsetAttributeValue.
static QVariant::Type metaTypeToVariantType(QMetaType::Type metaType)
Converts a QMetaType::Type to a QVariant::Type.
#define QgsDebugError(str)
Definition qgslogger.h:59