2016-03-24 8 views
1

Class2 ist meine Haupt-APP, die Liste der Schaltflächen aus favList anzeigt. In der displayLibrary erstelle ich Button mit Class1 Instance. Wenn Benutzer klicken Sie auf eine Schaltfläche (simulateButtonClick), ich musste doppelte Funktion von Class1 Dort führen ich werde alle erforderlichen Sachen zu duplizieren Objekt in Maya, und ich möchte dieses Material mit Class2.addSlot Funktion hinzufügen (weil ich viel bekam . von dort überprüft und keine unnötigen Code wollen)Daten übertragen und defs zwischen Klassen ohne Instanzen verwenden - möglicherweise Singleton Pattern

So ist der Deal, diese Verbindungen zu schaffen: 1. Class2.displayLibrary -> erstellen Tasten mit Instanz von Class1 2. Wenn Class2.simulateButtonClick verwendet -> goto Class1.duplicateNetwork -> goto Class2.addSlot Und die zweite bin ich die härteste, denn wenn ich von Button DuplicateNetwork aufrufen, rufe ich die Instanz, die ich erstellt habe, und es ist in Ordnung. aber wenn ich zu Class2.addSlot zurückkehren möchte, kann ich keine Instanz erstellen. Ich muss die einzige verwenden, die ich am Anfang verwende. Deshalb versuche ich Singleton zu verwenden.

Ich habe diese 2 Zeilen kommentiert, die Fehler verursachen.

favList = [] 
buttons = {} 
favList.append("shader1") 
favList.append("shader2") 
favList.append("shader3") 
favList.append("shader4") 

class Singleton(object): 
    _instances = {} 
    def __new__(class_, *args, **kwargs): 
     if class_ not in class_._instances: 
      class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs) 
     else: 
      # class_._instances[class_].__init__(class_, *args, **kwargs) 
      class_._instances[class_].__init__(*args, **kwargs) 
     return class_._instances[class_] 

class Class1(Singleton): 
    def __init__(self, name): 
     print ("Just test if name is working: {0}").format(name) 

    @staticmethod 
    def duplicateNetwork(self): 
     newMaterial = "shader8000" 
     Class2.addSlot(newMaterial) 

class Class2(Singleton): 
    def __init__(self): 
     print "Do something in Class2" 
     self.displayLibrary() 
     self.simulateButtonClick() 

    def addSlot(self, shaderName=None): 
     favList.append(shaderName) 
     self.displayLibrary() 

    def displayLibrary(self): 
     for i,obj in enumerate(favList): 
      # create button with Class1 Instance 
      buttons[i] = Class1(obj) 
      print("Shader library contains: {0}").format(obj) 

    def simulateButtonClick(self): 
     material = "Shader6000" 
     # Simulate click for button "Shader1" 
     buttons[0].duplicateNetwork(self) 


run = Class2() 

Jetzt habe ich Fehler: Tasten [i] = Class1 (obj)

Traceback (most recent call last): 
    File "G:\kTools\singlethon.py", line 46, in <module> 
    run = Class2() 
    File "G:\kTools\singlethon.py", line 27, in __init__ 
    self.displayLibrary() 
    File "G:\kTools\singlethon.py", line 38, in displayLibrary 
    buttons[i] = Class1(obj) 
    File "G:\kTools\singlethon.py", line 13, in __new__ 
    class_._instances[class_].__init__(class_, *args, **kwargs) 
TypeError: __init__() takes exactly 2 arguments (3 given) 

Das ist, weil ich in Singleton in anderen Wenn class_ wurde. Ich habe auch diese Zeile kommentiert, aber könnten Sie mir sagen, warum? Ich weiß nicht, warum es notwendig ist, * args ** kwargs zu sein, ich weiß meistens, was sie sind, aber keine Idee, warum ich sie in Singleton brauche.

Zweiter Fehler:

