Problems with ETO GitHub Examples

Hello,
I’ve spent a couple frustrating hours starting to learn ETO with Python3. I have gotten a grand total of zero example scripts to work! Not a good average.

From here:

I have tried these scripts with and got the following errors

SampleEtoCollapsibleDialog.py
NameError: name 'Padding' is not defined

SampleEtoDialog.py
NameError: name 'Dialog' is not defined

SampleEtoRebuildCurve.py
NameError: name 'Dialog' is not defined

SampleEtoViewports.py and SampleEtoViewCaptureDialog.py

Rhino.Runtime.Code.Execution.ExecuteException: Object reference not set to an instance of an object.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at Eto.Forms.Window.set_Title(String value) in D:\BuildAgent\work\dujour\src4\DotNetSDK\Eto\src\Eto\Forms\Window.cs:line 244
   at InvokeStub_Window.set_Title(Object, Object, IntPtr*)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
--- End of stack trace from previous location ---
   at Python.Runtime.PythonException.ThrowLastAsClrException()
   at Python.Runtime.PythonException.ThrowIfIsNull(NewReference& ob)
   at Python.Runtime.PyModule.Execute(PyObject script, PyDict locals)
   at Python.Runtime.RhinoCodePythonEngine.RunScope(Object scope, Object code, String pythonFile, String beforeScript, String afterScript)
   at Rhino.Runtime.Code.Languages.PythonNet.CPythonCode.Execute(RunContext context)
   at Rhino.Runtime.Code.Code.ExecTry(RunContext context, IPlatformDocument& doc, Object& docState)
   at Rhino.Runtime.Code.Code.Run(RunContext context)
   --- End of inner exception stack trace ---
System.NullReferenceException: Object reference not set to an instance of an object.
   at Eto.Forms.Window.set_Title(String value) in D:\BuildAgent\work\dujour\src4\DotNetSDK\Eto\src\Eto\Forms\Window.cs:line 244
   at InvokeStub_Window.set_Title(Object, Object, IntPtr*)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
--- End of stack trace from previous location ---
   at Python.Runtime.PythonException.ThrowLastAsClrException()
   at Python.Runtime.PythonException.ThrowIfIsNull(NewReference& ob)
   at Python.Runtime.PyModule.Execute(PyObject script, PyDict locals)
   at Python.Runtime.RhinoCodePythonEngine.RunScope(Object scope, Object code, String pythonFile, String beforeScript, String afterScript)
   at Rhino.Runtime.Code.Languages.PythonNet.CPythonCode.Execute(RunContext context)
   at Rhino.Runtime.Code.Code.ExecTry(RunContext context, IPlatformDocument& doc, Object& docState)
   at Rhino.Runtime.Code.Code.Run(RunContext context)

Am I missing some kind of secret decoder ring to make the examples work?
The Rhino version is Version 8 SR8

All of these scripts are 6 to 7 years old, so maybe I have just followed the documentation to the wrong location?

Thanks for the insight,
Henry

I copy and paste into Rhino 8 and get this:

The 8.x version is a bit older. Running a check for update may help.

Is there anything different with the screenshot above?

Some of the more sophisticated examples do through some errors because of function overload syntax. I can take a look at that.

Well, I don’t know how to explain it, but I restarted Rhino and now the “basic” example works but the other ones still do not. The only change is that I closed Rhino and started it again. It seems worse to have something that works intermittently.

Here are a couple images to prove that I am not crazy…

Here is a quick brute force way to fix the Collapsable.

The Print method syntax and the multi-property control overloads are changed:

#! python3
################################################################################
# SampleEtoCollapsibleDialog.py
# MIT License - Copyright (c) 2017 Robert McNeel & Associates.
# See License.md in the root of this repository for details.
################################################################################
import scriptcontext
import rhinoscriptsyntax as rs
import clr
import sys

from Rhino.UI import *
from Eto.Forms import Form, Dialog, Label, TextBox, StackLayout, Orientation, Button, HorizontalAlignment, VerticalAlignment, TextAlignment, NumericUpDown, MessageBox, DropDown, CheckBox, TableLayout, StackLayoutItem, DynamicLayout, Control, Panel, Form
from Eto.Drawing import *

# Custom label helper to set alignment
def L(text):
    label = Label()
    label.Text = text
    label.VerticalAlignment = VerticalAlignment.Center
    label.TextAlignment = TextAlignment.Right
    return label

# Custom label helper to set alignment
def CB(text):
    cb = CheckBox()
    cb.Text = text
    return cb

form = Dialog[bool]() # return True or False from ShowModal()
form.Title = "My Collapsible Eto Form"
form.Resizable = False
form.Padding = Padding(5)

