Zum Inhalt springen

Marionette, Popup mit Werten aus Tabelle


hölzli

Empfohlene Beiträge

Ich möchte gerne ein Marionette Node erstellen, welches "dynamisch" die Werte aus einer Tabelle zur Auswahl stellt und die entsprechenden Werte aus den jeweiligen Spalten wiedergibt.

 

Die Auswahl funktioniert soweit, dass im Popup die richtigen Werte stehen. Beim Ausführen erhalte ich jedoch eine Meldung, dass ein Name nicht definiert ist - genau der Name, welcher jedoch für die Auswahl ja zu funktionieren scheint ?

 

Wie kann ich ein Script so ausführen lassen, dass die Namen sowohl in der Nodedefinition wie auch in der Ausführung verfügbar sind?

 

Inhalt des Nodes:

#gim2020-11-19
#Modified April 2017

#Script zur Auswahl der Tabelle und der Werte
tabname = 'Spot Standard' #Name der Tabelle
tab = vs.GetObject(tabname) #Handle zur Tabelle
(numRows, numColumns) = vs.GetWSRowColumnCount(tab) #Zählt die Anzahl Zeilen und Spalten
	
def frange(x, y, jump): #x entspricht der Startzeile in der Tabelle, y der letzten Zeile, jump ist die Schrittgrösse
	while x - y <= .000001:
		yield x
		x += jump

list = []
list = [n for n in frange(2, numRows, 1)] #erstellt eine Liste, welche Zeilen aus der Tabelle ausgewählt werden sollen
	
Artikelbeschriebe = []
Artikelnummern = []
for i in range(len(list)):
	Artikelbeschriebe.append(vs.GetWSCellFormulaN(tab, list[i], 1)) #Die Beschriebe sind in der ersten Spalte
	Artikelnummern.append(vs.GetWSCellFormulaN(tab, list[i], 2)) #Die Nummern sind in der zweiten Spalte


@Marionette.NodeDefinition
class Params(metaclass = Marionette.OrderedClass):
#APPEARANCE
	#Name
	this = Marionette.Node( 'Popup' )	
	this.SetDescription('This node demonstrates the use of a Popup OIP control. The values returned by this node will be integers based on your selection starting with 0 for the first option and increasing by 1 for consecutive options.')
	
	#Input Ports
		
	#OIP Controls
	input = Marionette.OIPControl( 'Popup', Marionette.WidgetType.Popup, 0, Artikelbeschriebe)
	input.SetDescription('an OIP control representing the options designated within the script editor')
	
	#Output Ports
	outputs = Marionette.PortOut('sArtikel')
	outputs.SetDescription('Artikelbeschrieb')
	outputn = Marionette.PortOut('nArtikel')
	outputn.SetDescription('Artikelnummer')
	
#BEHAVIOR

def RunNode(self):
	#inputs
	pass
	
	input = self.Params.input.value #Integer der Auswahl
	Artb = self.Params.Artikelbeschriebe.value
	Artn = self.Params.Artikelnummern.value
	
	#script
	outputs = Artb[input]
	outputn = Artn[input]
	
	#outputs
	self.Params.outputs.value = outputs
	self.Params.outputn.value = outputn

Die Tabelle sowie das Popup im OIP:

image.png.a508a69ff90be1cf397e89eeda799d91.pngimage.png.236b587066a40d0f6dbc168d374d1f6a.png

 

und die ernüchternde Fehlermeldung:

image.png.4fdff07aee057ef89819b51e013009e4.png

Popup mit Werten aus Tabelle_2020-11-19.vwx

  • Like 1

Vectorworks 2022 interiorcad |  Windows11

Link zu diesem Kommentar

Wow, habe gar nicht gewusst, dass vor @Marioette.NodeDefiniton noch Code eingefügt werden kann. Habe noch nie einen solchen Node gesehen und weiss ehrlich gesagt auch nicht, was das mit der Funktion des Nodes macht und ob es überhaupt legal ist.

 

