Generalise descriptor and use it in button.py