qgis-syntax-expressions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

qgis-syntax-expressions

QGIS表达式语法参考

Quick Reference

快速参考

Expression Evaluation Pipeline

表达式求值流程

StepClassPurpose
1. Parse
QgsExpression(string)
Validate syntax, build AST
2. Context
QgsExpressionContext()
Provide variables, fields, scopes
3. Scopes
QgsExpressionContextUtils
Add global/project/layer/feature scopes
4. Evaluate
exp.evaluate(context)
Execute and return result
5. Validate
exp.hasEvalError()
Check for runtime errors
步骤用途
1. 解析
QgsExpression(string)
验证语法,构建AST
2. 上下文
QgsExpressionContext()
提供变量、字段、作用域
3. 作用域
QgsExpressionContextUtils
添加全局/项目/图层/要素作用域
4. 求值
exp.evaluate(context)
执行并返回结果
5. 验证
exp.hasEvalError()
检查运行时错误

Expression Syntax Cheatsheet

表达式语法速查表

ElementSyntaxExample
Field reference
"field_name"
(double quotes)
"population"
String literal
'text'
(single quotes)
'hello world'
Number literal
123
,
3.14
42
NULL check
IS NULL
,
IS NOT NULL
"name" IS NOT NULL
Comparison
=
,
!=
,
>
,
>=
,
<
,
<=
"area" > 100
Logical
AND
,
OR
,
NOT
"pop" > 1000 AND "type" = 'city'
Arithmetic
+
,
-
,
*
,
/
,
^
,
%
"population" * 1.05
Pattern match
LIKE
,
ILIKE
,
~
(regex)
"name" ILIKE '%lake%'
Concatenation
||
"first" || ' ' || "last"
Conditional
CASE WHEN ... THEN ... END
CASE WHEN "pop" > 1e6 THEN 'large' ELSE 'small' END
Geometry vars
$area
,
$length
,
$x
,
$y
$area / 1e6
Current geometry
$geometry
num_points($geometry)
元素语法示例
字段引用
"field_name"
(双引号)
"population"
字符串字面量
'text'
(单引号)
'hello world'
数字字面量
123
,
3.14
42
NULL值检查
IS NULL
,
IS NOT NULL
"name" IS NOT NULL
比较运算
=
,
!=
,
>
,
>=
,
<
,
<=
"area" > 100
逻辑运算
AND
,
OR
,
NOT
"pop" > 1000 AND "type" = 'city'
算术运算
+
,
-
,
*
,
/
,
^
,
%
"population" * 1.05
模式匹配
LIKE
,
ILIKE
,
~
(正则表达式)
"name" ILIKE '%lake%'
字符串拼接
||
"first" || ' ' || "last"
条件判断
CASE WHEN ... THEN ... END
CASE WHEN "pop" > 1e6 THEN 'large' ELSE 'small' END
几何变量
$area
,
$length
,
$x
,
$y
$area / 1e6
当前几何对象
$geometry
num_points($geometry)

Common Expression Functions

常用表达式函数

CategoryFunctions
Math
sqrt()
,
abs()
,
round()
,
floor()
,
ceil()
,
sin()
,
cos()
,
pi()
String
upper()
,
lower()
,
length()
,
trim()
,
replace()
,
regexp_replace()
,
substr()
,
left()
,
right()
Conversion
to_int()
,
to_real()
,
to_string()
,
to_date()
,
to_datetime()
Date/Time
now()
,
day()
,
month()
,
year()
,
hour()
,
minute()
,
age()
,
day_of_week()
Geometry
$area
,
$length
,
$x
,
$y
,
$perimeter
,
centroid()
,
buffer()
,
area()
,
length()
,
num_geometries()
,
num_points()
Aggregates
aggregate()
,
sum()
,
count()
,
mean()
,
min()
,
max()
,
concatenate()
,
array_agg()
Conditionals
if()
,
coalesce()
,
nullif()
,
try()
Arrays
array()
,
array_length()
,
array_contains()
,
array_append()
,
array_to_string()
Map/Record
map()
,
map_get()
,
hstore_to_map()
Color
color_rgb()
,
color_hsv()
,
ramp_color()
,
darker()
,
lighter()

