[PySide] loading gui from json data, connect slots from strings

I am experimenting with json driven PySide interfaces. I am trying to automate the connection of slots and signals of a qt interface in a construction loop.

Here is an example json:

{
	
	"components":[
		{
		"qt_type":"QPushButton",
		"name":"test  ",
		"qt_signal":"clicked()",
		"qt_slot":"test_button1"
		},
		{
		"qt_type":"QPushButton",
		"name":"another test",
		"qt_signal":"clicked()",
		"qt_slot":"test_button2"
		}
	]
}

here is the python:


#!/usr/bin/python
        
import sys
import json
from pprint import pprint
from PySide.QtCore import *
from PySide.QtGui import *
from functools import partial

class Form(QDialog):

    def __init__(self, parent=None, uifile=None):
        super(Form, self).__init__(parent)
        self.json=None
        self.components=[]
        self.label=QLabel("json gui")
        self.loadJson(uifile)

        layout=QVBoxLayout()
        layout.addWidget(self.label)

        #create and add QWidgets to self.componenets[]
        for i in range(len(self.json['components'])):
            self.components.append(QPushButton('%s' % (self.json['components'][i]['name'])))
            layout.addWidget(self.components[i])
            
        self.setLayout(layout)

        #delcare signal connections
        for i in range(len(self.json['components'])):
            button=self.components[i]
            signal=self.json['components'][i]['qt_signal']
            #not sure how to pass my string as fucntion
            slot=eval('self.'+self.json['components'][i]['qt_slot'])
            print "component[%i]
	button:%s(%s)
	signal:%s(%s)
	slot:%s(%s)
" %(i, button,type(button), signal,type(signal), slot, type(slot))
            self.connect(button,SIGNAL(signal),slot)


        self.setWindowTitle('json qt gui')

    def test_button1(self):
        print "pressed 1"
        self.label.setText("pressed 1")
        
    def test_button2(self):
        print "pressed 2"
        self.label.setText("pressed 2")

    def loadJson(self,f):
        try:
            with open(f) as data_file:    
                self.json = json.load(data_file)
        except IOError as e:
            print e
            pass


f='Pyside/gui.json'
app = QApplication(sys.argv)
form = Form(uifile=f)
form.show()
app.exec_()

the first issue is that the value for the json key ‘slot’ is type unicode,
I needed to somehow convert it to a callable python identifier, which I did using eval().
when I check the type it seems to be correct:

slot:<bound method Form.test_button1 of <__main__.Form object at 0x0000000002FE97C8>>(<type 'instancemethod'>)

but the functions aren’t executing on button press, I’m not sure why.
I can call form.test_button1() from the console and get my print statement, so the functions seem to work.
What am I missing?

getattr is all you need:


class Form(object):
  def test_button1(self):
     print "button clicked"
form = Form()

# get link to method
methodLink = getattr(form,'test_button1')

# execute
methodLink()

I was able to get it working after reading this
http://wiki.qt.io/Signals_and_Slots_in_PySide

replacing the ‘old syntax’

self.connect(button,SIGNAL(signal),slot)

with the ‘new syntax’

button.clicked.connect(slot)

did the trick.