| Reply | « Previous Thread | Next Thread » |
|
I was playing around and found a way to prevent closing of Python when the red key (hang-up key) is pressed. No external modules are needed.
The trick abuses the fact that PyS60 applications run in Active Objects environment and they spend most of their time in Active Scheduler. As with standard Python, in PyS60 we can set up a function to be called upon interpreter close. This is simply done by assigning a callable to sys.exitfunc or by using the atexit.register() function. As it turns out, this function is properly called when the red key is pressed. However, this function has no way to tell Python to abort the close. As soon as this function returns, the interpreter will shut down. So, we have to make sure it will never return. This is simply done by creating an e32.Ao_lock() object and calling its wait() method each time the system wants to shut Python down. Let me show you some code: Code:
import sys, e32 lock = e32.Ao_lock() sys.exitfunc = lock.wait One issue is that you have to remember to set the sys.exitfunc to None if you will ever want to close Python. Otherwise, it will be impossible to close it. For example, your exit_key_handler in a standalone app could look like this: Code:
sys.exitfunc = None appuifw.app.set_exit() I'm not sure how this will behave in a long run because probably every such quit attempt allocates some memory which is freed only when the application finally closes. But this may be so small that it can be ignored. All tests done using an N73ME / latest firmware / latest PyS60 (1.4.3). Comments are welcome. --- Added --- It happened to me that after coming back to the application, the top pane was gone (no icon, no title). The remedy to this was to force a screen refresh in the exitfunc: Code:
import sys, e32, appuifw
lock = e32.Ao_lock()
def myexitfunc():
s = appuifw.app.screen
appuifw.app.screen = 'large'
appuifw.app.screen = s
lock.wait()
sys.exitfunc = myexitfunc
Last edited by y.a.k : 2008-06-25 at 04:16.
|
|
Join Date: Oct 2007
Posts: 2,845
Location: Deva, Romania
Online
Forum Nokia Champion
|
|
That's really great
. I for one didn't know we could to that. Congrats on the discovery .I tested it on N95, v21 firmware and Python 1.4.3 and it worked just like it did for you. And to kill Python I used Handy Taskman to kill its process. Again, nice trick ![]() |
|
Quote:
-- Aapo |
|
Join Date: Oct 2007
Posts: 2,845
Location: Deva, Romania
Online
Forum Nokia Champion
|
|
|
Quote:
Code:
import appuifw, e32, sys from keycapture import * from key_codes import * lock = e32.Ao_lock() def myexitfunc(): s = appuifw.app.screen appuifw.app.screen = 'large' appuifw.app.screen = s lock.wait() sys.exitfunc = myexitfunc def quit(): capturer.stop() lock.signal() c=0 def cb_capture(key): global c if(key==EKeyNo):c+=1 if(c==4):quit() #When the key has been pressed a cetain number of times, exit capturer=KeyCapturer(cb_capture) capturer.keys=(all_keys) capturer.start() |
|
Hi,
Good discovery y.a.k, Till now the only solution to prevent the red key terminate python was Envy Module by Cyke64, ![]() Happy Pythoning, Best Regards, Croozeus |
|
Thanks guys!
Bogdan, counting could also be done without the KeyCapturer (which requires SwEvent capability). Just increase a global count variable in exitfunc() and if it reaches certain amount, don't call the lock.wait() but simply return, Python will close. |
|
Thanks, this is what I ment.
|
|
Could there be issues with resource usage? multiple threads waiting on the lock?
|
|
First of all, they're not real threads, they're Active Objects. As for the lock, it seems that multiple Active Objects can wait for a single lock. No issues were observed. If I get some free time, I may look into the PyS60 sources and Ao_lock implementation and compare it with the Symbian reference to know for sure.
|
|
Quote:
Best Regards, Croozeus |
|
Hi guys,
I also tried y.a.ks Trick to prevent an pys60 app from closing. I want to share my testing results with you for further discussion: The test program is running a second threat. After pressing the red hang-up key and comming back to the application my UI was still alive (which already was a sensation to me )But I soon discovered that my second threat was (obviously) still in waiting mode. Usualy my second threat delivers data every few seconds to a global variable, which I display on the screen. But here, there was no automatic screen refresh showing new data anymore. The only way getting the latest data on the screen was to press the "options softkey" and then "cancel"). The result was a screen refresh with the latest set of data. (but still no automatic screen refresh anymore) Unfortunately I'm still not familiar with the inner work of active objects, so I can only guess the problem: Either: After comming back to the application the second threat was still in waiting mode Or: something happend to my while-loop that I use in the main threat. Because here I check if there is new data from the second threat to refresh the screen. thx novis |
|
Hmm, I'm not sure what happens in a multithreaded application. The question is: does Python kill the subthreads before it calls the sys.exitfunc or it waits until it returns? If the latter then we should be fine.
If, however, the trick works for single-thread apps only I have a suggestion for you. If you use a subthread just to update some value every couple of seconds, why not use an active object timer? Take a look at e32.Ao_timer class. And remember that it's much cheaper (resource-wise) to use an active object than a full fledged subthread. And you can use appuifw from them. |
|
Hi y.a.k,
the second thread is connecting to a server via socket to receive data every few seconds. The problemm having this in mainthread was, that my application screen was freezing as long as I was waiting for data. Quote:
Quote:
kind regards novis |
|
I see, if the thread sleeps waiting for data, having it in an active object will still cause freezes to the UI. You said that the thread downloads the data and sets a global variable which is then read by the main thread and displayed on screen. How do you tell the main thread to update this value? Maybe you could use the e32.Ao_timer to do this.
|
|
Quote:
The mainthread just checks if the value of the global variable is changing. If yes, then I initiate a screen refresh. In order to give both threads enought time for their work I use "e32.ao_sleep(0.1)" which is causing the Global Interpreter Lock to switch back to the other thread. |
| Reply | « Previous Thread | Next Thread » |
| Thread Tools | Search this Thread |
|---|---|
| Rate This Thread | |
| Thread | Thread Starter | Forum | Replies | Last Post |
|---|---|---|---|---|
| Yucca please help: Long key press - iRepeats is never 1 | Tasneem Rangwala | General Symbian C++ | 1 | 2009-10-28 04:32 |
| End(red) Button in HandleWsEventL() | ezchip | General Symbian C++ | 48 | 2009-04-28 12:46 |
| how capture the long key press | krgvs | General Symbian C++ | 1 | 2008-04-14 09:09 |
| How to disable the red key for closing Python? | carknue | Python | 3 | 2007-11-15 22:18 |
| Prevent python getting closed by kernel | prashanth_ym | Python | 2 | 2007-05-21 11:30 |