Page 1 of 2
Global functions?
Posted: Sat Sep 16, 2017 8:53 am
by Luca Brasi
Hey guys,
I guess this must have been discussed before but I couldn't find anything about it:
Sometimes I'd like to access some functions from different scripts. Like accessing eg.globals.[variables]
This would come in handy for osd loops, find window stuff or checking if processes are running and alike.
As far as I can see I will have to define each function in each script.
I tried to define functions like
Code: Select all
def eg.globals.check_mp():
eg.globals.mp_running = len( WMI.ExecQuery('select * from Win32_Process where Name="MediaPortal.exe"') ) > 0
The main reason for having it in a function in that case is that I can have it run in another thread. But this is just a short example.
Is there any way to do this?
Re: Global functions?
Posted: Sat Sep 16, 2017 9:34 am
by yokel22
Yes, you can assign functions as eg.global variables like this.
Code: Select all
def myFunction():
'do stuff'
eg.globals.newFunction = myFunction
Or
Code: Select all
def check_mp():
eg.globals.mp_running = len( WMI.ExecQuery('select * from Win32_Process where Name="MediaPortal.exe"') ) > 0
eg.globals.check_mp = check_mp
You'll need to initialize the variable functions each time eg starts. I usually use the Main. OnInit event that's generated on eg load.
Re: Global functions?
Posted: Sat Sep 16, 2017 10:19 am
by Luca Brasi
Great man, thanks!
One simple line eg.globals.newFunction = myFunction

