The example is a bit complex: would recommend getting the smallest thing (not) running first.
At first glance: on_click takes a function, not the output of a function, so more like .on_click(print_lid).
If it is unpalatable to reference the variables inside print_lid, make a second one, e.g. def on_click) that gathers all the values and documents its intent more clearly.
As for whether something shows based on another widget’s value: dlink is great: the third option provides a callable which has a much simpler signature than observe.