Ich habe auch schon versucht, ein PopUp dynamisch mit einem Input von der Marionette zu füllen. Dieses Vorhaben funktioniert allerdings nicht. Bei dir ist die Situation allerdings leicht anders, da die Werte nicht nur während der Laufzeit des Scripts verfügbar sind, sondern die ganze Zeit fix in der Tabelle stehen. Ich erwähne, dies nur, damit du gewarnt bist, dass dein Vorhaben eventuell nicht funktionieren könnte.

 

Da mich der Vorabcode gestört hat, habe ich ihn direkt unter der Klasse Params eingebaut. Die Fehlermeldung hat sich daraufhin geändert, und nach dem Weglassen von .value beim Wertimport von RunScript gibt dir der Node schon einmal den gewählten String aus.

 

Was allerdings noch nicht funktioniert, ist das Update der OIP. Das ist aber ein Thema, bei dem Marionette allgemein Mühe hat. Egal mit was für Methoden ich den Node resete, das Update der OIP funktionert nicht richtig. Am Besten funktioniert noch das Bearbeiten des Codes. Dann ist durchnittlich nach dem dritten Klick auf OK die OIP aktualisiert. Dieses Problem besteht allerdings auch bei deinem Originalcode und ist eher auf das Tool, als auf den Code zurückzuführen. Vielleicht findest du eine Möglichkeit zur zuverlässigen Aktualisierung.

 

Dein Node wird sich allerdings nicht ohne einen Kick von selbst aktualisieren. Du müsstest einen Weg finden, eine Änderung der Tabelle abzufangen und den Node erst dann zu aktualisieren. Ich habe allerdings noch nie einen Ereignisslistener in Marionette gesehen. Es gibt aber allem anschein nach noch eine Menge, was ich noch nie gesehen habe. ?Und die Tatsache, dass es diese Listener für PIOs gibt, macht Hoffnung, dass es eventuell auch in Marionette möglich ist.

@Marionette.NodeDefinition
class Params(metaclass = Marionette.OrderedClass):
#APPEARANCE
	tabname = 'Spot Standard' #Name der Tabelle
	tab = vs.GetObject(tabname) #Handle zur Tabelle
	(numRows, numColumns) = vs.GetWSRowColumnCount(tab) #Zählt die Anzahl Zeilen und Spalten
		
	def frange(x, y, jump): #x entspricht der Startzeile in der Tabelle, y der letzten Zeile, jump ist die Schrittgrösse
		while x - y <= .000001:
			yield x
			x += jump

	list = []
	list = [n for n in frange(2, numRows, 1)] #erstellt eine Liste, welche Zeilen aus der Tabelle ausgewählt werden sollen
		
	Artikelbeschriebe = []
	Artikelnummern = []
	for i in range(len(list)):
		Artikelbeschriebe.append(vs.GetWSCellFormulaN(tab, list[i], 1)) #Die Beschriebe sind in der ersten Spalte
		Artikelnummern.append(vs.GetWSCellFormulaN(tab, list[i], 2)) #Die Nummern sind in der zweiten Spalte

	#Name
	this = Marionette.Node( 'Popup' )	
	this.SetDescription('This node demonstrates the use of a Popup OIP control. The values returned by this node will be integers based on your selection starting with 0 for the first option and increasing by 1 for consecutive options.')
	
	#Input Ports
		
	#OIP Controls
	input = Marionette.OIPControl( 'Popup', Marionette.WidgetType.Popup, 0, Artikelbeschriebe)
	input.SetDescription('an OIP control representing the options designated within the script editor')
	
	#Output Ports
	outputs = Marionette.PortOut('sArtikel')
	outputs.SetDescription('Artikelbeschrieb')
	outputn = Marionette.PortOut('nArtikel')
	outputn.SetDescription('Artikelnummer')
	
#BEHAVIOR

def RunNode(self):
	#inputs
	input = self.Params.input.value #Integer der Auswahl
	Artb = self.Params.Artikelbeschriebe
	
	#script
	outputs = Artb[input]
	
	#outputs
	self.Params.outputs.value = outputs
	self.Params.outputn.value = 0

