I’m doing quite a bit of wheel spinning trying to close a modeless form with a close button instead of the user clicking the “X”. I’ve pasted in some sample code below. I’ve tried a self.Close(), which crashes Rhino and tried what is in the pasted code below with no success. Can someone tell me what I am doing wrong?
Test():
print ("Hi")
# Form Closed event handler
def OnFormClosed(self, sender, e):
print("the form has closed")
# Dispose of the form and remove it from the sticky dictionary
if sc.sticky.has_key('sample_modeless_form'):
form = sc.sticky['sample_modeless_form']
if form:
form.Dispose()
form = None
sc.sticky.Remove('sample_modeless_form')
# Close button click handler
def OnCloseButtonClick(self, sender, e):
print("the form has closed")
# Dispose of the form and remove it from the sticky dictionary
if sc.sticky.has_key('sample_modeless_form'):
form = sc.sticky['sample_modeless_form']
if form:
form.Close()
form.Dispose()
form = None
sc.sticky.Remove('sample_modeless_form')
# OK button click handler
def OnOKButtonClick(self, sender, e):
print("clicked")
## End of Dialog Class ##
def Test():
# See if the form is already visible
if sc.sticky.has_key('sample_modeless_form'):
return
# Create and show form
form = ETOModelessForm()
form.Owner = Rhino.UI.RhinoEtoApp.MainWindow
form.Show()
# Add the form to the sticky dictionary so it
# survives when the main function ends.
sc.sticky['sample_modeless_form'] = form
if __name__ == '__main__':
Test()
I did a test this morning, putting in self.Close() as well as stripping out the Sticky Code and the form closes normally without crashing Rhino. If I reactivate the Sticky Code Rhino Crashes. I’ve pasted the code below. I’ve also posted a video of the Rhino crashing and not crashing after stripping out the Sticky code. The crash is about 1/3 of the way in the video after pushing the Cancel Button.
# Imports
import Rhino
import scriptcontext as sc
import Rhino.UI
import Eto.Drawing as drawing
import Eto.Forms as forms
# SampleEtoRoomNumber dialog class
class ETOModelessForm(forms.Form):
# Dialog box Class initializer
def __init__(self):
# Initialize dialog box
self.Title = 'Identify Assembly Components'
self.Padding = drawing.Padding(10)
self.Resizable = False
#FormClosed event handler
self.Closed += self.OnFormClosed
# self.ClientSize = drawing.Size(300, 400) #sets the (Width, Height)(Optional only)
# Create controls for the dialog
self.m_label = forms.Label(Text = 'Enter Your Name:')
self.m_textbox = forms.TextBox(Text = None)
# Create the default button
self.DefaultButton = forms.Button(Text = 'OK')
self.DefaultButton.Click += self.OnOKButtonClick
# Create the abort button
self.AbortButton = forms.Button(Text = 'Cancel')
self.AbortButton.Click += self.OnCloseButtonClick
# Create a table layout and add all the controls
layout = forms.DynamicLayout()
#Sets spacing between controls(pixels)
layout.Spacing = drawing.Size(5, 5)
#Textbox 1
layout.AddRow(self.m_label, self.m_textbox)
layout.AddRow(None)
#Buttons
layout.AddRow(self.DefaultButton, self.AbortButton)
# Set the dialog content
self.Content = layout
# Form Closed event handler
def OnFormClosed(self, sender, e):
print("the form has closed")
# Dispose of the form and remove it from the sticky dictionary
if sc.sticky.has_key('sample_modeless_form'):
form = sc.sticky['sample_modeless_form']
if form:
form.Dispose()
form = None
sc.sticky.Remove('sample_modeless_form')
# Close button click handler
def OnCloseButtonClick(self, sender, e):
self.Close()
print("the form has closed")
# Dispose of the form and remove it from the sticky dictionary
if sc.sticky.has_key('sample_modeless_form'):
form = sc.sticky['sample_modeless_form']
if form:
form.Dispose()
form = None
sc.sticky.Remove('sample_modeless_form')
# OK button click handler
def OnOKButtonClick(self, sender, e):
print("clicked")
def Test():
# See if the form is already visible
if sc.sticky.has_key('sample_modeless_form'):
return
# Create and show form
form = ETOModelessForm()
form.Owner = Rhino.UI.RhinoEtoApp.MainWindow
form.Show()
# Add the form to the sticky dictionary so it
# survives when the main function ends.
sc.sticky['sample_modeless_form'] = form
if __name__ == '__main__':
Test()
Just so I understand this. I disabled form.Dispose() and this solved the issue. Can you explain to me when one would want to use Dispose? I’m unsure of it’s purpose now.
Also, since I have two functions that handle closing the form, one for the ‘X’ and another for the button, do I need to have the Sticky Code in each function or is it only necessary in the function “OnFormClosed”? See below.
# Form Closed event handler
def OnFormClosed(self, sender, e):
print("the form has closed")
# Dispose of the form and remove it from the sticky dictionary
if sc.sticky.has_key('sample_modeless_form'):
form = sc.sticky['sample_modeless_form']
if form:
#form.Dispose()
form = None
sc.sticky.Remove('sample_modeless_form')
# Close button click handler
def OnCloseButtonClick(self, sender, e):
self.Close()
print("the form has closed")
# Dispose of the form and remove it from the sticky dictionary
if sc.sticky.has_key('sample_modeless_form'):
form = sc.sticky['sample_modeless_form']
if form:
# form.Dispose()
form = None
sc.sticky.Remove('sample_modeless_form')
self.Close() triggers your event OnFormClosed() when you click the close button. So you can put your sticky code only there and do not have to do it in the OnCloseButtonClick() function.
I guess this only is usable for modal forms if you want to cleanup memory references after closing it.