2011-06-09 98 views
1

我有下面的类Python函数调用

class GUI(QtGui.QMainWindow): 
    ''' 
    classdocs 
    ''' 
    """**********************************************************************""" 
    """    Constructor            """ 
    """**********************************************************************""" 
    def __init__(self, parent = None): 
      self.udpClass = MCUDP.MCUDP() 

    def insertText(self, string): 
      string = time.ctime() + ': ' + string + '\n' 
      self.messageField.insertPlainText(string) 

而且我也有在GUI类中创建MCUDP类。我的问题是我怎么能到达GUI类insertText功能MCUDP

修订

这是MCUDP

''' 
Created on 09.06.2011 

@author: robu 
''' 
import socket 
import time 
import MCGui; 

class MCUDP(object): 
    ''' 
    classdocs 
    ''' 
    """**********************************************************************""" 
    """    UDP: Broadcasting          """ 
    """**********************************************************************""" 
    def UDPBroadcast(self, ip = "255.255.255.255", UDPport = 15000, message = 'whoisthere', timeout = 10, TCPport = 30000): 
     # ip="255.255.255.255" stands for a broadcast   
     ip = str(ip) 
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
     s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True) 
     s.settimeout(timeout) 
     ownIP = socket.gethostbyname(socket.gethostname()) 
     if message.upper() == 'WHOISTHERE': 
      message = message + ';' + ownIP + ':' + str(TCPport) 
     #print "Trying to send '%s' to IP %s, Port %s!" %(message, ip, port) 
     #self.Eingang.put("Trying to send '%s' to IP %s, Port %s!" %(message, ip, UDPport)) 
     s.sendto(message, (ip, UDPport)) 
     answer = "%s: '%s' broadcasted to %s!" % (time.asctime(), message, ip) 
     GUI.insertText('test'); 
     #print answer 
     s.close() 
     return answer 

回答

6

您有两个需要相互通信的对象,这是一个相当标准的通信问题。有许多方法可以解决此问题:

(1)依赖注入 - 使您的MCUDP()类在构建时需要MCGUI类。 那么你必须使用它时,你需要:

class MCUDP(object): 
    def __init__(self, gui): self.gui = gui 
    def UDPBroadcast(...): 
     # ... as necessary ... 
     self.gui.insertText("YourText") 

class MCGUI(...) 
    def __init__(self, parent = None): 
     self.udpClass = MCUDP.MCUDP(self) 

如果你这样做你MCUDP类变得依赖它实现的是MCUDP使用self.gui所有方法的对象上。换句话说,MCUDP现在直接耦合到MCGUI类。当然,MCGUI类在某种程度上已经依赖于MCUDP。

(2)消息传递 - 在Qt,信号和插槽中。惯用的Qt路线使用的邮件,而不是函数调用:

class MCGUI(...) 
    def __init__(self, parent = None): 
     self.udpClass = MCUDP.MCUDP() 
     self.connect(self.udpClass, PYSIGNAL("textUpdated"), self.insertText); 

然后你只需要让你的MCUDP类QObject的,以便它可以发出事件:

class MCUDP(QObject): 
    def __init__(self, parent = None): 
     QObject.__init__(self, parent) 
    def UDPBroadcast(...): 
     # ... as necessary ... 
     self.emit(PYSIGNAL("textUpdated"), ("yourText",)) 

这样做的好处是现在MCUDP不需要知道MCGUI类的任何内容,这将使测试和将来的更改变得更容易。

1

它声明时可作为insertTextGUI.insertTextGUI().insertText执行过程中。如果您不确定自己的位置,请尝试两种方法:)。 如果您发布实际的完整代码,我会说你需要哪一个。

[更新] 您的MCDUP类不是“在GUI类中创建的”。您只需创建一个MCDUP实例并在GUI中保存对其的引用。基准是单向的,所以如果你需要访问父GUI实例,你需要一个反向参考,是这样的:

class GUI(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
      self.udp = MCUDP.MCUDP(gui=self) 

然后在MCDUP:

class MCUDP(object): 
    def __init__(self, gui): 
     self.gui = gui 
    def udp_broadcast(self, ...): 
     ... 
     self.gui.insertText('test') 
     ... 

我也做了代码多一点PEP8 - 煎。

+0

我刚刚更新。 – 2011-06-09 14:34:16

0

一般来说,Kaleb Pederson建议的第二个选项是要走的路。
但是,如果您想要引用MainWindow,则可以将其作为QApplication实例的属性保存为 。
当你启动应用程序:

app = QApplication(sys.argv) 
... 
mainwindow = GUI() 
app.setProperty("mainwindow", QVariant(mainwindow)) 

然后,当你想使用的参考:

... 
mainwindow = qApp.property('mainwindow').toPyObject() 
...