Jiajun Yang Jiajun Yang - 3 months ago 12
Python Question

Python, A class within a class, how to access variables from the upper class

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.

Answer

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.

Comments