Traceback (most recent call last): 
    File "G:\kTools\singlethon.py", line 49, in <module> 
    run = Class2() 
    File "G:\kTools\singlethon.py", line 31, in __init__ 
    self.simulateButtonClick() 
    File "G:\kTools\singlethon.py", line 46, in simulateButtonClick 
    buttons[0].duplicateNetwork(self) 
    File "G:\kTools\singlethon.py", line 25, in duplicateNetwork 
    Class2.addSlot(newMaterial) 
TypeError: unbound method addSlot() must be called with Class2 instance as first argument (got str instance instead) 

Und für diese, ich habe Problem von Anfang an. Keine Ahnung, wie man es löst.

+0

Sie ein komplettes Arbeitsbeispiel liefern können, so können wir leicht sehen, was falsch ist? Wenn Sie Ihren Code mit 'favouriteMaterial_UI.addSlot (shader)' kommentiert, gibt es keinen Fehler bei der Ausführung von 'RightClickMenuButton()' ... Auch, welche Version von Python benutzen Sie? – Silmathoron

+0

Sicher ist dies meine vollständige Codeskizze. http://pastebin.com/4rPv3xDG und QTutils zu importieren http: // Pastebin.com/ANUVkX1D Sie können es in Autodesk Maya ausführen – user2455219

+0

Viele Dinge zu kommentieren, um Ihren Code auf meinem Laptop laufen zu lassen gibt keinen Fehler beim Erstellen 'favouriteMaterial_UI' ... Sie änderten auch' __call__' zu '__new__', was macht mehr Sinn für mich. Bitte versuchen Sie ein ** wirkliches ** minimal funktionierendes Beispiel ohne unnötige Bibliothek (wie Maya, Shiboken, etc.) auszuarbeiten, die immer noch den Fehler anzeigt, der Sie beunruhigt, so dass jeder den gleichen Code ausführt. Bearbeiten Sie Ihren Beitrag, um den alten Code zu ersetzen. – Silmathoron

Antwort

0

Nach dem neuen bearbeiten sehen, ich glaube, Sie wollen einfach nur einen Verweis auf Class2 in jedem Class1 so dass diese sollte es tun (Sie wahrscheinlich Singleton nicht brauchen):

from weakref import proxy 

favList = [] 
buttons = {} 
favList.append("shader1") 
favList.append("shader2") 
favList.append("shader3") 
favList.append("shader4") 

class Class1: 
    def __init__(self, name, parent): 
     self.parent = proxy(parent) 
     print ("Just test if name is working: {0}").format(name) 

    def duplicateNetwork(self): 
     newMaterial = "shader8000" 
     self.parent.addSlot(newMaterial) 

class Class2: 
    def __init__(self): 
     print "Do something in Class2" 
     self.displayLibrary() 
     self.simulateButtonClick() 

    def addSlot(self, shaderName=None): 
     favList.append(shaderName) 
     self.displayLibrary() 

    def displayLibrary(self): 
     for i,obj in enumerate(favList): 
      # create button with Class1 Instance 
      buttons[i] = Class1(obj, parent=self) 
      print("Shader library contains: {0}").format(obj) 

    def simulateButtonClick(self): 
     material = "Shader6000" 
     # Simulate click for button "Shader1" 
     buttons[0].duplicateNetwork() 


run = Class2() 
+0

Ich sehe, dass ich in meinem Code einige weniger komplexe Anrufe machen kann, und ich werde das tun. Ich lerne gerade und ohne Programmierhintergrund ist es nicht immer klar vom Anfang an. Sie haben die statische Methode verwendet, aber Sie haben keine beliebigen Defs von der Klasse RightClickMenuButton in der Klasse favoriteMaterial_UI aufgerufen. Wenn ich das versuche, habe ich immer noch die gleichen Fehler. Auch wenn ich eine andere Struktur verwenden kann, wenn Sie mir bitte helfen können, defs zwischen Klassen aufzurufen, ohne jedes Mal neue Instanzen zu erstellen. Deshalb habe ich versucht, Singleton zu verwenden. Jetzt Code ich Sie gab, kann ich Singleton löschen und es funktioniert immer noch die gleichen – user2455219

+0