# set content of the collapsed section
collapsePanel = DynamicLayout()
collapsePanel.Visible = False
collapsePanel.Padding = Padding(40, 10)
collapsePanel.DefaultSpacing = Size(5, 5)
collapsePanel.BeginVertical()
collapsePanel.AddRow(None, L("Density:"), NumericUpDown())
collapsePanel.AddRow(None, L("Maximum angle:"), NumericUpDown())
collapsePanel.AddRow(None, L("Maximum aspect ratio:"), NumericUpDown())
collapsePanel.AddRow(None, L("Minimum edge length:"), NumericUpDown())
collapsePanel.AddRow(None, L("Maximum edge length:"), NumericUpDown())
collapsePanel.AddRow(None, L("Maximum distance, edge to surface:"), NumericUpDown())
collapsePanel.AddRow(None, L("Minimum initial grid quads:"), NumericUpDown())
collapsePanel.EndVertical()
collapsePanel.BeginVertical()
collapsePanel.AddRow(None, CB("Refine mesh"))
collapsePanel.AddRow(None, CB("Jagged seams"), CB("Pack textures"), None)
collapsePanel.AddRow(None, CB("Simple planes"))
collapsePanel.EndVertical()

# button to toggle collapsing
collapseButton = Button()
collapseButton.text = "v"
collapseButton.MinimumSize = Size.Empty
def collapseButton_Click(sender, e):
	try:
		if collapsePanel.Visible:
			form.ClientSize = Size(form.ClientSize.Width, form.ClientSize.Height - collapsePanel.Height)
			collapsePanel.Visible = False
			collapseButton.Text = "^"
		else:
			collapsePanel.Visible = True
			collapseButton.Text = "v"
			form.ClientSize = Size(max(form.ClientSize.Width, collapsePanel.Width), form.ClientSize.Height + collapsePanel.Height)
	except:
		print ("Unexpected error:", sys.exc_info()[0])
		pass # so we don't bring down rhino if there's a bug in the script

collapseButton.Click += collapseButton_Click


# a few buttons always shown at the bottom
previewButton = Button()
previewButton.Text = "Preview"

cancelButton = Button()
cancelButton.Text = "Cancel"
def cancelButton_Click (sender, e):
	try:
		form.Close(False)
	except:
		print ("Unexpected error:", sys.exc_info()[0])
		pass # so we don't bring down rhino if there's a bug in the script
cancelButton.Click += cancelButton_Click;

okButton = Button()
okButton.Text = "OK"
def okButton_Click (sender, e):
	try:
		form.Close(True)
	except:
		print ("Unexpected error:", sys.exc_info()[0])
		pass # so we don't bring down rhino if there's a bug in the script
okButton.Click += okButton_Click

# set default buttons when user presses enter or escape anywhere on the form
form.DefaultButton = okButton
form.AbortButton = cancelButton
toleranceUpDown = NumericUpDown()

# our main layout
layout = DynamicLayout()
layout.DefaultSpacing = Size(2,2)
layout.AddSeparateRow(None, L("Tolerance"), toleranceUpDown, L("millimeters"), collapseButton)
layout.AddCentered(collapsePanel) # we need this auto-sized so we can get its width to adjust form height
layout.Add(None); # expanding space, in case you want the form re-sizable
layout.AddSeparateRow(None, previewButton, cancelButton, okButton);
form.Content = layout;
	
	
if form.ShowModal():
	print ("Do something, user clicked OK")
	

Thank you for taking the time to go through that Scott. I just brought them into WinMerge and it looks like creating the objects without parameters is the current solution. I’ll try to run with that process.

As a side note, I just searched for “python eto forms” on YouTube. There were two hits… one from 4 years ago that is 1:14 long with no audio. The second is from 8 years ago, is 1:05 long and has no dialog. So it seems that Rhino is the only software using Eto with Python?

I have no idea how I am going to learn this. Where did everyone get their knowledge from?

Henry

We are actually working on new documentation as we speak. So I hope to get that out as soon as we can.

Here are some started guides:

2 Likes

yes, it’s unfortunate that that is not possible in Python 3. If you have to create many of the same controls, e.g. a series of numeric steppers, it helps to create a function for it, that will help keep your code more concise.

Mostly brute force honestly. But I think that was a bit painful, so as Scott says, I’m writing some docs to make jumping into Eto a lot easier.

All of the scripts are old, you need to make sure you use IronPython (2) for a chance of them working, or the syntax will be off.

SampleEtoCollapsibleDialog.py

Half works, the collapsing doesn’t seem to collapse correctly for me on Mac
If I add the below code, It works for me and I can collapse and uncollapse the form

collapsePanel.EndVertical()
collapsePanel.Visible = True # <-- Add this line

# button to toggle collapsing

SampleEtoDialog.py

Works for me in IronPython 2, nothing exciting, but the barebones work

SampleEtoRebuildCurve.py

This works for me

SampleEtoViewCaptureDialog.py

Change the code in the OnCaptureButtonClick with this

    # Capture button click handler 
    def OnCaptureButtonClick(self, sender, e): 
        # Capture the active view to a System.Drawing.Bitmap
        view = scriptcontext.doc.Views.ActiveView
        bitmap = EtoExtensions.ToEto(view.CaptureToBitmap())
        self.m_image_view.Image = bitmap
        # Update the text label
        self.m_label.Text = 'Captured view: {}'.format(view.ActiveViewport.Name)
        # Disable the default button
        self.DefaultButton.Enabled = False

SampleEtoViewports.py

Works well for me

I hope this makes your journey into Eto a bit easier @Henry_Wede, what are you hoping to make with Eto? :slight_smile: