Passing New Parameters to an Existing Popup Window - Vision

I am having issues updating the parameters on an already existing popup when more than one instance of that popup is open.

My client wants me to add functionality that would allow them to right click any value in their Ignition system and either add it to an existing trend or create a new trend. I am able to get the right click function to parse through the popups that are open to create the menu, it is opening a new trend and passing the tag data fine, but when I go to add the tag data to a new trend, it always puts the information on my first opened trend.

This is a skeleton of my script that I have been working off of:

from functools import partial
openWindows = system.gui.findWindow("System/Generic Trend")
counter = 0
subMenuA = []
subMenuB = []
def addToTrend(event, number, window):
	system.nav.openWindow(window, {"popupNumber":number})
def openTrend(event, number):
	system.nav.openWindowInstance("System/Generic Trend", {"popupNumber":number})
for i in openWindows:
	path = i.path
	if "Generic Trend" in path:
		counter = counter + 1 
		subMenuA = subMenuA + ["Trend " + str(counter)]
		subMenuB = subMenuB + [partial(addToTrend, number=counter, window=path)]
finalCounter = counter + 1
subMenuA = subMenuA + ["New Trend"]
subMenuB = subMenuB + [partial(openTrend, number=finalCounter)]
subMenu = [subMenuA, subMenuB]
menu = system.gui.createPopupMenu(["Create Trend"], [subMenu])
menu.show(event)

I can't find any way to call a specific instance of the popup in the system.nav.openWindow() function.

Do you mean you are trying to create a new trend popup? Or are you trying to add the tag data to a specific popup that already exists?

A couple of points after looking through your code:

  • I'm not seeing anywhere in your code where you are handing off information to tell a trend to add a tag value. How are you passing the information to the popup?

  • In general I think your addToTrend function is incorrect. You shouldn't be calling openWindow to get an already open window. Either loop through the results of system.gui.findWindow or system.gui.getOpenedWindows and check for some identifer or pass a reference to the window object itself when you create the option in the popup menu.

  • You are putting a lot of assumption that your popups are never being closed after being opened. If you are trying to select a window by using the popup number as an Id, then you will run into the case of the counter number being offset from the actual window number values. You will definitely select the wrong window. Build a list of the actual popup Ids so you can check it to prevent Id collision.

Something along the lines of this should get you started:

Updated Code
from functools import partial
subMenuA, subMenuB, windowIds = [], [], []

# Get a list of all opened trend windows
openWindows = system.gui.findWindow("System/Generic Trend")

# Grab the tag path or some other id of the data we want to trend
selectedDataItem = event.some.path.to.tag.path

def addToTrend(event, selectedDataItem, window):
	""" Add selected data item to existing trend window """
	# Grab the existing list of trend items from the window root container:
	trendDataItems = window.rootContainer.trendItems

	# Add the selected data item's path/id to the dataset
	newTrendItems = system.dataset.addRow(trendDataItems, row=[selectedDataItem])

	# Put the new dataset back into the params for the window
	window.rootContainer.trendItems = newTrendItems

def openTrend(event, number, selectedDataItem):
	""" Open selected data item in a new trend window """
	# Create a new dataset with the selected data item path
	newTrendItems = system.dataset.toDataset(['tagPath'], [[selectedDataItem]])

	# Open a new instance of the trend window
	system.nav.openWindowInstance("System/Generic Trend", {"popupNumber": number, "trendDataItems": newTrendItems})

for window in openWindows:
	if "Generic Trend" in window.path:
		# Grab the popup window number from the window's parameters
		popupWindowNumber = window.rootContainer.popupNumber

		# Add window id number to list so we can avoid collisions
		windowIds.append(popupWindowNumber)

		#Create sub menus
		subMenuA = subMenuA + ["Trend " + str(popupWindowNumber)]
		subMenuB = subMenuB + [partial(addToTrend, number=popupWindowNumber, window=window, selectedDataItem=selectedDataItem)]

if len(windowIds) > 0:
	# Lazy collision avoidance, take largest number in the list and add 1
	newTrendWindowId = max(windowIds) + 1
else:
	newTrendWindowId = 1

# Add option to create new trend popup
subMenuA = subMenuA + ["New Trend"]
subMenuB = subMenuB + [partial(openTrend, number=newTrendWindowId, selectedDataItem=selectedDataItem)]

# Pack menu and display popup menu
subMenu = [subMenuA, subMenuB]
menu = system.gui.createPopupMenu(["Create Trend"], [subMenu])
menu.show(event)

Thank you, this gets me where I need to be. I was struggling with the interaction of the window object. My original plan was to write the tag path to a parameter on the popup and have a property change script that added it to the dataset.

This is a much more elegant solution and thanks again.