@Dominique Corpataux, was meinst du zu diesem Vorhaben?

  • Like 1

Freundliche Grüsse

 

Manuel Roth

_________________________________________________
Vectorworks 2022 SP3 | Architektur | Windows 10

Link zu diesem Kommentar
vor 10 Stunden schrieb hölzli:

Inhalt des Nodes:


#gim2020-11-19
#Modified April 2017

#Script zur Auswahl der Tabelle und der Werte
tabname = 'Spot Standard' #Name der Tabelle
tab = vs.GetObject(tabname) #Handle zur Tabelle
(numRows, numColumns) = vs.GetWSRowColumnCount(tab) #Zählt die Anzahl Zeilen und Spalten
	
def frange(x, y, jump): #x entspricht der Startzeile in der Tabelle, y der letzten Zeile, jump ist die Schrittgrösse
	while x - y <= .000001:
		yield x
		x += jump

list = []
list = [n for n in frange(2, numRows, 1)] #erstellt eine Liste, welche Zeilen aus der Tabelle ausgewählt werden sollen
	
Artikelbeschriebe = []
Artikelnummern = []
for i in range(len(list)):
	Artikelbeschriebe.append(vs.GetWSCellFormulaN(tab, list[i], 1)) #Die Beschriebe sind in der ersten Spalte
	Artikelnummern.append(vs.GetWSCellFormulaN(tab, list[i], 2)) #Die Nummern sind in der zweiten Spalte


@Marionette.NodeDefinition
class Params(metaclass = Marionette.OrderedClass):
#APPEARANCE
	#Name
	this = Marionette.Node( 'Popup' )	
	this.SetDescription('This node demonstrates the use of a Popup OIP control. The values returned by this node will be integers based on your selection starting with 0 for the first option and increasing by 1 for consecutive options.')
	
	#Input Ports
		
	#OIP Controls
	input = Marionette.OIPControl( 'Popup', Marionette.WidgetType.Popup, 0, Artikelbeschriebe)
	input.SetDescription('an OIP control representing the options designated within the script editor')
	
	#Output Ports
	outputs = Marionette.PortOut('sArtikel')
	outputs.SetDescription('Artikelbeschrieb')
	outputn = Marionette.PortOut('nArtikel')
	outputn.SetDescription('Artikelnummer')
	
#BEHAVIOR

def RunNode(self):
	#inputs
	pass
	
	input = self.Params.input.value #Integer der Auswahl
	Artb = self.Params.Artikelbeschriebe.value
	Artn = self.Params.Artikelnummern.value
	
	#script
	outputs = Artb[input]
	outputn = Artn[input]
	
	#outputs
	self.Params.outputs.value = outputs
	self.Params.outputn.value = outputn

 

 

Ich kann da nichts Konkretes besteuern, aber ich sehe, dass bei SetDescription 'Artikelbeschrieb' genutzt wird, aber beim Variablen auslesen Artb = self.Params.Artikelbeschriebe . Da scheint mir eine Diskrepanz um ein "e" zu sein.

  • Like 1

Software-Entwickler

extragroup GmbH

https://www.extragroup.de

Link zu diesem Kommentar
vor 21 Minuten schrieb Nicolas Goutte:

Ich kann da nichts Konkretes besteuern, aber ich sehe, dass bei SetDescription 'Artikelbeschrieb' genutzt wird, aber beim Variablen auslesen Artb = self.Params.Artikelbeschriebe . Da scheint mir eine Diskrepanz um ein "e" zu sein.

 

Nach meinem Verständnis ist ja SetDescription lediglich für die Beschreibung relevant, also ist der "Wert" dort der anzuzeigende Text, beim Klicken auf "Beschreibung.

image.png.66eedbece06bceef78bfc0cea0fd83f2.png

  • Like 1

Vectorworks 2022 interiorcad |  Windows11

Link zu diesem Kommentar