Before when I tried to assign the function directly to the global I got a syntax error.
This will help me a lot!
Re: Global functions?
Posted: Sat Sep 16, 2017 12:40 pm
by kgschlosser
there is one hiccup when using the Main.OnInit gets triggered after all of the plugins load. there is the possibility that a plugin can trigger an event before the Main.OnInit anf if that event that gets triggered is in a macro that makes use of a global that has not been set up yet you will get the ugly red.
So if you add the TiggerEvent Action and have it trigger an event that you can assign to setting up all of your global functions and attributes and place that Action at the very top of the Autostart then this problem cannot occur
Re: Global functions?
Posted: Sat Sep 16, 2017 2:46 pm
by Luca Brasi
Thanks for the heads up. I had seen this before with global variables and set it up as you recommended
Re: Global functions?
Posted: Sat Sep 16, 2017 4:18 pm
by yokel22
Yep, it's pretty handy sometimes. Something I didn't even realize you could do for way too long.
Re: Global functions?
Posted: Sat Sep 16, 2017 9:36 pm
by kgschlosser
this is how you can do proper socket and file closing if you are running a thread from a python script. You would build a class inside of the script and construct the class and set the instance of that class into a global. this class would house the running thread and you can set an event listener so when Main.OnClose gets triggered it will close down the thread properly if the thread is running.
example code
Code: Select all
import threading
class ThreadClass(threading.Thread):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self._event = threading.Event()
threading.Thread.__init__(self, name='SomeThreadName')
def start(self):
eg.Bind('Main.OnClose', self.stop)
threading.Thread.start(self)
def run(self):
# startup code
print 'Thread started'
# looping code
while not self._event.isSet():
# do your looping code here and access the params if needed
# non blocking sleep
eg.TriggerEvent(prefix=self.param1, suffix=self.param2, payload='EventPayload')
self._event.wait(1.0)
# closing code
print 'Thread closed'
def stop(self, dummyEvent=None):
if self.IsAlive():
eg.Unbind('Main.OnClose', self.stop)
self._event.set()
self.join(1.0)
return False
# you could set this instance at startup of EG and then
# make the calls to start and stop it whenever.
# it will always close properly if you close EventGhost
eg.globals.some_thread = ThreadClass('EventPrefix', 'EventSuffix')
eg.globals.some_thread.start()
# use this to close the event.
# eg.globals.some_thread.stop()
Re: Global functions?
Posted: Sun Sep 17, 2017 8:05 am
by Luca Brasi
Dude. You need to stop throwing stuff like that at me on a Sunday morning. My girlfriend is gonna kill me pretty soon
No honestly thank you very much. I love to learn how to do it in coding.
Until now I have been using the AddTask action for calling the functions. Can you tell me what's the difference in doing it with the code compared to AddTask?
And maybe I didn't understand entirely yet but if I try your code like this I will get an error about IsAlive
Code: Select all
import threading
class ThreadClass(threading.Thread):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self._event = threading.Event()
threading.Thread.__init__(self, name='MyTestLoop_1')
def start(self):
eg.Bind('Main.OnClose', self.stop)
threading.Thread.start(self)
def run(self):
# startup code
print 'Thread started'
# looping code
while not self._event.isSet():
# do your looping code here and access the params if needed
import time
for x in range(0,10):
print x
time.sleep(1)
else:
break
# non blocking sleep
eg.TriggerEvent(prefix=self.param1, suffix=self.param2, payload='EventPayload')
self._event.wait(1.0)
# closing code
print 'Thread closed'
def stop(self, dummyEvent=None):
if self.IsAlive():
eg.Unbind('Main.OnClose', self.stop)
self._event.set()
self.join(1.0)
return False
# you could set this instance at startup of EG and then
# make the calls to start and stop it whenever.
# it will always close properly if you close EventGhost
eg.globals.MyTestLoop_1 = ThreadClass('EventPrefix', 'EventSuffix')
eg.globals.MyTestLoop_1.start()
import time
time.sleep(5)
# use this to close the event.
eg.globals.MyTestLoop_1.stop()
Code: Select all
09:57:42 ---> Welcome to EventGhost <---
09:58:19 thread definiton
09:58:19 Thread started
09:58:19 0
09:58:20 1
09:58:21 2
09:58:22 3
09:58:23 4
09:58:24 Traceback (most recent call last):
09:58:24 Python script "42", line 49, in <module>
09:58:24 eg.globals.MyTestLoop_1.stop()
09:58:24 Python script "42", line 35, in stop
09:58:24 if self.IsAlive():
09:58:24 AttributeError: 'ThreadClass' object has no attribute 'IsAlive'
09:58:24 5
09:58:25 6
09:58:26 7
09:58:27 8
09:58:28 9
09:58:29 Thread closed
Re: Global functions?
Posted: Sun Sep 17, 2017 2:53 pm
by kgschlosser
I fat fingered the IsAlive() it is supposed to be isAlive() lowercase i
Re: Global functions?
Posted: Sun Sep 17, 2017 3:04 pm
by kgschlosser
also this is a thread and the loop is already set up for ya with the
this is the loop. the only thing that will break the loop is self._event.set() which you can see gets called when you close the thread. you can also call the self._event.set() from inside of the loop if an error happens and you want to shutdown the thread
the second thing is the use of time.sleep. you do not want to use this. it will block the thread being terminated with self._event.set(). when you call self._event.wait() it is basically the same thing as time.sleep() except that it will stop waiting/sleeping if self._event.set() gets called. time.sleep() does not. it will continue to sleep until the timeout period has expired. the problem with this is if you have a long wait period say 10 seconds the issue with this is that EG will only wait for 5 seconds for a thread to exit properly before throwing an error. and no one really likes to restart eg and have the process get stuck for 5 seconds before it closes.
try this code. this will print 0-9 one number every second and then exit the thread when it is done.
Code: Select all
def run(self):
# startup code
print 'Thread started'
x = 0
# looping code
while not self._event.isSet():
print x
x += 1
if x == 10:
self._event.set()
else:
# non blocking sleep
self._event.wait(1.0)
Re: Global functions?
Posted: Sun Sep 17, 2017 3:19 pm
by Luca Brasi
Ah yes I understand... I'll check the code later! Thanks man!
Re: Global functions?
Posted: Sun Sep 17, 2017 3:39 pm
by kgschlosser
make sure you change that IsAlive to isAlive
and no worries m8 that's why I am here
Re: Global functions?
Posted: Sun Sep 17, 2017 3:45 pm
by kgschlosser
Luca Brasi wrote:Dude. You need to stop throwing stuff like that at me on a Sunday morning. My girlfriend is gonna kill me pretty soon