(Warum übergeben Sie Eltern, Name und * Args, ** Kwargs zu Super-Anrufe?) In diesem Beispiel sind sie nicht notwendig, aber Sie haben mir geholfen, UI in PySide für Maya zu erstellen. – user2455219

+0

Okay, könntest du genau erklären, was du machen willst? Was meinst du mit "Call Defs zwischen den Klassen"? (Versuchen Sie, Ihren ersten Beitrag zu bearbeiten, um es für jeden verständlich zu machen) Bitte posten Sie auch den genauen Fehler, den Sie begegnen (die ** ganze ** Nachricht): wie Sie sehen, weder Kevin noch ich bekommen so etwas ... – Silmathoron

0

Okay, ich denke, dass ich es beheben konnte. Sie hatten gerade self als Argument fehlt.

RightClickMenuButton.duplicateNetwork(self) 

und wenn ich es lief bekam ich einen anderen Fehler in Zeile 27 so fixiert i, dass self wieder durch Zugabe.

favoriteMaterial_UI.addSlot(self, shader) 

so ist der endgültige Code.

favList = [] 
favList.append("shader1") 
favList.append("shader2") 
class Singleton(type): 
    _instances = {} 
    def __call__(cls, *args, **kwargs): 
     if cls not in cls._instances: 
      cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 
     else: 
      cls._instances[cls].__init__(*args, **kwargs) 
      # class_._instances[class_].__init__(class_, *args, **kwargs) 
     return cls._instances[cls] 

class RightClickMenuButton(object): 
    __metaclass__ = Singleton 
    def __init__(self): 
     print("Sygnal z Init RightClickMenu") 
     self.addMenuActions() 

    def addMenuActions(self): 
     print("Sygnal z addMenuActions") 
     self.duplicateNetwork() 

    def duplicateNetwork(self): 
     shader = "shader3" 
     print("Sygnal z duplikateNetwork") 
     favoriteMaterial_UI.addSlot(self, shader) 

class favoriteMaterial_UI(object): 
    __metaclass__ = Singleton 
    def __init__(self): 
     print("Sygnal z init favoriteMaterial_UI") 
     self.displayLibrary() 
     self.wymuszonyKlikPrzycisku() 

    def wymuszonyKlikPrzycisku(self): 
     print("click") 
     RightClickMenuButton.duplicateNetwork(self) 

    def addSlot(self, obj): 
     favList.append(obj) 
     self.refreshSlot() 

    def displayLibrary(self): 
     print("Wyswietlam liste:") 
     for obj in favList: 
      print(obj) 

    def refreshSlot(self): 
     print("Sygnal z refreshSlot") 
     self.displayLibrary() 


c = favoriteMaterial_UI() 

wenn dies nicht das war, was Sie wo suchen i hoffe jemand anderes kann Ihnen helfen! :)

+0

Sie haben keine Fehler? Ich habe: Linie 38, in wymuszonyKlikPrzycisku RightClickMenuButton.duplicateNetwork (Selbst-) Typeerror: ungebundene Methode duplicateNetwork() muss mit RightClickMenuButton Instanz als erstes Argument aufgerufen werden (bekam favoriteMaterial_UI Instanz statt) Script Ausgabe sein sollte: Sygnał z init favoriteMaterial_UI/ Wyswietlam liste:/ shader1/ Shader2/ Klick/ Sygnał z duplikateNetwork/ Sygnał z refreshSlot/ Wyswietlam liste:/ shader1/ Shader2/ shader3 – user2455219

+0

Nö, im nicht sicher, warum Sie bekommen ein Fehler. 'Sygnał z init favoriteMaterial_UI Wyswietlam liste: shader1 Shader2 Klick Sygnał z duplikateNetwork Sygnał z refreshSlot Wyswietlam liste: shader1 Shader2 shader3' das ist der Ausgang i bekam. –

+0

Sie haben korrekte Ausgabe. Vielleicht weil mein Python 2,7 ist? Welches ist deines? Ich habe den Beitrag mit einem neuen Code aktualisiert, es funktioniert für Sie? (Denken Sie daran, den Button vor der Überprüfung auszukommentieren) – user2455219

Verwandte Themen