2011-06-09 120 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() 
...