No honestly thank you very much. I love to learn how to do it in coding.
HA! I know right. But you have been around these boards for an extremely long time and You have a working knowledge of the syntax (one of the hardest parts of learning how to program) just got to show you the tools that are available. Good thing to do is to make a new bookmark category and bookmark these pages for reference. what i personally do is i made a folder on my desktop called code snippits and I create a new file and paste the code into it and name the file in a way so that it is something that you will remember so you can bring it back up when you need to use it.
Remember i saw your configuration tree! I am thinking you have been trimming the proverbial fat from it with all of the new information that has been posted.
Re: Global functions?
Posted: Mon Sep 18, 2017 5:39 pm
by Luca Brasi
Ok man, thanks again for all the info
I'm playing around with the code right now. I am running into problems when I try to call the class with parameters.
As far as I can see you already included that with param1 and param2.
But those two are defined in the startup script which defines the global function. This is done with
Code: Select all
eg.globals.MyTestLoop_1 = ThreadClass('EventPrefix', 'EventSuffix')
So how can I call the function from outside this script and pass some other parameters instead of ('EventPrefix', 'EventSuffix')? I was thinking about using global variables and it works. But this doesn't make any sense to me because the class is defined before when the globals are not set yet.
Code: Select all
eg.globals.MyTestLoop_1.start(param1,param2)
Will not work for obvious reasons:
Code: Select all
19:06:27 Traceback (most recent call last):
19:06:27 Python script "43", line 5, in <module>
19:06:27 eg.globals.MyTestLoop_1.start('Hello1', 'Hello2')
19:06:27 TypeError: start() takes exactly 1 argument (3 given)
I do understand why this is happening. I'm after all calling the function with the start argument and 'Hello1', 'Hello2' should be passed additionally.
And the thread seems not be closed properly because I will get this:
Code: Select all
19:38:12 thread definiton
19:38:16 Python Script
19:38:16 Thread started
19:38:16 Hello1
19:38:16 Hello2
19:38:16 0
19:38:17 1
19:38:18 Closing the thread
19:38:18 2
19:38:18 Thread closed
19:38:26 Python Script
19:38:26 Traceback (most recent call last):
19:38:26 Python script "51", line 4, in <module>
19:38:26 eg.globals.MyTestLoop_2.start()
19:38:26 Python script "50", line 13, in start
19:38:26 threading.Thread.start(self)
19:38:26 File "threading.pyc", line 730, in start
19:38:26 RuntimeError: threads can only be started once
Re: Global functions?
Posted: Tue Sep 19, 2017 2:18 pm
by Luca Brasi
Okidoki, I solved the first one:
Code: Select all
import threading
class ThreadClass(threading.Thread):
def __init__(self):
self._event = threading.Event()
threading.Thread.__init__(self, name='SomeThreadName')
def start(self, param1, param2):
self.param1 = param1
self.param2 = param2
eg.Bind('Main.OnClose', self.stop)
threading.Thread.start(self)
def run(self):
# startup code
print 'Thread started'
print str(self.param1)
print str(self.param2)
x = 1
# looping code
while not self._event.isSet():
print x
x += 1
if x == self.param2:
self._event.set()
else:
# non blocking sleep
self._event.wait(self.param1)
# closing code
print 'Thread closed'
def stop(self, dummyEvent=None):
if self.isAlive():
eg.Unbind('Main.OnClose', self.stop)
self._event.set()
self.join(1.0)
return False
# you could set this instance at startup of EG and then
# make the calls to start and stop it whenever.
# it will always close properly if you close EventGhost
eg.globals.some_thread = ThreadClass()
#eg.globals.some_thread.start()
# use this to close the event.
# eg.globals.some_thread.stop()
starting it with:
Code: Select all
eg.globals.some_thread.start(1.0, 10)
I still get the error that the thread can not be started again
Code: Select all
Traceback (most recent call last):
Python script "7", line 1, in <module>
eg.globals.some_thread.start(1.0, 10)
Python script "6", line 12, in start
threading.Thread.start(self)
File "threading.pyc", line 730, in start
RuntimeError: threads can only be started once