Jump to content

Python Dialog Box


Recommended Posts

Hi all, new to Vectorworks, but I've been using Python for a couple years and have used it a lot in TouchDesigner. I want to create a custom dialog box to collect user input parameters and then create a new symbol, but I'm lost where to even begin. I keep trying to run various dialog functions and then I get an error saying that they don't exist. example:

import vs
vs.BeginDialog(0, 1, 10, 10, 0, 0)
vs.EndDialog()

 

I get an error saying that vs has no attribute BeginDialog. Then I tried  vs.DrawDialog(), thinking that would be a better place to start, and I get the same error. All of the class functions work fine, as well as the predefined dialogs, what am I doing wrong here?

 

 

Also, in general, are there any more extensive resources for the Python API? The VS Function Reference wiki page is kind of awful.

Link to comment

Hi @sully8391 ,

   The "vs.BeginDialog()" and "vs.EndDialog()" commands are part of the Classic Dialog set which were discontinued in VW 2010. They continued to run for several years after that, but the shift was toward the Modern Dialog commands introduced in VW 9. They are the currently supported dialog calls.

 

   Consult the Developer Wiki at http://developer.vectorworks.net/index.php/VS:Function_Reference or the HTML Script Reference that ships with the application in the VWHelp folder @ "VWHelp/Script Reference/ScriptFunctionReference.html". Start with "CreateLayout()" and peruse that section. There are several examples in that section. If you're looking at the HTML Reference,, search for "Example" when you're in the "Modern Dialog" area.

 

   Simple dialogs are pretty easy to layout by hand. More complicated dialogs might require the use of the Dialog Builder. Good luck and write back.

 

Raymond

 

PS - Please create a signature with a basic description of your computer and VW version. It will help us answer your questions a little faster and possibly allow us to offer advice that is pertinent to your setup.

  • Like 1
Link to comment

I see the note there now that they've been deprecated. I still find the VS Function Reference lacking. I've been at it hours, and I can't even get a simple dialog box with a button. The examples don't make much sense to me. I'm seeing functions defined inside other function definitions, and functions that seem to do nothing but define global variables. The comments are also sparse, so I'm just having a lot of trouble figuring out how these elements are supposed to work together. 

Link to comment

You picked the wrong spot to start with PythonScript and Vectorworks. There is nothing simple about a custom dialog box.

 

If you only need a single or couple of inputs, try and do it with the Predefined dialog box (es) so you can get the rest of the code to work. Then you can go back and consider making a custom dialog.

 

For most of my (few) applications that use a custom dialog box, the code to draw and handle the dialogs is far more than the rest of the code.

  • Like 1
Link to comment

@sully8391 ,

Although Pat's advice is pretty much spot on, let me lessen the gravity of it a little. If you're tenacious, patient, and inquisitive, you can probably have your dialog up and running within a day or two. Once you get the first one done all the hurdles come down a bit. And as with all other disciplines: practice makes perfect, and failure is mandatory.

 

Modern Dialogs are constructed in three parts. The first part can be a procedure, or inline code, that contains all of the statements that define the dialog, while the second part is a procedure containing code to run the dialog (the event loop). The last part is typically one or two lines in the main program that call the dialog code.


Here is a short example in Pascal (sorry, I think faster this way.) Translating it shouldn't be too hard. The CASE statement in the Event Loop can be replaced with an "if / elif" tree.

PROCEDURE DialogExample;
{ This is a relatively simple example of a Modern Dialog that converts temperatures. }
{ It has 6 fields, 3 static text labels, and 3 Edit Text fields. }
{ It also as a basic event loop to control the dialog when it is running. }
{ Every key press and every click generates an event which is handled by the event loop. }
{ Events can be handled or ignored as you see fit. }
{ 03 Jan 2020 - Raymond J Mullin - Use or modify to your wildest whims. }

