2016-08-28 14 views
0

У меня есть класс Qt Gui, который обрабатывает все переменные (p1,, p2) с ползунками и т. Д. Внутри этого класса у меня есть класс слушателя OSC, который должен был слушать триггерные сигналы и переменную p3 с другого устройства и использовать параметры для запуска звука и графики. Но у меня проблемы с доступом к p1, p2 в классе слушателя. Вот пример:Python, класс внутри класса, как получить доступ к переменным из верхнего класса

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() 

Так вот я хочу oscListener() быть доступны для прямого доступа self.p1 и self.p2. И, очевидно, я не могу этого сделать, потому что «я» self.p1 относится к OscListener, но не к Ptsgui. Также do_stuff_listener находится в отдельном потоке, возможно ли получить доступ к self.p1 и self.p2?

В конечном счете, я надеюсь на графический интерфейс пользователя для управления значениями параметров. И каждый раз, когда сигнал триггера принимается через OSC, он генерирует новый график и звук. Пожалуйста, совет, если есть лучший способ сделать это.

ответ

0

То, что вы пытаетесь достичь можно сделать так:

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() 

Смотрите, что класс раскрой из вашего образца кода не необходимо.

Кроме того, мне кажется, что то, чего вы пытаетесь достичь, неверно. Код чрезвычайно связан. Рассмотрим развязку Ptsgui и OscListener. Проверьте Observer pattern для некоторого вдохновения.

+0

спасибо. Это именно то, что мне нужно. Значит ли это, что он передает указатели Ptsgui на OscListener? В этом случае я могу напрямую изменить значения p1 и p2 в OscListener? –

+0

Да, правильно. Вы можете это сделать, но, как я уже говорил, код очень связан. Если вы хотите получить лучшее решение, попробуйте отделить его, используя некоторые шаблоны проектирования, например. шаблон наблюдателя. –

0

Вы могли бы передать Ptsgui в OscListener так:

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()