accessing button handlers in multiple python modules
01 Aug 2018 20:05 #115341
by tripwire
accessing button handlers in multiple python modules was created by tripwire
I've created a custom GUI in Glade (gladevcp). I have a main python module which contains handler functions for my gui widgets. this is all working fine. However, I copied in some gladevcp (xml) code from Serguei Glavatski's probe screen into my main glade file. there are lots of buttons and widgets associated with this new code who's handler functions reside in a separate file, probe_screen.py. I'm trying to keep this file separate from my main python file. I've done anat the top of my main python file. The module *is* being imported (as indicated by a diagnostic "print" statement.) But I am missing all the handlers for the probe_screen widgets.
There are get_handlers() functions in both python modules:
in my main python file:
In probe_screen.py:
I've tried referencing the handler functions the following ways, all without success:
I'm stumped at this point. Anyone have any ideas?
Thanks!
Dave L.
import probe_screen
There are get_handlers() functions in both python modules:
in my main python file:
def get_handlers(halcomp,builder,useropts):
return [HandlerClass(halcomp,builder,useropts)]
In probe_screen.py:
def get_handlers(halcomp,builder,useropts):
return [ProbeScreenClass(halcomp,builder,useropts)]
I've tried referencing the handler functions the following ways, all without success:
on_button_released
probe_screen.on_button_released
ProbeScreenClass.on_button_released
probe_screen.ProbeScreenClass.button_released
I'm stumped at this point. Anyone have any ideas?
Thanks!
Dave L.
Please Log in or Create an account to join the conversation.
01 Aug 2018 20:21 - 01 Aug 2018 20:23 #115343
by Grotius
Replied by Grotius on topic accessing button handlers in multiple python modules
A example :
The widgets location for this is : ...../lib/python/gmoccapy/widgets.py
So in your case copy your file probe_screen in that directory.
Then you can test the import once again for functionality.
You type
Good luck !
from gmoccapy import widgets
So in your case copy your file probe_screen in that directory.
Then you can test the import once again for functionality.
You type
from gmoccapy import probe_screen
Good luck !
Last edit: 01 Aug 2018 20:23 by Grotius.
Please Log in or Create an account to join the conversation.
01 Aug 2018 22:27 - 01 Aug 2018 22:48 #115350
by Grotius
Replied by Grotius on topic accessing button handlers in multiple python modules
If you look in gscreen keybindings.py
You can see a lot of info.
It's a difficult item, i searched 5 mont's ago for the same issue. Then Norbert told me he
was going to program all the button's external. But i don't have a clear example for you right now, sorry.
In all the existing examples, there are no existing button handlers. So i am curious how the coding looks like.
If there is a main pyhon file that looks after the button handler, it works.
In external file, it is a problem. The error is: handler is missing...
So in the main file you have to do all your button handlers, then your problem is solved tonight.
I never seen a exernal button event, also on google there are no plug and play examples.....
You can see a lot of info.
It's a difficult item, i searched 5 mont's ago for the same issue. Then Norbert told me he
was going to program all the button's external. But i don't have a clear example for you right now, sorry.
In all the existing examples, there are no existing button handlers. So i am curious how the coding looks like.
If there is a main pyhon file that looks after the button handler, it works.
In external file, it is a problem. The error is: handler is missing...
So in the main file you have to do all your button handlers, then your problem is solved tonight.
I never seen a exernal button event, also on google there are no plug and play examples.....
Last edit: 01 Aug 2018 22:48 by Grotius.
Please Log in or Create an account to join the conversation.
02 Aug 2018 01:10 #115363
by tripwire
Replied by tripwire on topic accessing button handlers in multiple python modules
Thanks for your replies, Grotius. Yes, it seems complicated. I found the following code in gscreen.py which seems to be looking for widget handlers in external files. I'm just trying to decipher it:
And then in the Gscreen class __init__() function the above gets called as follows:
There should be an easier way to accomplish this for external modules in known locations.
I'll probably just resort to what you suggested and put all the widget handlers in the main python file.
Thanks again!
def load_handlers(usermod,halcomp,builder,useropts,gscreen):
hdl_func = 'get_handlers'
mod = object = None
def add_handler(method, f):
if method in handlers:
handlers[method].append(f)
else:
handlers[method] = [f]
handlers = {}
for u in usermod:
(directory,filename) = os.path.split(u)
(basename,extension) = os.path.splitext(filename)
if directory == '':
directory = '.'
if directory not in sys.path:
sys.path.insert(0,directory)
print _('adding import dir %s' % directory)
try:
mod = __import__(basename)
except ImportError,msg:
print ("module '%s' skipped - import error: %s" %(basename,msg))
continue
print _("module '%s' imported OK" % mod.__name__)
try:
# look for functions
for temp in ("periodic","connect_signals","initialize_widgets"):
h = getattr(mod,temp,None)
if h and callable(h):
print ("module '%s' : '%s' function found" % (mod.__name__,temp))
# look for 'get_handlers' function
h = getattr(mod,hdl_func,None)
if h and callable(h):
print ("module '%s' : '%s' function found" % (mod.__name__,hdl_func))
objlist = h(halcomp,builder,useropts,gscreen)
else:
# the module has no get_handlers() callable.
# in this case we permit any callable except class Objects in the module to register as handler
dbg("module '%s': no '%s' function - registering only functions as callbacks" % (mod.__name__,hdl_func))
objlist = [mod]
# extract callback candidates
for object in objlist:
dbg("Registering handlers in module %s object %s" % (mod.__name__, object))
if isinstance(object, dict):
methods = dict.items()
else:
methods = map(lambda n: (n, getattr(object, n, None)), dir(object))
for method,f in methods:
if method.startswith('_'):
continue
if callable(f):
dbg("Register callback '%s' in %s" % (method, basename))
add_handler(method, f)
except Exception, e:
print ("**** GSCREEN ERROR: trouble looking for handlers in '%s': %s" %(basename, e))
traceback.print_exc()
# Wrap lists in Trampoline, unwrap single functions
for n,v in list(handlers.items()):
if len(v) == 1:
handlers[n] = v[0]
else:
handlers[n] = Trampoline(v)
return handlers,mod,object
And then in the Gscreen class __init__() function the above gets called as follows:
# look for custom handler files:
HANDLER_FN = "%s_handler.py"%skinname
local_handler_path = os.path.join(CONFIGPATH,HANDLER_FN)
if os.path.exists(local_handler_path):
temp = [HANDLER_FN]
else:
temp = []
handlers,self.handler_module,self.handler_instance = load_handlers(temp,self.halcomp,self.xml,[],self)
self.xml.connect_signals(handlers)
There should be an easier way to accomplish this for external modules in known locations.
I'll probably just resort to what you suggested and put all the widget handlers in the main python file.
Thanks again!
Please Log in or Create an account to join the conversation.
02 Aug 2018 01:45 #115365
by Grotius
Replied by Grotius on topic accessing button handlers in multiple python modules
Hi Tripwire,
Try to figure this out please. You can ask this question on the Python forum to specialists. They will have the ansfer within 2 day's
I would also like to know how the code looks like. Please post your solution over here.
Try to figure this out please. You can ask this question on the Python forum to specialists. They will have the ansfer within 2 day's
I would also like to know how the code looks like. Please post your solution over here.
Please Log in or Create an account to join the conversation.
02 Aug 2018 02:58 - 02 Aug 2018 03:00 #115367
by cmorley
Replied by cmorley on topic accessing button handlers in multiple python modules
If you are building your own GUI then there is no requirement to use a handler file.
Handler files isa way to extend GladeVCP without having to add to the source code. Gmoccapy and gscreen use it for the same reason.
If you are creating the source code and don't need to be able to extend it then yes just import the file like normally.
you need to instantiate the class, then reference it through that name.
something like this:
from probe import HandlerClass as Probe # import the class changing the name
self. probe = Probe() # instantiate the class and giving a reference name
self.probe.someFunctionName() # calling the functions using the reference name
By importing while changing the class name you avoid the problem of the two file both being name HandlerClass ( I am assuming that is true)
Hope this helps
Chris M
Handler files isa way to extend GladeVCP without having to add to the source code. Gmoccapy and gscreen use it for the same reason.
If you are creating the source code and don't need to be able to extend it then yes just import the file like normally.
you need to instantiate the class, then reference it through that name.
something like this:
from probe import HandlerClass as Probe # import the class changing the name
self. probe = Probe() # instantiate the class and giving a reference name
self.probe.someFunctionName() # calling the functions using the reference name
By importing while changing the class name you avoid the problem of the two file both being name HandlerClass ( I am assuming that is true)
Hope this helps
Chris M
Last edit: 02 Aug 2018 03:00 by cmorley.
Please Log in or Create an account to join the conversation.
02 Aug 2018 03:32 #115369
by tripwire
Replied by tripwire on topic accessing button handlers in multiple python modules
Thanks for your input, Chris M. Yes, I am doing what you suggested and it works for accessing, from the main python file, functions in the class in the external python module.
But I was trying to have widget signals (those specified in the Glade XML file) "find" their handler functions in the external python module without having to write additional code in the main python file. (So far I'm getting "missing handler" error messages for all the external handlers.)
It seems to hinge on the gladevcp get_handlers() and gtkbuilder.connect_signals() functions. But I haven't worked it out yet.
But I was trying to have widget signals (those specified in the Glade XML file) "find" their handler functions in the external python module without having to write additional code in the main python file. (So far I'm getting "missing handler" error messages for all the external handlers.)
It seems to hinge on the gladevcp get_handlers() and gtkbuilder.connect_signals() functions. But I haven't worked it out yet.
Please Log in or Create an account to join the conversation.
02 Aug 2018 19:27 #115430
by tripwire
Replied by tripwire on topic accessing button handlers in multiple python modules
OK. Here's a working example. (I don't consider it the final solution as the widget handlers, here are added manually which would be laborious with a lot of widgets. But this code does show how widget handlers can be located in different python modules...
This can be tested in Terminal with:multi-module-test.glade:
multi-module-test.py:
external_module.py:
I'll work on iterating through the handler classes to more easily create the dictionary for connect_signals(). Will keep you posted...
This can be tested in Terminal with:
python multi-module-test.py
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.18"/>
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<signal name="destroy" handler="onDestroy" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">button w. local handler</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="pressed" handler="onButton1Pressed" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">button w. external handler</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="pressed" handler="onButton2Pressed" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
multi-module-test.py:
#!/usr/bin/env python
import gtk
# the following is an external module containing a button handler:
import external_module
class Handler:
def onDestroy(self, *args):
print("quit app")
gtk.main_quit()
# local button handler:
def onButton1Pressed(self, button):
print("Button1 Pressed")
def __init__(self):
self.builder = gtk.Builder()
self.builder.add_from_file("multi-module-test.glade")
# get an instance of the handler class in the external module
self.xmod = external_module.externalHandler()
# create a dictionary of handler pairs from both this module and the external module
self.handlers = {"onButton1Pressed": self.onButton1Pressed, "onDestroy": self.onDestroy, "onButton2Pressed": self.xmod.onButton2Pressed}
# pass the dictionary to the connect_signals() function
self.builder.connect_signals(self.handlers)
self.window = self.builder.get_object("window1")
self.window.show_all()
try:
app = Handler()
except KeyboardInterrupt:
sys.exit(0)
gtk.main()
external_module.py:
#!/usr/bin/env python
import gtk
class externalHandler:
def onButton2Pressed(self, button):
print("Button2 Pressed")
I'll work on iterating through the handler classes to more easily create the dictionary for connect_signals(). Will keep you posted...
Please Log in or Create an account to join the conversation.
02 Aug 2018 21:07 #115441
by Grotius
Replied by Grotius on topic accessing button handlers in multiple python modules
Hi Tripwire,
Nice that it works now. If i look at the code, it looks like you have more work now then keeping all the button handlers in the same file.
Nice that it works now. If i look at the code, it looks like you have more work now then keeping all the button handlers in the same file.
The following user(s) said Thank You: tripwire
Please Log in or Create an account to join the conversation.
02 Aug 2018 22:22 #115458
by cmorley
Ahh I see. Yes then in that case IIRC that is a limitation of GTK's connect_signals() one can't add module reference to it.
So In that case that is where the get_handlers() was a solution. Again IIRC if adds the handler's function calls to the main python program. Then connects the signals with .connect_signals() so GTK can find the functions.
i'll point out that gscreen and gmocapy's routines are derivatives of gladevcp's own handler function.
gladevcp's functions may be easier to follow the flow as gladevcp is simpler
src/hal/user_comps/gladevcp.py
Chris M
Replied by cmorley on topic accessing button handlers in multiple python modules
But I was trying to have widget signals (those specified in the Glade XML file) "find" their handler functions in the external python module without having to write additional code in the main python file. (So far I'm getting "missing handler" error messages for all the external handlers.)
It seems to hinge on the gladevcp get_handlers() and gtkbuilder.connect_signals() functions. But I haven't worked it out yet.
Ahh I see. Yes then in that case IIRC that is a limitation of GTK's connect_signals() one can't add module reference to it.
So In that case that is where the get_handlers() was a solution. Again IIRC if adds the handler's function calls to the main python program. Then connects the signals with .connect_signals() so GTK can find the functions.
i'll point out that gscreen and gmocapy's routines are derivatives of gladevcp's own handler function.
gladevcp's functions may be easier to follow the flow as gladevcp is simpler
src/hal/user_comps/gladevcp.py
Chris M
The following user(s) said Thank You: tripwire
Please Log in or Create an account to join the conversation.
Moderators: HansU
Time to create page: 0.104 seconds