1

I have Qt Gui class that handles all the variables (p1, p2) adjustment with sliders and stuff. Inside this class, I have a OSC listener class that was supposed to listen to trigger signals and a variable p3 from another device and use the parameters to trigger sound and graphic. But I have trouble accessing p1, p2 in the listener class. Here is an example:

class Ptsgui(QtGui.QMainWindow):
    def __init__(self):
        super(Ptsgui, self).__init__()
        self.p1, self.p2, self.data = 0, 0, np.zeros(10)
        self.initUI()

    class OscListener(object):
        def __init__(self, data):
            self.listenerData = data
            self.receive_address = '127.0.0.1', 7000
        def do_stuff_listener(self, addr, tags, stuff, source):
            print self.p1
            print self.p2
            self.p3 = stuff[0]
            trigger_sound_and_graphic(self.p1, self.p2, self.p3)

        def spawn(self):
            self.receiveServer = OSC.OSCServer(self.receive_address)
            self.receiveServer.addDefaultHandlers()
            self.receiveServer.addMsgHandler("/trigger", self.do_stuff_listener()
            self.emorating_oscServer = threading.Thread(target=self.receiveServer.serve_forever)
            self.emorating_oscServer.start()

    def initUI():
        """ 
        Some sliders setup for change the p1 & p2
        """
        self.setGeometry(50, 50, 1050, 650)
        mainlayout = QtGui.QVBoxLayout()
        self.widget = QtGui.QWidget()
        self.widget.setLayout(mainlayout)
        self.listener = OscListener(data = self.data)
        self.show()

So here I want the oscListener() to be available to directly access self.p1 and self.p2. And obviously I can't with this because the self.p1's 'self' refers to OscListener but not Ptsgui. Also the do_stuff_listener is in a separate thread, is it still possible to access self.p1 and self.p2?

Ultimately, I am hoping to the GUI for user to control the parameters values. And each time a trigger signal is received via OSC, it will generated a new graph and sound. Please advice if there is a better way to do this.

J_yang
  • 2,672
  • 8
  • 32
  • 61

2 Answers2

0

You could pass thePtsgui to OscListener like this:

class Ptsgui(QtGui.QMainWindow):
    def __init__(self):
        super(Ptsgui, self).__init__()
        self.p1, self.p2, self.data = 0, 0, np.zeros(10)
        self.initUI()

    class OscListener(object):
        def __init__(self, cls, data):
            self.parent = cls
            self.listenerData = data
            self.receive_address = '127.0.0.1', 7000
        def do_stuff_listener(self, addr, tags, stuff, source):
            print self.parent.p1 # Access it.
            print self.parent.p2
            self.p3 = stuff[0]
            trigger_sound_and_graphic(self.p1, self.p2, self.p3)

        def spawn(self):
            self.receiveServer = OSC.OSCServer(self.receive_address)
            self.receiveServer.addDefaultHandlers()
            self.receiveServer.addMsgHandler("/trigger", self.do_stuff_listener()
            self.emorating_oscServer = threading.Thread(target=self.receiveServer.serve_forever)
            self.emorating_oscServer.start()

    def initUI():
        """ 
        Some sliders setup for change the p1 & p2
        """
        self.setGeometry(50, 50, 1050, 650)
        mainlayout = QtGui.QVBoxLayout()
        self.widget = QtGui.QWidget()
        self.widget.setLayout(mainlayout)
        self.listener = OscListener(cls=self, data = self.data) # Pass it here
        self.show()
noteness
  • 2,440
  • 1
  • 15
  • 15
0

What you trying to achieve can be done like that:

class Ptsgui(QtGui.QMainWindow):
    def __init__(self):
        super(Ptsgui, self).__init__()
        self.p1, self.p2, self.data = 0, 0, np.zeros(10)
        self.initUI()

    def initUI():
        """
        Some sliders setup for change the p1 & p2
        """
        self.setGeometry(50, 50, 1050, 650)
        mainlayout = QtGui.QVBoxLayout()
        self.widget = QtGui.QWidget()
        self.widget.setLayout(mainlayout)
        self.listener = OscListener(gui=self, data=self.data)
        self.show()


class OscListener(object):
    def __init__(self, gui, data):
        self.gui = gui
        self.listenerData = data
        self.receive_address = '127.0.0.1', 7000
    def do_stuff_listener(self, addr, tags, stuff, source):
        print self.gui.p1
        print self.gui.p2
        self.p3 = stuff[0]
        trigger_sound_and_graphic(self.gui.p1, self.gui.p2, self.gui.p3)

    def spawn(self):
        self.receiveServer = OSC.OSCServer(self.receive_address)
        self.receiveServer.addDefaultHandlers()
        self.receiveServer.addMsgHandler("/trigger", self.do_stuff_listener()
        self.emorating_oscServer = threading.Thread(target=self.receiveServer.serve_forever)
        self.emorating_oscServer.start()

See that the class nesting from your code sample is not needed.

Also, it seems to me that what you are trying to achieve is not right. The code is extremely coupled. Consider decoupling Ptsgui and OscListener. Check Observer pattern for some inspiration.

Jordan Jambazov
  • 3,460
  • 1
  • 19
  • 40
  • Thank you. This is exactly what I need. So does it means it passes the pointers of Ptsgui to OscListener? In that case, can I directly change the values of p1 and p2 in OscListener? – J_yang Aug 28 '16 at 21:03
  • Yes, correct. You can do that, but as I mentioned the code is very coupled. If you would like to have a better solution, try to decouple it using some design patterns, e.g. observer pattern. – Jordan Jambazov Aug 30 '16 at 15:26