peterhinch / micropython-touch

A GUI for touch panel displays.
MIT License
17 stars 2 forks source link

Can single widgets be deleted from a screen? #8

Closed sreitner closed 3 weeks ago

sreitner commented 3 weeks ago

Ist there a way to delete a widget (label, button) from a screen? What I'm doing is create some widgets depending on smarthome states, eg. mailbox, open windows. Now I want to delete a widget once the according state changed. For example I draw a label with the number of open windows. Later if all widows are closed, I want to entirely remove this label. I can use the value method to overwrite the text with "" and set the border and background color to black (which is my common screen background color), but this always leaves back a black square which may likely overlay other objects esp. drawn by framebuff raw functions. Furthermore, I need to keep track whether the label already exists and update it instead of creating a new when the count of open windows changes from 0 to something. Regarding buttons things are even more difficult. The only way I found is to to a Screen.change(MainScreen, mode=Screen.REPLACE) without even creating the "open windows" label in the init.

peterhinch commented 3 weeks ago

This is not possible. The Screen instance has a displaylist bound variable which is a list of all widgets on the screen. It is initialised as an empty list by the constructor; items are added but are never removed. Removing them is not entirely straightforward.

Widgets have a .visible bound boolean. As a hack you might set this False which should make the widget disappear. It should also prevent it from responding to a touch. This may be your best approach. Note: I haven't tested this :)

sreitner commented 3 weeks ago

Alright, thanks for the prompt reply. Unlike buttons, labels have no property called visible, at least not according to how far I understand the widget source code. On the other hand, buttons don't have the value method. So none of this really fits my requirement.

Actually, changing the value of the visible property works at least half way. I wasn't quite happy with the behavior of buttonlists switching the buttons without waiting for callback result; hence, I did some tests with the visible property. It seems that Screen.show() must be called to make it have effect and in some cased it simply just wouldn't.

Anyway, I introduced a class to my program which holds the current values of all the states, these are read in init and if there was no change to a certain state, the widget will stay, or better said re-drawn as it was. The widgets no longer needed get vanished this way. In other words, instead of changing widget's contents one by one, I now save the states and always do a full screen refresh. Not the smartest way, but in the end does the job.

Great THANKS for your work!!! Never would have got the display working at all without this.

peterhinch commented 3 weeks ago

Ah - you have to set a .draw variable to force a widget to be refreshed. A Label object should have a .visible property because it is subclassed from Widget. The ButtonList is an instance where a Button is made invisible and replaced with another.

Making widgets disappear should be possible, but you're the first to request it on any of my GUI's so it's not a documented part of the API. Anyway, I'm glad you've found a workround - so I'll close this.