Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
子代调用父代';s方法而不调用父对象';python中的s_uuinit_uu_Python_Multithreading_Inheritance_Pyqt_Parent Child - Fatal编程技术网

子代调用父代';s方法而不调用父对象';python中的s_uuinit_uu

子代调用父代';s方法而不调用父对象';python中的s_uuinit_uu,python,multithreading,inheritance,pyqt,parent-child,Python,Multithreading,Inheritance,Pyqt,Parent Child,我有一个程序,在主线程中有一个PyQt中的gui。它与光电探测器通信并获取另一个线程中的功率读数,该线程向主线程发送信号以更新gui的功率值。 现在我想用一个马达来自动校准我的光纤,从光电探测器得到反馈 所以我创建了一个控制电机的类,但我必须以某种方式将光电探测器的读数传递给该类。首先,我试图访问parent的power变量,但没有成功。 然后,我在gui中创建了一个方法来返回变量的值,并尝试从motor类访问它。我遇到一个问题,就是如果不先使用父方法的\uuuu init\uuuu,我就无法使

我有一个程序,在主线程中有一个PyQt中的gui。它与光电探测器通信并获取另一个线程中的功率读数,该线程向主线程发送信号以更新gui的功率值。 现在我想用一个马达来自动校准我的光纤,从光电探测器得到反馈

所以我创建了一个控制电机的类,但我必须以某种方式将光电探测器的读数传递给该类。首先,我试图访问parent的power变量,但没有成功。 然后,我在gui中创建了一个方法来返回变量的值,并尝试从motor类访问它。我遇到一个问题,就是如果不先使用父方法的
\uuuu init\uuuu
,我就无法使用它。有办法绕过它吗?我不能再次调用gui
\uuuu init\uuuu
,我只想在子类中使用它的一个方法

如果有别的办法,我也会很高兴的

PS:我想我不能给孩子们一个光电探测器对象,因为它在另一个线程中,对吗

--编辑-- gui代码是:

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类,它位于另一个线程中,但与gui位于同一个文件中:

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)

用于
NanoMax
MyApp
\uuuuuuuu init\uuuuuuuuu()
应调用
super()。\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
以确保所有级别的初始化都已完成(如果这是Python 2,您不能使用无参数
super
,因此它将是
super(NanoMax,self)。\uuuuuuuuuu init()
)分别)。这假设
PyQT
是用新型类正确编写的,并且正确使用了
super
本身;您在其他地方使用的是
super
,所以至少前者是正确的。在所有类中适当地使用
super
将确保所有级别都被
初始化一次,而手动列出超类在某些继承模式下不起作用,或者可能多次调用某些
\uuuu初始化
或根本不调用

如果许多级别可能采用参数,您还应该接受
*args
/
**kwargs
,并将它们转发到
super()。\uuuu init\uuuu
调用,以便将参数转发到需要的位置

将两者结合起来,您的代码应该如下所示:

class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        super(MyApp, self).__init__(*args, **kwargs)
        ... rest of __init__ ...

class PDThread(QtCore.QThread):
    def __init__(self, state, port, *args, **kwargs):
        super(PDThread, self).__init__(*args, **kwargs)
        ...

class NanoMax(gui.MyApp): #inheriting parent

    def __init__(self, mcontroller_port, *args, **kwargs):
        super(NanoMax, self).__init__(*args, **kwargs)
        self.mcontroller = Nano(mcontroller_port) #mcontroller is the communication to the motor
注意:如果您重载了超类可能在其
\uuuu init\uuuuu
中调用的方法,并且您的重载依赖于您自己的
\uuuu init\uuuu
中设置的状态,那么您需要在
super()之前而不是之后设置该状态。合作多重继承可能是一种痛苦。还请注意,对除最低级别的类以外的任何对象使用位置参数可能会导致多重继承,因此按关键字传递所有参数可能是有意义的,并且只接受并转发
**kwargs
,而不是
*args
,因此,如果继承层次结构稍有改变,人们传递位置参数的方式不会中断

class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    self.PDvalue = 0 #initial PD value
    self.PDState = 0 #control the PD state (on-off)
在上面的代码中,它是在函数外部设置变量。在类中执行此操作时,不要将self关键字放在前面。这样,您就可以在类定义中

class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    PDvalue = 0 #initial PD value
    PDState = 0 #control the PD state (on-off)
在超级系列中

power = super(NanoMax, self).PDvalue
例如:

>>> class Hi:
  H = 5
  def __init__(self):
    self.g = 6

>>> class Bye(Hi):
  def H(self):
    print(super(Bye, self).H)

>>> e = Bye()
>>> e.H()
5
>>> 

我试图访问家长的电源变量。。。父母?这个motor类是从GUI类继承的吗?这似乎不正确,甚至没有用处。motor类的实例可以从另一个线程中的photo detector对象获取数据,但可能需要一个锁来确保线程安全。假设你的phote探测器有一个getter方法,它使用
线程.Lock
读取数据。你能分享你的代码吗?理想情况下不是全部,但至少是类和它们之间通信的线路?它是这样工作的,但它总是读取0表示功率。我认为这是因为他正在读取父类变量,而不是实例变量。还是我做错了什么?我也将主代码中的所有self.PDvalue更改为MyApp.PDvalue。很抱歉,我没有复制到帖子中的代码,但我正在初始化MyApp类。现在我更改了您提到的所有
\uuuuu init\uuuuu
,即
super(MyApp,self)。\uuuu init\uuuu()
。然而,我得到了一个无限循环
\uuu inits
\uuuu`。MyApp启动NanoMax,后者再次启动MyApp构造函数,依此类推forth@Eduardo:要么您误用了
super
(将错误的类型作为第一个参数传递),要么您的代码被设计破坏。你确定
NanoMax
\uuuuu init\uuuuuu
正在使用
super(NanoMax,self)
MyApp
super(MyApp,self)
?即使如此,在重读时,
MyApp
将创建
NanoMax
的实例,而
NanoMax
MyApp
,这可能是错误的;看起来您正在将继承与组合相结合,将两者都打破;如果
NanoMax
MyApp
MyApp
不需要
NanoMax
;如果
MyApp
需要
NanoMax
NanoMax
不应该是
MyApp
。否则就全是圆形的。@shaderanger:是的,他们都在用super。此外,我同意你刚才所说的,这是有道理的。在我的例子中,发生的是:我只想允许NanoMax读取我的MyApp对象的一个变量,它实际上不需要是MyApp的子对象。还有其他方法吗?@Eduardo:当
MyApp
构造
NanoMax
时,将
self
传递给
NanoMax
的构造函数,以便它引用
MyApp
实例?这可能是
MyApp
构造函数中完成的最后一件事,因此
MyApp
已完全构建;或者,
NanoMax
存储参考以供以后使用,但不在
\uuuuu init\uuuuuu
中使用它(在可能的位置)