there are a bunch of events you can subscribe to with a modal dialog. Note that a modal dialog blocks Rhino, so you can only get something back in your calling function if the dialog has been closed. I’ve added 2 buttons to receive a return value…
Hi @clement ,
Thanks for providing this nice example, much appreciated. It makes sense, there are way more events related to closing dialogs that I may need.
I realized when using these events on a modeless form, it doesn’t have the same behaviour, maybe because, as you mentioned, your file its a modal dialog.
I’ve tryed to print the “Event: Closed” as your example but it doesnt output anything, even if the closed event is created, it seems it wont return any value. Do your know if there is any different configuration for modeless forms?
Here’s my atempt to print the closed event:
import System
import Rhino.UI
import Eto.Drawing as drawing
import Eto.Forms as forms
import Eto
import scriptcontext as sc
class OptionsPanel(forms.Form):
def __init__(self):
self.m_slider = forms.Slider()
self.m_slider.TickFrequency = 10
self.m_slider.MinValue = 1
self.m_slider.MaxValue = 100
self.m_slider.Value = x
self.m_slider.ValueChanged += self.OnSliderValueChanged
self.m_numeric_updown = forms.NumericUpDown()
self.m_numeric_updown.DecimalPlaces = 0
self.m_numeric_updown.Increment = 1
self.m_numeric_updown.MaxValue = 100.0
self.m_numeric_updown.MinValue = 1.0
self.m_numeric_updown.Value = x
self.m_numeric_updown.ValueChanged += self.OnNumericChanged
self.o_slider = forms.Slider()
self.o_slider.TickFrequency = 10
self.o_slider.MinValue = 1
self.o_slider.MaxValue = 60
self.o_slider.Value = y
self.o_slider.ValueChanged += self.OnSliderValueChanged
self.o_numeric_updown = forms.NumericUpDown()
self.o_numeric_updown.DecimalPlaces = 0
self.o_numeric_updown.Increment = 1
self.o_numeric_updown.MaxValue = 60
self.o_numeric_updown.MinValue = 1.0
self.o_numeric_updown.Value = y
self.o_numeric_updown.ValueChanged += self.OnNumericChanged
self.o_numeric_updown.ValueBinding.Bind(self.o_slider, "Value", Eto.Forms.DualBindingMode.TwoWay)
self.m_numeric_updown.ValueBinding.Bind(self.m_slider, "Value", Eto.Forms.DualBindingMode.TwoWay)
self.DefaultButton = forms.Button(Text="OK")
self.DefaultButton.Click += self.OnOkButtonClick
self.AbortButton = forms.Button(Text="Cancel")
self.AbortButton.Click += self.OnCancelButtonClick
self.Initialize()
self.CreateFormControls()
def Initialize(self):
self.Padding = drawing.Padding(10)
self.Resizable = False
self.Topmost = True
self.Closed += self.OnFormClosed
def CreateFormControls(self):
layout = forms.DynamicLayout()
layout.Spacing = drawing.Size(5, 5)
layout.AddRow(None)
layout.AddRow(self.m_slider, self.m_numeric_updown)
layout.AddRow(None)
layout.AddRow(self.o_slider, self.o_numeric_updown)
layout.AddRow(None)
layout.AddRow(self.DefaultButton, self.AbortButton)
self.Content = layout
def OnSliderValueChanged(self, sender, e):
ghenv.Component.ExpireSolution(True)
def OnNumericChanged(self, sender, e):
ghenv.Component.ExpireSolution(True)
def GetNumber1(self):
return self.m_numeric_updown.Value
def GetNumber2(self):
return self.o_slider.Value
def OnOkButtonClick(self, sender, e):
self.Close()
def OnCancelButtonClick(self, sender, e):
self.Close()
def OnFormClosed(self, sender, e):
print "Event: Closed"
if sc.sticky.has_key('form'):
form = sc.sticky['form']
if form:
form.Dispose()
form = None
sc.sticky.Remove('form')
def Dostuff():
if sc.sticky.has_key('form'):
return
form = OptionsPanel();
form.Show()
sc.sticky['form'] = form
if z == True:
Dostuff()
if sc.sticky.has_key('form'):
form = sc.sticky['form']
value1 = form.GetNumber1()
value2 = form.GetNumber2()
else:
value1 = x
value2 = y
a = value1
b = value2
modeless forms return immediately once shown and have no return value. So once you run this:
form = OptionsPanel();
form.Show()
....other code here
the code below will continue to run. I am not able to run your example using _EditPythonScript due to some missing variables (x,y,z). If i remove the lines where these variables are used, the form opens. Once i click OK, i see the “Event: Closed” gets printed. Btw. one tip to prevent crashes: put your delegate function codes into try: ... except: blocks. I got one crash though while running your code a second time, i guess it is because you’re trying to Dispose() the modeless form.
Hi Clement,
Thank you for the tips, maybe there is a diference when runing the script from GhPython compared to run it from _EditPythonScript command. I managed to print the “Event: Closed” on _EditPythinScript as you mentioned, but it doesnt print on GhPython. I mean, it does print the Close Event = False, but after closing, it doesn’t print the Close Event=True.
I’m now trying a different approach by returning the Event value to later put it on a variable, however, it doesnt accept Value as a valid argument, please see bellow
Hi @dale ,
Thank you for sharing this example code as well as all the other eto samples which are quite useful.
However it doesnt seem to work with modeless forms
import Eto.Forms as forms
class OptionsPanel(forms.Form[bool]):
I get a runtime error
Do you have any other recommended approach on how to know if modeless form is open or closed?
Hi @dale ,
Thanks for the follow-up!
I believe the issue I’m facing is caused by using it on GhPython.
We can see it’s printing well on Rhino _EditPythonScrip
By other hand, it doesn’t output anything whithin GHpython
I’m using these forms to run GH definitions, this is the main reason why it’s important to get the closed value in order to continue other steps ahead on each definition.
Either by printing it or defining boolean variable a, I don’t mind to explore any possibility available but I just got stuck in this last step and not sure what else to try.
May you please recommend another aproach?