Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kannes/a5589d5965090829eb4a62095b30db5b to your computer and use it in GitHub Desktop.
Save kannes/a5589d5965090829eb4a62095b30db5b to your computer and use it in GitHub Desktop.
# 2022-08 Johannes Kröger (WhereGroup), GPLv3
# Silly interface to interactively adjust (project) variable
# values in real time. Meant to be used with expressions.
# Use @variable_name in expressions and have a go at it.
# - Displays widgets for editing int/float project variables
# - Refreshes canvas after any change in value
# WIP, might make it a plugin some day
from functools import partial
def update_var(var_name, value):
#print(f"update_var({value=}, {var_name=})") # only for debugging, slow!
QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(), var_name, str(value)) # must be str again...
iface.mapCanvas().refreshAllLayers() # TODO check if something more lean works... .refresh() does not!
widgets = [] # -> list of (var_name, widget)
project_scope = QgsExpressionContextUtils.projectScope(QgsProject.instance())
variable_names = sorted(project_scope.variableNames())
for var_name in variable_names:
# var "project_filename" gave:
# TypeError: unable to convert a C++ 'QVariantList' instance to a Python object
try:
var_value = project_scope.variable(var_name)
except TypeError:
continue
# lets be lazy for now and skip all default ones (and potentially more)
if "project" in var_name or var_name == 'layer_ids':
continue
# float to float, int to int, str ignored for now (TODO add str for colors etc)
value = None
try:
value = int(var_value)
except (ValueError, TypeError):
try:
value = float(var_value)
except (ValueError, TypeError):
pass
print(f"{var_name}: {var_value} ({type(value)}")
widget = None
#not_zero_additor = 0.00000000000000001 # to avoid 0 being uneditable
if isinstance(value, float):
double_spinbox = QDoubleSpinBox()
#double_spinbox.setRange(-(value+not_zero_additor)*10, (value+not_zero_additor)*10)
#double_spinbox.setSingleStep(0.1)
widget = double_spinbox
elif isinstance(value, int):
slider = QSlider(Qt.Horizontal)
#slider.setRange(-(value+not_zero_additor)*10, (value+not_zero_additor)*10)
#slider.setSingleStep(1)
widget = slider
else:
# skip unsupported types for now
continue
widget.setValue(value)
widget.valueChanged.connect(partial(update_var, var_name))
widgets.append((var_name, widget))
dlg = QDialog(iface.mainWindow())
dlg.setWindowTitle("Project Variable Manipulator 3000")
layout = QVBoxLayout()
for var_name, widget in widgets:
sublayout = QHBoxLayout()
sublayout.addWidget(QLabel(var_name))
sublayout.addWidget(widget)
layout.addLayout(sublayout)
dlg.setLayout(layout)
dlg.show()
@kannes
Copy link
Author

kannes commented Aug 28, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment