У меня есть программа, которая имеет gui в PyQt в основном потоке. Он связывается с фотодетектором и получает показания мощности в другом потоке, который посылает сигнал в основной поток, чтобы обновить значение мощности gui. Теперь я хочу использовать двигатель для автоматического выравнивания оптического волокна, получения обратной связи с фотодетектором.Ребенок, вызывающий родительский метод без вызова родительского __init__ в python
Итак, я создал класс, который управляет двигателями, но мне нужно как-то передать показания фотодетекторов этому классу. Во-первых, я попытался получить доступ к переменной мощности родителя, но это не сработало. Затем я создал метод в моем gui, чтобы вернуть значение переменной и попытался получить к нему доступ из класса motor. У меня возникла проблема, говоря, что я не мог использовать метод родителя, не используя сначала его __init__
. Есть ли способ обойти его? Я не могу снова вызвать gui __init__
, я просто хочу использовать один из его методов из дочернего класса.
Если есть альтернативный способ сделать это, я был бы счастлив.
PS: Я думаю, я не могу дать ребенку класс объекта фотодетекторов, потому что он находится в другом потоке, верно?
--Edit-- графического пользовательского интерфейса код:
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
self.PDvalue = 0 #initial PD value
self.PDState = 0 #control the PD state (on-off)
self.PDport = self.dialog.pm100d.itemText(self.dialog.pm100d.currentIndex()) #gets pot info
def __init__(self):
... #a lot of other stuff
self.nano = AlgoNanoMax.NanoMax('COM12') #creates the motor object
self.nano_maxX.clicked.connect(self.NanoMaximizeX) #connect its fun to a buttom
self.actionConnect_PM100D.triggered.connect(self.ActionConnect_PM100D) #PD buttom
def NanoMaximizeX(self):
self.nano.maximize_nano_x() #uses motor object function
def ActionConnect_PM100D(self):
if self.PDState == 0: #check if PD is on
self.PD = PDThread(self.PDState, self.PDport) #creates thread
self.PD.valueupdate.connect(self.PDHandler) #signal connect
self.PD.dialogSignal.connect(self.PDdialog) #create error dialog
self.threads = []
self.threads.append(self.PD)
self.PD.start() #start thread
else:
self.PDState = 0
self.PD.state = 0 #stop thread
self.startpd.setText('Start PD') #change buttom name
def PDHandler(self, value):
self.PDvalue = value #slot to get pow from thread
def ReturnPow(self):
return self.PDvalue #return pow (I tried to use this to pass to the motor class)
def PDdialog(self):
self.dialog.set_instrument('PM100D') #I have a dialog that says error and asks you to type the right port
if self.dialog.exec_() == QtGui.QDialog.Accepted: #if Ok buttom try again
ret = self.dialog.pm100d.itemText(self.dialog.pm100d.currentIndex()) #new port
self.PD.port = str(ret)
self.PD.flagWhile = False #change PD stop loop condition to try again
else: #pressed cancel, so it gives up
self.PD.photodetector.__del__() #delete objects
self.PD.terminate() #stop thread
self.PD.quit()
Теперь класс PD, который находится в другом потоке, но в том же файле графического интерфейса:
class PDThread(QtCore.QThread):
valueupdate = QtCore.pyqtSignal(float) #creating signals
dialogSignal = QtCore.pyqtSignal() #signal in case of error
state = 1 #used to stop thread
def __init__(self, state, port):
QtCore.QThread.__init__(self)
self.photodetector = PM100D() #creates the PD object
self.port = port
def run(self):
while True:
self.flagWhile = True #used to leave while
try:
self.photodetector.connect(self.port) #try to connect
except:
self.dialogSignal.emit() #emit error signal
while self.flagWhile == True:
time.sleep(0.5) #wait here until user press something in the dialog, which is in another thread
else:
break #leave loop when connected
window.PDState = 1 #change state of main gui buttom (change functionality to turn off if pressed again)
window.startpd.setText('Stop PD') #change buttom label
while self.state == 1:
time.sleep(0.016)
value = self.photodetector.get_pow() #get PD pow
self.valueupdate.emit(value) #emit it
Файл AlgoNanoMax :
import gui
from NanoMax import Nano
class NanoMax(gui.MyApp): #inheriting parent
def __init__(self, mcontroller_port):
self.mcontroller = Nano(mcontroller_port) #mcontroller is the communication to the motor
def maximize_nano_x(self, step=0.001, spiral_number=3):
''' Alignment procedure with the nano motor X'''
print 'Optimizing X'
power = super(NanoMax, self).ReturnPow() #here I try to read from the photodetector
xpos = self.mcontroller.initial_position_x
position = []
position = [[power, xpos]]
xsign = 1
self.mcontroller.move_relative(self.mcontroller.xaxis, (-1) * spiral_number * step)
print 'X nano move: '+ str((-1) * spiral_number * step * 1000) + ' micrometers'
time.sleep(4)
power = super(NanoMax, self).ReturnPow()
xpos += (-1) * spiral_number * step
position.append([power, xpos])
for _ in xrange(2*spiral_number):
self.mcontroller.move_relative(self.mcontroller.xaxis, xsign * step)
print 'X nano move: '+ str(xsign * step * 1000) + ' micrometers'
time.sleep(5)
power = super(NanoMax, self).ReturnPow()
xpos += xsign * step
position.append([power, xpos])
pospower = [position[i][0] for i in xrange(len(position))]
optimalpoint = pospower.index(max(pospower))
x_shift = (-1) * (xpos - position[optimalpoint][1])
print 'Maximum power: ' + str(max(pospower)) + ' dBm'
print 'Current power: ' + str(super(NanoMax, self).ReturnPow()) + ' dBm'
self.mcontroller.move_relative(self.mcontroller.xaxis, x_shift)
_I пытался получить доступ к мощности variable_ родителя ... родитель ? Этот класс моторов наследуется от класса GUI? Это не кажется правильным или даже полезным. Экземпляр класса двигателя может получить данные от объекта фотодетектора в другом потоке, но может потребоваться блокировка, чтобы сделать его потокобезопасным. Предположим, ваш фотодетектор имеет метод геттера, который использует 'threading.Lock' для чтения данных. – tdelaney
Не могли бы вы поделиться своим кодом? В идеале не все это, но, по крайней мере, классы и линии, где они общаются между собой? – brandizzi