VAR
	dlogID, dlogResult :Longint;

	function BuildDialog :Longint;
	{ This dialog returns the Dialog ID and has 2 parts. }
	{ 1) Code that creates the dialog elements. }
	{ 2) Code that arranges the elements in the dialog, either below or to the right of the previous element. }
	{ This function could also contain two more parts... }
	{ 3) Code that controls the alignment of the elements to each other. This is optional. }
	{ 4) Code that defines Help Strings when the cursor hovers over dialog elements. This is also optional. }
	Var
		dlogID :Longint;
	Begin
		{ This is the most common way to start. }
		dlogID := CreateLayout('Temperature', False, 'OK', '');	{ No HELP text, OK button and no Cancel button }

		{ create 1st element at 4 or higher, it's arbitrary. I usually start at 10 for static text and 20 for the edit fields }
		CreateStaticText(dlogID, 10, 'Fahrenheit (°F)', 13);	{ Name says it all - it's static (usually) }
		CreateStaticText(dlogID, 11, 'Celsius (°C)', 13);	{ the last number is its width in characters (approximately))... }
		CreateStaticText(dlogID, 12, 'Kelvin (°K)', 13);	{   ...average characters, not the skinny ones }
		CreateEditReal(dlogID, 20, 1, 32, 16);			{ a field you can type in }
		CreateEditReal(dlogID, 21, 1, 0, 16);			{ another field you can type in }
		CreateEditReal(dlogID, 22, 1, 273.15, 16);		{ a third field you can type in, or write to }

		{ The next section arranges the dialog elements either right or down }
		SetFirstLayoutItem(dlogID, 10);				{ everything else is anchored to this item }
		SetBelowItem(dlogID, 10, 11, 0, 0);			{ item 11 goes below item 10 }
		SetBelowItem(dlogID, 11, 12, 0, 0);			{ item 12 goes below item 11 }
		SetRightItem(dlogID, 10, 20, 0, 0);			{ item 20 goes to right of item 10 }
		SetRightItem(dlogID, 11, 21, 0, 0);			{ item 21 goes to right of item 11 }
		SetRightItem(dlogID, 12, 22, 0, 0);			{ item 22 goes to right of item 12 }

		BuildDialog := dlogID;					{ this is your "return" value in Python }
	End;		{ BuildDialog }
	
	
	procedure DialogEventLoop(var item :Longint; data :Longint);	{ this procedure is always defined this way }
	{ This is the Event Loop. For every event (keystroke or click) this procedure is executed }
	Var
		Fahr, Cel, Kel :Real;
	Begin
		{ use this next line for debug to see what events are called and when. Comment it out when done. }
		{	AlrtDialog(concat('item= ', item, '   data= ', data));	}
		
		{ if you want something to happen when an event occurs, put the item # (aka, the event #) in the case statement }
		case item of
			SetupDialogC : begin
				{ initialize all dialog values here }
				{ this event only gets called once at the beginning of dialog execution }
			end;		{ SetupDialogC }
			
			1: begin		{ OK button was pressed }
				SysBeep;	{ BEEP for joy - it worked }
			end;		{ 1 }
				
			2: begin		{ code for CANCEL button was pressed, if you had one (but you don''t) }
			end;		{ 2 }
			
			20: begin
				if GetEditReal(dlogID, 20, 1, Fahr) then begin
					Cel := (Fahr-32) * 5/9;
					SetEditReal(dlogID, 21, 1, Cel);
					SetEditReal(dlogID, 22, 1, Cel+273.15);
				end;		{ if }
			end;		{ 20 }
			
			21: begin
				if GetEditReal(dlogID, 21, 1, Cel) then begin
					Fahr := Cel * 9/5 + 32;
					SetEditReal(dlogID, 20, 1, Fahr);
					SetEditReal(dlogID, 22, 1, Cel+273.15);
				end;		{ if }
			end;		{ 21 }
				
			22: begin
				if GetEditReal(dlogID, 22, 1, Kel) then begin
					Cel := Kel - 273.15;
					SetEditReal(dlogID, 21, 1, Cel);
					SetEditReal(dlogID, 20, 1, Cel*9/5+32);
				end;		{ if }
			end;		{ 22 }
		end;		{ case }
		
		{ the dialog exits when (item == 1) or (item == 2) at the end of this procedure. }
		{ this procedure will "return item" in Python }
	End;		{ DialogEventLoop }

BEGIN		{ main program }
	{ This line builds the dialog and returns its ID. }
	dlogID := BuildDialog;
	
	{ VerifyLayout() checks the dialog, if it passes then it runs the dialog }
	{ in the next statement with the Event Loop specified. }
	if VerifyLayout(dlogID) then
		dlogResult := RunLayoutDialog(dlogID, DialogEventLoop);
		
	{ Check the "dlogResult", 1 = OK; 2 = Cancel. Proceed accordingly. }
END;		{ main program }
Run(DialogExample);

 

Keep the Function Reference close. Even with all its shortcomings it is still an invaluable aid. The next best reference source is this forum. Write back when you have more questions and @Pat Stanford will most likely beat me to a response. 😉

 

Raymond

 

 

Edited by MullinRJ
  • Like 1
Link to comment
  • 4 weeks later...

Hello

 

I created for my pyhton script two types of custom dialogs a simple one and a version I can define the custom dialog by an string (multiple strings passed to the same Dialog-ID). I put both dialogs in a function placed in a lib, so I have them "handy" for all scripts:

 

simple dialog:

 

def dialog_input_simple(vDialog_Titel = '', vDialog_Text = '', vDialog_Text_help = '', vDialog_Text_input = ''):

	cCancelButton = 2
	cOKButton = 1
	cSetupDialog = 12255


	def setup(vDialog_Titel, vDialog_Text, vDialog_Text_help, vDialog_Text_input):
	
		vDialog_ID = vs.CreateLayout(vDialog_Titel,1,'ausführen','abbrechen')
		vs.CreateStaticText(vDialog_ID,100,vDialog_Text,-1)
		vs.CreateEditText(vDialog_ID,300,vDialog_Text_input,40)

		vs.SetFirstLayoutItem(vDialog_ID, 100)
		vs.SetBelowItem (vDialog_ID,100,300,0,0)

		vs.SetHelpText(vDialog_ID, 300,vDialog_Text_help)

		return (vDialog_ID)
		
		
	def control(vDialog_Item, vDialog_Data):
	
		# do not write any code here, as it is executed on every event cycle, even after the ok-event
		nonlocal vDialog_Text_input

		if vDialog_Item == cSetupDialog:
			vDialog_Text_input = ''
		elif vDialog_Item == cCancelButton:
			pass # pass statement is a null operation
		elif vDialog_Item == cOKButton:
			vDialog_Text_input = vs.GetItemText(vDialog_ID, 300)
			# vestB.messageA(vObject_ID)
			
		return (vDialog_Item)
	
	vDialog_ID = setup(vDialog_Titel, vDialog_Text, vDialog_Text_help, vDialog_Text_input)
	vDialog_Result = vs.RunLayoutDialog(vDialog_ID, control)

	return (vDialog_Result, vDialog_Text_input)

 

variable custom dialog:

 

def dialog_input_multiple(vDialogParameters = ""):

	cCancelButton = 2
	cOKButton = 1
	cSetupDialog = 12255
	
	vDialog_Result = cCancelButton

	def setup(vDialogParameters_list):
	
		vDialog_Titel = vDialogParameters_list['title']
		vDialog_Text = vDialogParameters_list['head']
	
		vDialog_Items_search = 'item'
		vDialog_Items_List = [vKey for vKey,vValue in vDialogParameters_list.items() if (vKey.lower()).startswith(vDialog_Items_search)]
	
		vDialog_ID = vs.CreateLayout(vDialog_Titel,1,'ausführen','abbrechen')
		
		vDialog_Item_ID_start = 1000
		vDialog_Item_ID = vDialog_Item_ID_start
		
		vs.CreateStaticText(vDialog_ID,vDialog_Item_ID,vDialog_Text,-1)
		vs.SetFirstLayoutItem(vDialog_ID, vDialog_Item_ID)
		
		vDialog_Items_List.sort() # this sorts only on items key and not on the ID, future sorting should be on ID
		# messageA(vDialog_Items_List)
		
		vDialog_Results = list()
		
		for vDialog_Item_key in vDialog_Items_List:
			
			vDialog_Item_values = vest.base.vw.lists.keyvalueList_ToList(vest.base.vw.lists.text_ToList_embraced(vDialogParameters_list[vDialog_Item_key]))
			
			vDialog_Item_ID_previous = vDialog_Item_ID
			vDialog_Item_ID_org = vDialog_Item_values['ID']
			vDialog_Item_ID = int(vDialog_Item_ID_org)+(2*vDialog_Item_ID_start)
			vDialog_Item_name = vDialog_Item_values['name']
			vDialog_Item_label = vDialog_Item_values['label']
			vDialog_Item_input = vDialog_Item_values['input']
			vDialog_Item_help = vDialog_Item_values['help']
			
			# messageA("vDialog_Item_ID_previous | vDialog_Item_ID:" + str(vDialog_Item_ID_previous) + " | " + str(vDialog_Item_ID))
			vs.CreateEditText(vDialog_ID,vDialog_Item_ID,vDialog_Item_input,40)
			vs.SetBelowItem (vDialog_ID,vDialog_Item_ID_previous,vDialog_Item_ID,0,0)
			vs.SetHelpText(vDialog_ID, vDialog_Item_ID,vDialog_Item_help)
			
			vDialog_Results.append({'dialogID': vDialog_Item_ID, 'ID': vDialog_Item_ID_org, 'name': vDialog_Item_name, 'input': vDialog_Item_input})

		return (vDialog_ID, vDialog_Results)
		
		
	def control(vDialog_Item, vDialog_Data):
	
		# do not write any code here, as it is executed on every event cycle, even after the ok-event
		nonlocal vDialog_Results

		if vDialog_Item == cSetupDialog:
			pass # pass statement is a null operation
		elif vDialog_Item == cCancelButton:
			pass # pass statement is a null operation
		elif vDialog_Item == cOKButton:
			for vDialog_Results_item in vDialog_Results:
				vDialog_Item_ID = vDialog_Results_item['dialogID']
				vDialog_Results_item['input'] = vs.GetItemText(vDialog_ID, vDialog_Item_ID)
			
		return (vDialog_Item)
	
	
	vDialogParameters_list = vest.base.vw.lists.keyvalue_ToList(vDialogParameters, ';', '+=')

	if len(vDialogParameters_list)>0:
		
		vDialog_ID, vDialog_Results = setup(vDialogParameters_list)
		vDialog_Result = vs.RunLayoutDialog(vDialog_ID, control)

	return (vDialog_Result, vDialog_Results)

# END		:	vest.base.vw.base.dialog_input_multiple

 

the variable dialog can by called by these parameters:

 

# dialog_input_multiple(vDialogParameters = "") # "title+=Titel;head+=Head;item1+=[ID=100] [name=field 100] [label=label 100] [input=input 100] [help=help 100] [type=text];"

 

or as example:

 

	vDialog_Parameters = ''
	vDialog_Parameters += 'title+=Table Export;'
	vDialog_Parameters += 'head+=Entry of DB-name and list of all DB-field-name;'
	vDialog_Parameters += 'item1+=[ID=100] [name=db_name] [label=DB name] [input='+ vDB_Name +'] [help=please enter the DB-name] [type=text];'
	vDialog_Parameters += 'item2+=[ID=110] [name=db_field_list] [label=Feld Namen] [input='+ vDB_Field_Name_TextList +'] [help=please enter all DB-field names as a list : field1, field2 ... oder !ALL! for all DB fields] [type=text];'

	vDialog_Result, vDialog_Results = vestB.dialog_input_multiple(vDialog_Parameters)

 

and here the functions called inside of the dialog_input_multiple(vDialogParameters) function to decode the input string vDialogParameters:

 

def keyvalue_ToList(vValues_text, vValues_Entity_Split = ';', vValues_Pair_Split = '='): # 'key1=value1;key2=value2;key3=value3'

		vEntity_List = text_ToList(vValues_text, vValues_Entity_Split)
		vValues_list = list()
		vValues_list = dict(vEntity.split(vValues_Pair_Split) for vEntity in vEntity_List) 
	
		return (vValues_list)



def text_ToList(vValues_text, vValues_Entity_Split = ',' ):
	import re

	vValues_list = list()
	vValues_list = re.split(r"" + vValues_Entity_Split + "\s*", vValues_text)
	vValues_list = list(filter(None,vValues_list)) # removes void/empty items
	
	return (vValues_list)
    
    
    
def text_ToList_embraced(vValues_text, vValues_Entity_SplitStart = '', vValues_Entity_SplitEnd = ''):
	import re

	vValues_list = list()
	if vValues_Entity_SplitStart != '' and vValues_Entity_SplitEnd != '':
		vPattern = re.escape(vValues_Entity_SplitStart) +  "[^" + re.escape(vValues_Entity_SplitEnd) + "]*" + re.escape(vValues_Entity_SplitEnd) + "|\S+"
		vValues_list = re.findall(vPattern, vValues_text)
		vPatternReplace = "\A" + re.escape(vValues_Entity_SplitStart) + "|" + re.escape(vValues_Entity_SplitEnd )+ "\Z"
		vValues_list = [re.sub(vPatternReplace, '', item) for item in vValues_list] # to strip leading and trailing embracing strings
	else:
		vValues_list = re.findall('\[[^\]]*\]|\([^\)]*\)|\"[^\"]*\"|\S+',vValues_text)
		vValues_list = [re.sub('\A\[|\]\Z|\A\(|\)\Z|\A\"|\"\Z', '', item) for item in vValues_list]
		
	vValues_list = list(filter(None,vValues_list)) # removes void/empty items

	
	return (vValues_list)

 

best regards,

 

relume

 

 

 

Edited by relume
added secondary functions
  • Like 2
Link to comment
  • 1 year later...
On 2/2/2020 at 10:27 PM, Pat Stanford said:

You picked the wrong spot to start with PythonScript and Vectorworks. There is nothing simple about a custom dialog box.

 

If you only need a single or couple of inputs, try and do it with the Predefined dialog box (es) so you can get the rest of the code to work. Then you can go back and consider making a custom dialog.

 

For most of my (few) applications that use a custom dialog box, the code to draw and handle the dialogs is far more than the rest of the code.

Hi Pat,

 

Trying to figure out the control to dismiss a dialog, any leads are appreciated.

Link to comment

@Jiajing

Assuming you are referring to a custom dialog, a dialog will close when the ITEM variable, defined in the Dialog_Event_Handler routine, is equal to 1, or 2.

 

Clicking on the CANCEL button (if you have one) will set ITEM=2. Usually when the ITEM variable equals 2, the dialog will dismiss (i.e., Cancel) with no changes, but that depends on what you write for the ITEM=2 case of your dialog event handler

 

Clicking on the OK button will set ITEM=1. With ITEM=1 the dialog will also dismiss, and it should accept all changes to the dialog, but that, too, depends on what you write in the ITEM=1 case of your dialog event handler.

 

At any time in your dialog event handler, you can force the ITEM variable to be either 1 or 2 to close the dialog. When the event loop ends, if the ITEM variable =1 or =2, the dialog handler will stop, and the dialog will close.

 

HTH,

Raymond

Link to comment
13 hours ago, MullinRJ said:

@Jiajing

Assuming you are referring to a custom dialog, a dialog will close when the ITEM variable, defined in the Dialog_Event_Handler routine, is equal to 1, or 2.

 

Clicking on the CANCEL button (if you have one) will set ITEM=2. Usually when the ITEM variable equals 2, the dialog will dismiss (i.e., Cancel) with no changes, but that depends on what you write for the ITEM=2 case of your dialog event handler

 

Clicking on the OK button will set ITEM=1. With ITEM=1 the dialog will also dismiss, and it should accept all changes to the dialog, but that, too, depends on what you write in the ITEM=1 case of your dialog event handler.

 

At any time in your dialog event handler, you can force the ITEM variable to be either 1 or 2 to close the dialog. When the event loop ends, if the ITEM variable =1 or =2, the dialog handler will stop, and the dialog will close.

 

HTH,

Raymond

Thank you, Raymond.

 

My question is how to force ITEM to be 1. Do I need special fuction to do that or it just be assigned to 1.

 

Here is a quick custom dialog:

  • Do I have ITEM =1 at right spot?  I am pretty sure it does not work as I am trying to assign a value back to a fuction variable.
import vs

# control IDs
kOK                   = 1
kCancel               = 2
kUnnamed1             = 5
kTextbox              = 7
kCpop                 = 8
kC2                   = 9

def CreateDialog():
    # Alignment constants
    kRight                = 1
    kBottom               = 2
    kLeft                 = 3
    kColumn               = 4
    kResize               = 0
    kShift                = 1

    def GetPluginString(ndx):
        # Static Text
        if ndx == 1001:			return 'OK'
        elif ndx == 1002:		return 'Cancel'
        elif ndx == 1003:		return 'Dialog'
        elif ndx == 1005:		return 'None'
        elif ndx == 1007:		return ''
        elif ndx == 1008:		return ''
        elif ndx == 1009:		return ''
        # Help Text
        elif ndx == 2001:		return 'Accepts the dialog data.'
        elif ndx == 2002:		return 'Cancels the dialog data.'
        elif ndx == 2005:		return 'Help text.'
        elif ndx == 2007:		return 'Help text.'
        elif ndx == 2008:		return 'Help text.'
        elif ndx == 2009:		return 'Help text.'
        return ''

    def GetStr(ndx):
        result = GetPluginString( ndx + 1000 )
        return result

    def GetHelpStr(ndx):
        result = GetPluginString( ndx + 2000 )
        return result

    dialog = vs.CreateLayout( GetStr(3), True, GetStr(kOK), GetStr(kCancel) )

    # create controls
    vs.CreateEditText( dialog, kTextbox, GetStr(kTextbox), 16 )
    vs.CreateColorPopup( dialog, kCpop, 16 )
    vs.CreateEditReal( dialog, kC2, 1, 0.0, 16 )
    vs.CreatePushButton( dialog, kUnnamed1, GetStr(kUnnamed1) )

    # set relations
    vs.SetFirstLayoutItem( dialog, kTextbox )
    vs.SetBelowItem( dialog, kTextbox, kCpop, 0, 0 )
    vs.SetBelowItem( dialog, kCpop, kC2, 0, 0 )
    vs.SetBelowItem( dialog, kC2, kUnnamed1, 0, 0 )

    # set alignments

    # set help strings
    cnt = 1
    while ( cnt <= 9 ):
        vs.SetHelpText( dialog, cnt, GetHelpStr(cnt) )
        cnt += 1

    return dialog

# Sample dialog handler
# Uncomment this code if you want to display the dialog

def DialogHandler(item, data):
    ### do other coding
	item = 1 ??


dlg = CreateDialog()
vs.RunLayoutDialog( dlg, DialogHandler )

  

 

 

Link to comment

@Jiajing,

   My apologies. I didn't read your code example before I answered. What I said above is still true, you can set the "item" variable to 1 at any point in your dialog handler, BUT what I didn't say and should have, you must return that value at the end of the DialogHandler proc. The second part is always needed, since the handler uses the value of "item" on exit to determine whether to stop or continue.  I modified your example slightly to demonstrate a little better. Note that now when you click on your "None" pushbutton, "item" is set to 1 and the dialog closes without any fanfare, but hey, it's just an example.

 

   Also note, there are two constants that run just before the dialog starts and just after the dialog stops – kSetUpDialogC & kSetDownDialogC. I only included the first one in the DialogHandler definition below. The second one is rarely used, but it's included if you need it. In Python you have to define them, but in VectorScript they are predefined.

 

import vs

# control IDs
kOK			= 1
kCancel			= 2
kUnnamed1		= 5
kTextbox		= 7
kCpop			= 8
kC2			= 9
kSetUpDialogC		= 12255	# predefined dialog event constant used for setup BEFORE dialog runs
kSetDownDialogC		= 12256	# predefined dialog event constant used for setup AFTER dialog runs

def CreateDialog():
	# Alignment constants
	kRight		= 1
	kBottom		= 2
	kLeft		= 3
	kColumn		= 4
	kResize		= 0
	kShift		= 1

	def GetPluginString(ndx):
		# Static Text
		if ndx == 1001:			return 'OK'
		elif ndx == 1002:		return 'Cancel'
		elif ndx == 1003:		return 'Dialog'
		elif ndx == 1005:		return 'None'
		elif ndx == 1007:		return ''
		elif ndx == 1008:		return ''
		elif ndx == 1009:		return ''
		# Help Text
		elif ndx == 2001:		return 'Accepts the dialog data.'
		elif ndx == 2002:		return 'Cancels the dialog data.'
		elif ndx == 2005:		return 'Help text.'
		elif ndx == 2007:		return 'Help text.'
		elif ndx == 2008:		return 'Help text.'
		elif ndx == 2009:		return 'Help text.'
		return ''

	def GetStr(ndx):
		result = GetPluginString( ndx + 1000 )
		return result

	def GetHelpStr(ndx):
		result = GetPluginString( ndx + 2000 )
		return result


	dialog = vs.CreateLayout( GetStr(3), True, GetStr(kOK), GetStr(kCancel) )

	# create controls
	vs.CreateEditText( dialog, kTextbox, GetStr(kTextbox), 16 )
	vs.CreateColorPopup( dialog, kCpop, 16 )
	vs.CreateEditReal( dialog, kC2, 1, 0.0, 16 )
	vs.CreatePushButton( dialog, kUnnamed1, GetStr(kUnnamed1) )

	# set relations
	vs.SetFirstLayoutItem( dialog, kTextbox )
	vs.SetBelowItem( dialog, kTextbox, kCpop, 0, 0 )
	vs.SetBelowItem( dialog, kCpop, kC2, 0, 0 )
	vs.SetBelowItem( dialog, kC2, kUnnamed1, 0, 0 )

	# set alignments

	# set help strings
	cnt = 1
	while ( cnt <= 9 ):
		vs.SetHelpText( dialog, cnt, GetHelpStr(cnt) )
		cnt += 1

	return dialog

# Sample dialog handler
# Uncomment this code if you want to display the dialog

def DialogHandler(item, data):
	if (item == kSetupDialogC):	# 12255
		pass
	elif (item == kOK):		# 1
		pass
	elif (item == kCancel):		# 2
		pass
	elif (item == kUnnamed1):	# 5
		item = 1		# change "item" from 5 to 1 after pushing button
	elif (item == kTextbox):	# 7
		pass
	elif (item == kCpop):		# 8
		pass
	elif (item == kC2):		# 9
		pass

	return item


dlg = CreateDialog()
result = vs.RunLayoutDialog( dlg, DialogHandler )	# use "result" if you want to process 
							# things after the dialog closes

 

Raymond

  • Like 1
Link to comment
12 hours ago, MullinRJ said:

@Jiajing,

   My apologies. I didn't read your code example before I answered. What I said above is still true, you can set the "item" variable to 1 at any point in your dialog handler, BUT what I didn't say and should have, you must return that value at the end of the DialogHandler proc. The second part is always needed, since the handler uses the value of "item" on exit to determine whether to stop or continue.  I modified your example slightly to demonstrate a little better. Note that now when you click on your "None" pushbutton, "item" is set to 1 and the dialog closes without any fanfare, but hey, it's just an example.

 

   Also note, there are two constants that run just before the dialog starts and just after the dialog stops – kSetUpDialogC & kSetDownDialogC. I only included the first one in the DialogHandler definition below. The second one is rarely used, but it's included if you need it. In Python you have to define them, but in VectorScript they are predefined.

 

import vs

# control IDs
kOK			= 1
kCancel			= 2
kUnnamed1		= 5
kTextbox		= 7
kCpop			= 8
kC2			= 9
kSetUpDialogC		= 12255	# predefined dialog event constant used for setup BEFORE dialog runs
kSetDownDialogC		= 12256	# predefined dialog event constant used for setup AFTER dialog runs

def CreateDialog():
	# Alignment constants
	kRight		= 1
	kBottom		= 2
	kLeft		= 3
	kColumn		= 4
	kResize		= 0
	kShift		= 1

	def GetPluginString(ndx):
		# Static Text
		if ndx == 1001:			return 'OK'
		elif ndx == 1002:		return 'Cancel'
		elif ndx == 1003:		return 'Dialog'
		elif ndx == 1005:		return 'None'
		elif ndx == 1007:		return ''
		elif ndx == 1008:		return ''
		elif ndx == 1009:		return ''
		# Help Text
		elif ndx == 2001:		return 'Accepts the dialog data.'
		elif ndx == 2002:		return 'Cancels the dialog data.'
		elif ndx == 2005:		return 'Help text.'
		elif ndx == 2007:		return 'Help text.'
		elif ndx == 2008:		return 'Help text.'
		elif ndx == 2009:		return 'Help text.'
		return ''

	def GetStr(ndx):
		result = GetPluginString( ndx + 1000 )
		return result

	def GetHelpStr(ndx):
		result = GetPluginString( ndx + 2000 )
		return result


	dialog = vs.CreateLayout( GetStr(3), True, GetStr(kOK), GetStr(kCancel) )

	# create controls
	vs.CreateEditText( dialog, kTextbox, GetStr(kTextbox), 16 )
	vs.CreateColorPopup( dialog, kCpop, 16 )
	vs.CreateEditReal( dialog, kC2, 1, 0.0, 16 )
	vs.CreatePushButton( dialog, kUnnamed1, GetStr(kUnnamed1) )

	# set relations
	vs.SetFirstLayoutItem( dialog, kTextbox )
	vs.SetBelowItem( dialog, kTextbox, kCpop, 0, 0 )
	vs.SetBelowItem( dialog, kCpop, kC2, 0, 0 )
	vs.SetBelowItem( dialog, kC2, kUnnamed1, 0, 0 )

	# set alignments

	# set help strings
	cnt = 1
	while ( cnt <= 9 ):
		vs.SetHelpText( dialog, cnt, GetHelpStr(cnt) )
		cnt += 1

	return dialog

# Sample dialog handler
# Uncomment this code if you want to display the dialog

def DialogHandler(item, data):
	if (item == kSetupDialogC):	# 12255
		pass
	elif (item == kOK):		# 1
		pass
	elif (item == kCancel):		# 2
		pass
	elif (item == kUnnamed1):	# 5
		item = 1		# change "item" from 5 to 1 after pushing button
	elif (item == kTextbox):	# 7
		pass
	elif (item == kCpop):		# 8
		pass
	elif (item == kC2):		# 9
		pass

	return item


dlg = CreateDialog()
result = vs.RunLayoutDialog( dlg, DialogHandler )	# use "result" if you want to process 
							# things after the dialog closes

 

Thank you for clarification, Raymond.   It works prefectly. 

 

Good to know about kSetUpDialogC & kSetDownDialogC. 

 

 

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...