类别函数
数学
sqrt()
,
abs()
,
round()
,
floor()
,
ceil()
,
sin()
,
cos()
,
pi()
字符串
upper()
,
lower()
,
length()
,
trim()
,
replace()
,
regexp_replace()
,
substr()
,
left()
,
right()
类型转换
to_int()
,
to_real()
,
to_string()
,
to_date()
,
to_datetime()
日期/时间
now()
,
day()
,
month()
,
year()
,
hour()
,
minute()
,
age()
,
day_of_week()
几何
$area
,
$length
,
$x
,
$y
,
$perimeter
,
centroid()
,
buffer()
,
area()
,
length()
,
num_geometries()
,
num_points()
聚合
aggregate()
,
sum()
,
count()
,
mean()
,
min()
,
max()
,
concatenate()
,
array_agg()
条件
if()
,
coalesce()
,
nullif()
,
try()
数组
array()
,
array_length()
,
array_contains()
,
array_append()
,
array_to_string()
映射/记录
map()
,
map_get()
,
hstore_to_map()
颜色
color_rgb()
,
color_hsv()
,
ramp_color()
,
darker()
,
lighter()

Critical Warnings

重要警告

ALWAYS check
exp.hasParserError()
after creating a
QgsExpression
. A parser error means the expression string is syntactically invalid and evaluation will fail silently or return NULL.
ALWAYS check
exp.hasEvalError()
after calling
exp.evaluate()
. Evaluation errors occur when the expression is syntactically valid but fails at runtime (e.g., field not found, type mismatch).
ALWAYS set up a proper
QgsExpressionContext
with appropriate scopes when evaluating expressions that reference fields, project variables, or layer properties. Evaluating without context returns NULL for all field references.
NEVER use double quotes for string literals in expressions. Double quotes reference field names:
"name"
reads the field,
'name'
is the string literal.
NEVER forget to call
context.setFeature(feature)
before evaluating feature-dependent expressions in a loop. Omitting this causes all features to evaluate against stale or empty data.
NEVER use
print()
inside custom expression functions (
@qgsfunction
). Use
QgsMessageLog
instead. Expression functions run during rendering and
print()
causes thread-safety issues.
ALWAYS specify
referenced_columns
in
@qgsfunction
for performance. Use
[QgsFeatureRequest.ALL_ATTRIBUTES]
if the function reads arbitrary fields; use
[]
if it reads no fields.
ALWAYS set
usesgeometry=True
in
@qgsfunction
if the function accesses
feature.geometry()
. Omitting this causes the geometry to be unavailable.

务必在创建
QgsExpression
后检查
exp.hasParserError()
。解析错误表示表达式字符串语法无效,求值将静默失败或返回NULL。
务必在调用
exp.evaluate()
后检查
exp.hasEvalError()
。求值错误发生在表达式语法有效但运行时失败的场景(例如:字段未找到、类型不匹配)。
务必在求值涉及字段、项目变量或图层属性的表达式时,设置包含合适作用域的
QgsExpressionContext
。如果没有上下文,所有字段引用的求值结果都将是NULL。
切勿在表达式中使用双引号表示字符串字面量。双引号用于引用字段名:
"name"
表示读取字段,
'name'
才是字符串字面量。
切勿在循环中求值依赖要素的表达式前忘记调用
context.setFeature(feature)
。省略此步骤会导致所有要素都基于过期或空数据进行求值。
切勿在自定义表达式函数(
@qgsfunction
)中使用
print()
。请改用
QgsMessageLog
。表达式函数在渲染期间运行,
print()
会引发线程安全问题。
务必
@qgsfunction
中指定
referenced_columns
以提升性能。如果函数读取任意字段,请使用
[QgsFeatureRequest.ALL_ATTRIBUTES]
;如果不读取任何字段,请使用
[]
如果函数访问
feature.geometry()
,务必
@qgsfunction
中设置
usesgeometry=True
。省略此步骤会导致几何对象不可用。

Decision Tree: Choosing the Right Expression Approach

决策树:选择合适的表达式使用方式

Need to use an expression?
|
+-- Filter features? --> QgsFeatureRequest.setFilterExpression()
|
+-- Calculate field values? --> Field Calculator pattern (edit session + evaluate per feature)
|
+-- Drive labeling? --> QgsPalLayerSettings.fieldName + isExpression = True
|
+-- Drive symbology? --> QgsProperty.fromExpression() on symbol/renderer properties
|
+-- Evaluate standalone? --> QgsExpression.evaluate(context)
|
+-- Need custom logic? --> @qgsfunction decorator + QgsExpression.registerFunction()

需要使用表达式?
|
+-- 筛选要素? --> QgsFeatureRequest.setFilterExpression()
|
+-- 计算字段值? --> 字段计算器模式(编辑会话 + 逐要素求值)
|
+-- 驱动标注? --> QgsPalLayerSettings.fieldName + isExpression = True
|
+-- 驱动符号化? --> 在符号/渲染器属性上使用QgsProperty.fromExpression()
|
+-- 独立求值? --> QgsExpression.evaluate(context)
|
+-- 需要自定义逻辑? --> @qgsfunction装饰器 + QgsExpression.registerFunction()

Essential Patterns

核心使用模式

Pattern 1: Parse and Evaluate an Expression

模式1:解析并求值表达式

python
from qgis.core import (
    QgsExpression, QgsExpressionContext, QgsExpressionContextUtils
)

exp = QgsExpression('"population" * 1.05')
if exp.hasParserError():
    raise ValueError(f"Parse error: {exp.parserErrorString()}")

context = QgsExpressionContext()
context.appendScopes(
    QgsExpressionContextUtils.globalProjectLayerScopes(layer)
)

for feature in layer.getFeatures():
    context.setFeature(feature)
    value = exp.evaluate(context)
    if exp.hasEvalError():
        raise ValueError(f"Eval error: {exp.evalErrorString()}")
    print(f"Feature {feature.id()}: {value}")
python
from qgis.core import (
    QgsExpression, QgsExpressionContext, QgsExpressionContextUtils
)

exp = QgsExpression('"population" * 1.05')
if exp.hasParserError():
    raise ValueError(f"Parse error: {exp.parserErrorString()}")

context = QgsExpressionContext()
context.appendScopes(
    QgsExpressionContextUtils.globalProjectLayerScopes(layer)
)

for feature in layer.getFeatures():
    context.setFeature(feature)
    value = exp.evaluate(context)
    if exp.hasEvalError():
        raise ValueError(f"Eval error: {exp.evalErrorString()}")
    print(f"Feature {feature.id()}: {value}")

Pattern 2: Expression-Based Feature Filtering

模式2:基于表达式的要素筛选

python
from qgis.core import QgsFeatureRequest
python
from qgis.core import QgsFeatureRequest

Method A: expression string directly

方法A:直接使用表达式字符串

request = QgsFeatureRequest().setFilterExpression('"population" >= 50000') features = list(layer.getFeatures(request))
request = QgsFeatureRequest().setFilterExpression('"population" >= 50000') features = list(layer.getFeatures(request))

Method B: QgsExpression object

方法B:使用QgsExpression对象

exp = QgsExpression('"name" ILIKE '%lake%'') request = QgsFeatureRequest(exp) features = list(layer.getFeatures(request))
undefined
exp = QgsExpression('"name" ILIKE '%lake%'') request = QgsFeatureRequest(exp) features = list(layer.getFeatures(request))
undefined

Pattern 3: Field Calculator (Update Attributes)

模式3:字段计算器(更新属性)

python
from qgis.core import (
    edit, QgsExpression, QgsExpressionContext,
    QgsExpressionContextUtils
)

exp = QgsExpression('"population" * 2')
context = QgsExpressionContext()
context.appendScopes(
    QgsExpressionContextUtils.globalProjectLayerScopes(layer)
)

with edit(layer):
    for f in layer.getFeatures():
        context.setFeature(f)
        f['doubled_pop'] = exp.evaluate(context)
        layer.updateFeature(f)
python
from qgis.core import (
    edit, QgsExpression, QgsExpressionContext,
    QgsExpressionContextUtils
)

exp = QgsExpression('"population" * 2')
context = QgsExpressionContext()
context.appendScopes(
    QgsExpressionContextUtils.globalProjectLayerScopes(layer)
)

with edit(layer):
    for f in layer.getFeatures():
        context.setFeature(f)
        f['doubled_pop'] = exp.evaluate(context)
        layer.updateFeature(f)

Pattern 4: Expression-Based Labeling

模式4:基于表达式的标注

python
from qgis.core import QgsPalLayerSettings, QgsVectorLayerSimpleLabeling

settings = QgsPalLayerSettings()
settings.fieldName = '"name" || \' (\' || "population" || \')\''
settings.isExpression = True
settings.enabled = True

text_format = settings.format()
text_format.setSize(12)
settings.setFormat(text_format)

labeling = QgsVectorLayerSimpleLabeling(settings)
layer.setLabeling(labeling)
layer.setLabelsEnabled(True)
layer.triggerRepaint()
python
from qgis.core import QgsPalLayerSettings, QgsVectorLayerSimpleLabeling

settings = QgsPalLayerSettings()
settings.fieldName = '"name" || \' (\' || "population" || \')\''
settings.isExpression = True
settings.enabled = True

text_format = settings.format()
text_format.setSize(12)
settings.setFormat(text_format)

labeling = QgsVectorLayerSimpleLabeling(settings)
layer.setLabeling(labeling)
layer.setLabelsEnabled(True)
layer.triggerRepaint()

Pattern 5: Data-Defined Symbology Properties

模式5:数据定义的符号化属性

python
from qgis.core import QgsProperty

symbol = layer.renderer().symbol()
python
from qgis.core import QgsProperty

symbol = layer.renderer().symbol()

Size driven by expression

由表达式驱动大小

symbol.setDataDefinedSize( QgsProperty.fromExpression('"population" / 1000') )
symbol.setDataDefinedSize( QgsProperty.fromExpression('"population" / 1000') )

Color driven by expression

由表达式驱动颜色

symbol.setDataDefinedColor( QgsProperty.fromExpression( "CASE WHEN "type" = 'city' THEN '#ff0000' ELSE '#0000ff' END" ) )
layer.triggerRepaint()
undefined
symbol.setDataDefinedColor( QgsProperty.fromExpression( "CASE WHEN "type" = 'city' THEN '#ff0000' ELSE '#0000ff' END" ) )
layer.triggerRepaint()
undefined

Pattern 6: Custom Expression Function

模式6:自定义表达式函数

python
from qgis.core import qgsfunction, QgsExpression

@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def population_density(population, area_km2, feature, parent):
    """
    Calculate population density per square kilometer.
    <p>Usage: population_density("pop_field", "area_field")</p>
    """
    if area_km2 and area_km2 > 0:
        return population / area_km2
    return None
python
from qgis.core import qgsfunction, QgsExpression

@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def population_density(population, area_km2, feature, parent):
    """
    Calculate population density per square kilometer.
    <p>Usage: population_density("pop_field", "area_field")</p>
    """
    if area_km2 and area_km2 > 0:
        return population / area_km2
    return None

Register (call once, e.g., in plugin initGui)

注册(调用一次,例如在插件的initGui中)

