How to get a window names and string values of presended components on that window in client?

Hi everyone..,
I need some clarifications on vision client. i have faced some errors when i try to get a components values form windows in client. Our need is collect the all String value of component values in all window.I already explained that in previous part.That is Fetching a Components data from window and transfer that value to Translation Manager. Please visit that window what i'm saying and doing it for. I devleopt a script for get a values for a component on window. And we tested that script is run or not.But that script has run succesfully.That script is,

from com.inductiveautomation.factorypmi.application.components import BasicContainer
from java.lang import String

def printTextAndDataStrings(container):

	ins_list = []

	for component in container.getComponents():
	
		if isinstance(component, BasicContainer):
			printTextAndDataStrings(component)
			
		if hasattr(component, 'text'):
			val = component.text
			ins_list.append(str(val))
			
		if hasattr(component, 'Text'):
			val = component.Text
			ins_list.append(str(val))
			
		if hasattr(component, 'data'):
			dataset = component.data
			
			if dataset.rowCount > 0 and dataset.columnCount >0:
				
				for column in range(dataset.columnCount):
					value = dataset.getValueAt(0, column)
					
					if isinstance(value,(String, unicode)):
						val = dataset.getColumnAsList(column)
				
				for x in val:
#					print x
					ins_list.append(str(x))
			
		if hasattr(component, 'Data'):
			dataset = component.data
			
			if dataset.rowCount > 0 and dataset.columnCount >0:
				
				for column in range(dataset.columnCount):
					value = dataset.getValueAt(0, column)
					
					if isinstance(value,(String, unicode)):
						val = dataset.getColumnAsList(column)
				
				for x in val:
#					print x
					ins_list.append(str(x))
			
	query = "SELECT Keyes FROM translation"
	val = system.db.runQuery(query,"MySQL")
	val1 = val.getColumnAsList(0)
	
	list = []
	for x in ins_list:
	
		if x in val1:
			pass
			
		else:
			list.append(str(x))
#	print list
			
	y = "('" + "'),('".join(list)+ "')"
	print y
	
	if y != "('')":
		query = "insert into translation (Keyes) values {}".format(y)
		run = system.db.runPrepUpdate(query,[],"MySQL")
		print run

windows = system.gui.getWindowNames()
e_list = []

for path in windows:
    e_list.append(path)

for x in e_list:

	rootContainer = system.gui.getWindow(str(x)).rootContainer
	printTextAndDataStrings(rootContainer)
	

i put that script in Button and when i clic that button that time it run. First it fetched all window name of vision window. then it use that to fetching the data. But, here get the string values when the window has opened. Once that window has closed it through the error. So, i opened all window on vision designer and tested the script, its working good. But, i launched the window and test that in cliend, it through error, Like "window_1" in not opened.

Thanks,

So, the function system.gui.getWindowNames() just gets the names--it doesn't open them for you, and they need to be open for the rest of your code to work. Consider using system.nav.openWindow() instead of system.gui.getWindow() in your outermost loop. Also consider closing the windows after you are done with them, to minimize memory usage within the loop.

2 Likes

I've done quite a bit of this type of work, so I'll warn you that if you have many windows in a project, you will need to develop a way to do this in batches. I typically use the button I am running the script from, and I add a custom parameter to keep track of what index I'm at. If the custom property is called startingNumber, and I want to edit in batches of 5, the top of the script will look like this:

start = event.source.startingNumber
end = (start + 4)

Theoretically, for closing the windows, you should be able to do something like this:

for name in system.gui.getOpenedWindowNames():
	if  name != 'nameOfWindowWithButton':#I don't imagine that we would want to close our utility window
		system.nav.closeWindow(name)

...but this doesn't work in the designer, so I end up adding a dataset custom property that keeps track of which windows I am opening, so I can close them at the beginning of the next script run.

If the dataset custom property was called openWindows, then the next part of my script would look like this:

openWindows = event.source.openedWindows
for row in range(openWindows.rowCount):
	name = openWindows.getValueAt(row, 0)
	system.nav.closeWindow(name)

Then, to batch which windows get opened relative to the starting point, it's simply:

headers = ['name']
data = [] #This is for keeping track of which windows I have opened in the designer
for index, name in enumerate(system.gui.getWindowNames()[start:end]):
	window = system.nav.openWindow(name)
	data.append([name])
	#Call any "WORK" functions, or do work here

Finally, I update my custom properties:

event.source.openedWindows = system.dataset.toDataSet(headers, data)
event.source.startingNumber = (end)

I've developed this approach in any number of ways, from a fully automated cycle that opens and closes windows one at a time for a specified number of cycles to only keeping the windows open if certain attributes are found up to a maximum number of opened windows, regardless of the usage case, what I've posted above is pretty much the gist of how I go about it.

this might be interesting

Here are a couple of examples of cycling through windows from the forum that could also help you:
A basic example of cycling through windows one at a time
A much more complex example of cycling through all windows one at a time, and later in the thread: cycling in batches

Han., I do that, It works well. When we try this way to fetch the component, that time we face a big error. That is, If we use that script in Our local host, it will work smoothly. Because localhost has few windows and low data. But, Our Production server and testing servers have more than 100 windows and They contain Pulk amount of data. That is our big problem Because if we run the script on the Production or testing server in the designer it'll work and no issues happen. But we run that script in the client that time the total Client has hanged. That's why I omit that Open and close the window in the client. so, I need to get the all components in indirectly..,

Thanks,