Genau, der Wert bei SetDescription kann irgend ein String sein, der unter Beschreibung angezeigt wird. Hat ansonsten keine Relaevanz auf das Script. Eigentlich könnte die Zeile sogar weggelassen werden, wenn dir keine intelligente Beschriebung einfällt. (Damit habe ich oftmals mehr Probleme als mit dem Script selbst. ?)

  • Like 1

Freundliche Grüsse

 

Manuel Roth

_________________________________________________
Vectorworks 2022 SP3 | Architektur | Windows 10

Link zu diesem Kommentar
vor 21 Stunden schrieb Manuel Roth:

Wow, habe gar nicht gewusst, dass vor @Marioette.NodeDefiniton noch Code eingefügt werden kann. Habe noch nie einen solchen Node gesehen und weiss ehrlich gesagt auch nicht, was das mit der Funktion des Nodes macht und ob es überhaupt legal ist.

 

Haha, "...dann kam einer, der wusste das nicht und hat es gemacht" ? Dein Script funktioniert soweit ja wunderbar.  Das Weglassen vom .value war mein Fehler, weshalb ich durch" try and error" auf den Versuch mit dem Einfügen VOR @Marionette.NodeDefinition kam und dachte, eine Lösung gefunden zu haben.

 

vor 21 Stunden schrieb Manuel Roth:

Dein Node wird sich allerdings nicht ohne einen Kick von selbst aktualisieren. Du müsstest einen Weg finden, eine Änderung der Tabelle abzufangen und den Node erst dann zu aktualisieren.

 

Es scheint, dass der Code in Class Params nur beim Einfügen eines Nodes oder der Bearbeitung aktualisiert wird.

  • Like 1

Vectorworks 2022 interiorcad |  Windows11

Link zu diesem Kommentar

Werden die Daten, welche ausgewertet werden innerhalb der Klasse möglicherweise im "pycache" zwischengespeichert?

C:\Users\USERNAME\AppData\Roaming\Nemetschek\Vectorworks\2020\Plug-Ins\Marionette\__pycache__

Falls ja, weiss jemand, ob es möglich ist, die entsprechende Instanz dieses Nodes mit dem Ausgeführten Skript zu unterdrücken oder zu löschen, damit wieder neu berechnet werden muss?

 

Im Prinzip ja absolut ineffizient was die Geschwindigkeit angeht, aber für gewisse Situationen könnte dies ja durchaus hilfreich sein ? 

Auf jeden Fall werden die Daten ja berechnet und müssen dann auch gespeichert werden. Wenn man den Ort kennt, gibt es vielleicht ja auch eine Möglichkeit, dies zu ändern?

 

Interessanterweise wird eine Änderung in der Tabelle zwar im Popup nicht angezeigt, ein neuer Wert wird jedoch im Output ausgegeben. Das Skript wird also sehr wohl ausgeführt, jedoch ohne Einfluss auf die Liste, welche für das Dropdown verwendet wird.

Bearbeitet von hölzli
  • Like 1

Vectorworks 2022 interiorcad |  Windows11

Link zu diesem Kommentar
  • 11 Monate später...

Salut zusammen

 

@HolzzukunftIch hab zu diesem Thema leider keine Lösung gefunden und hab dieses Thema folglich auch nicht mehr weiter verfolgt. Ich wäre aber ebenfalls sehr interessiert daran, falls dies doch klappen sollte.

 

@kingchaos Ja eigentlich würde dies funktionieren, falls mein eigentlicher Wunsch überhaupt laufen würde: Nämlich dass der Inhalt des Nodes bei jeder Ausführung neu ausgewertet wird. Ich hab dies aber leider nicht hinbekommen, daüfür reichen meine Programmierkenntnisse um Welten zu wenig weit :-)

Vectorworks 2022 interiorcad |  Windows11

Link zu diesem Kommentar

Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden
  • Forenstatistik

    • Themen insgesamt
      23,5Tsd
    • Beiträge insgesamt
      120,8Tsd
×
×
  • Neu erstellen...