QgsExpression.registerFunction(population_density)
QgsExpression.registerFunction(population_density)

Now usable: population_density("population", "area")

现在可使用:population_density("population", "area")

Unregister (call in plugin unload)

注销(在插件unload中调用)

QgsExpression.unregisterFunction('population_density')

---
QgsExpression.unregisterFunction('population_density')

---

Context Scope Hierarchy

上下文作用域层级

Scopes are stacked from generic to specific. When variable names collide, the most specific scope wins:
Global scope        → @qgis_version, @user_full_name, custom global vars
  Project scope     → @project_title, @project_crs, custom project vars
    Layer scope     → @layer_name, @layer_id, layer fields
      Feature scope → Feature attributes, $geometry, $id, $currentfeature
作用域从通用到特定依次堆叠。当变量名冲突时,最特定的作用域优先级最高:
全局作用域        → @qgis_version, @user_full_name, 自定义全局变量
  项目作用域     → @project_title, @project_crs, 自定义项目变量
    图层作用域     → @layer_name, @layer_id, 图层字段
      要素作用域 → 要素属性, $geometry, $id, $currentfeature

Adding Custom Variables

添加自定义变量

python
from qgis.core import QgsExpressionContextUtils
python
from qgis.core import QgsExpressionContextUtils

Set global variable (persists across sessions)

设置全局变量(跨会话持久化)

QgsExpressionContextUtils.setGlobalVariable('my_threshold', 42)
QgsExpressionContextUtils.setGlobalVariable('my_threshold', 42)

Set project variable (saved with project)

设置项目变量(随项目保存)

QgsExpressionContextUtils.setProjectVariable( QgsProject.instance(), 'analysis_year', 2024 )
QgsExpressionContextUtils.setProjectVariable( QgsProject.instance(), 'analysis_year', 2024 )

Set layer variable (saved with layer in project)

设置图层变量(随项目中的图层保存)

QgsExpressionContextUtils.setLayerVariable(layer, 'source_date', '2024-01-15')
QgsExpressionContextUtils.setLayerVariable(layer, 'source_date', '2024-01-15')

Access in expressions: @my_threshold, @analysis_year, @source_date

在表达式中访问:@my_threshold, @analysis_year, @source_date


---

---

Aggregate Expressions

聚合表达式

Aggregates compute values across features within a layer:
python
undefined
聚合函数用于计算图层内多个要素的汇总值:
python
undefined

In expression strings:

在表达式字符串中:

aggregate('layer_name', 'sum', "population")

aggregate('layer_name', 'sum', "population")

aggregate('layer_name', 'mean', "area", filter:="type" = 'residential')

aggregate('layer_name', 'mean', "area", filter:="type" = 'residential')

Common shorthand (current layer):

常用简写(当前图层):

sum("population")

sum("population")

count("id", filter:="active" = 1)

count("id", filter:="active" = 1)

mean("temperature", group_by:="region")

mean("temperature", group_by:="region")


**ALWAYS** use the `filter` parameter in aggregates to limit the scope. Aggregating an entire large layer without a filter is a performance bottleneck.

---

**务必**在聚合函数中使用`filter`参数来限定作用范围。不对大型图层进行过滤就直接聚合会导致性能瓶颈。

---

Reference Links

参考链接

  • references/methods.md -- API signatures for QgsExpression, QgsExpressionContext, QgsExpressionContextUtils, @qgsfunction
  • references/examples.md -- Complete expression examples for filtering, labeling, symbology, field calculator
  • references/anti-patterns.md -- Expression pitfalls and incorrect patterns
  • references/methods.md —— QgsExpression、QgsExpressionContext、QgsExpressionContextUtils、@qgsfunction的API签名文档
  • references/examples.md —— 用于筛选、标注、符号化、字段计算的完整表达式示例
  • references/anti-patterns.md —— 表达式使用陷阱及错误模式

Official Sources

官方资源