Unable to disable button within a callback


I have a button called Import on a screen. When it is pressed, it does a bunch of stuff in the background (importing things, basically). So the code looks like this:

int importCallBack() { importStuff(); return( Pt_CONTINUE ); }

Now, since ImportStuff() function takes a while to execute, I want to gray out the Import button while it is executing. So I changed the code to:

int importCallBack() { PtSetResource(Import_widget, Pt_ARG_FLAGS, Pt_BLOCKED, Pt_BLOCKED) importStuff(); //Enable Import button by calling BtSetReSource again return( Pt_CONTINUE ); }

However, this does not appear to work. The Import button stays enabled. If user presses on it while import is in process, it simply queues up the button press, and does import again after the first import is finished.

Please help! What is the standard approach here?


Yes, you have discovered one of the mysteries of Photon that you must conquer to become proficient.

When you write code that changes some property of a widget, or paints to a raw widget, you are loading graphical events into a buffer. When you return from the callback they are flushed, causing the screen to update.
But since you are busy doing something, you never return from the callback.
Here’s one strategy.

int importCallBack()
PtSetResource(Import_widget, Pt_ARG_FLAGS, Pt_BLOCKED, Pt_BLOCKED)
pthread_create(… runBackground…)

int runBackground()
int ret;

ret = PtEnter(0);
//Enable Import button by calling BtSetReSource again
return( Pt_CONTINUE );

Hi maschoen,

Thank you for your reply. I did a search on this forum shortly after I posted my question, and saw several people had the same issue. I also saw that you’ve provided the same answer below before, but cautioned against it, as it can get pretty messy.

I read that if the app is single-thread (which in my case is true), it might be easier to use a timer instead. Can you please give me some pointers on how to proceed using the timer approach?


Since you creating a Photon program, it’s a little easier to use a PtTimer widget.

Create a timer widget,
In the button callback, disable the button and set the timer to fire in 1 ms. (I don’t think you can set it any shorter)

In the timer callback, do your background processing.

When the processing is done, re-enable the button.