Issue in Eto Docs python sample

Hi This example does not work in Python 3 if you cut and paste it into Script Editer
in Rhino 8.

Roger

import scriptcontext as sc
 
import Rhino
from Rhino.UI import RhinoEtoApp, EtoExtensions
 
from Eto.Drawing import Padding
from Eto.Forms import *
 
parent = RhinoEtoApp.MainWindowForDocument(sc.doc)
 
dialog = Dialog()
dialog.Padding = Padding(8)
 
drop_down = DropDown()
drop_down.DataStore = ["Point", "Curve", "Brep" ]
drop_down.SelectedIndex = 0
 
dialog.Content = drop_down
dialog.ShowModal(parent)

What doesn’t work about it? Do you get an error message?
It works perfectly for me in Rhino 8 win/mac.

Works in Iron Python not Python 3 it gives the error

name dialog is not defined as shown in the screenshot

Roger

If you use the script in a completely empty file does it work? The other imports might be messing it up.

Hi Callum,

No if it is pasted in the script editor then nothing other than the error I quoted. If it is pasted into Edit Python Script editor as an iron python script it works nota a Python 3 as indicated on the web page.

Roger

I’ve moved to a new topic as this might get a bit long and off topic for the original post.

If

from Eto.Forms import *

Is replaced with;

from Eto.Forms import Dialog, DropDown

Does that fix your issue?

yes that works now in Python 3

Roger

1 Like

I’ve updated the docs to be more specific :slight_smile:

1 Like

Hi Callum,

Thanks us self taught and still learning programmers need all the help we can get.

Kind regards

Roger

1 Like

If you struggle anywhere else in the docs, let me know, I’d like to make sure you can walk through any page and have a good grasp on what you read and learn.

3 Likes

In my oinion the way you guide through the subjects with many and increasingly involved examples is very well designed and can be followed nicely! Also the small result images next to the code snippets are very nice to have a quick clue on what’s covered in that section.
Great way of writing docs, thank you!

2 Likes

I tried the code and it worked as is, but, I got trapped the second time I ran it. If I switch to the script editor before clearing the dialog I think it will happen again. Easy to avoid at least.

From my AutoLISP adventures I know that the hardest bugs to find are the ones that only occur sometimes or on different systems. AutoLISP is pretty basically so I can usually find them, and the ultra-rare times I can’t I just take a detour.

I agree with what the others are saying. I’ve always liked the style/nature of ETO just the support hasn’t been there for novice/low-level coders. I’ve been trying to figure out why I was so successful with AutoLISP but floundering with Rhino stuff. I recall a while back when I first tried to learn ETO they only had a few simple examples on their site. One example was even missing a line of code and wouldn’t run. You figure all the work that goes into creating ETO and then it just goes to waste if nobody can teach people how to use it. This will be a huge boost I think and we might see some cool stuff appearing in the not-so-distant future because of it.

Thanks so much for putting this together!

1 Like

This is a shame, but I’m not too surprised this sort of thing can happen, I found dialogs better than forms for the docs, but still not perfect.

That would be very cool, I hope so! :blush:

Hi Callum,

I hope you can explain something to me, I am wanting to have three drop down lists side by side in one layout, depending upon the list index of the first the second list is populated and finally depending upon the second drop down index the third is populated. In my head this is straight forward but for some reason it doesn’t come together when written out.

eg List 1 flange, bend , reducer

 if flange List 2 150, 300, 600, 900
 if bend or reducer selected List 2  1" 2" 3" 4"

 if flange was selected in list 1 then List3   1" 2" 3" 4"
 if bend or reducer selected in List 1 then List 3 is blank 

All help appreciated

Roger

Hey @RogerD,

Cool question, Here is a simple-ish way to achieve this in python, I think there are better ways with custom data structures but I wanted to keep this simple, that being said, this still feels tricky.

# Imports
import scriptcontext as sc
 
import Rhino
from Rhino.UI import RhinoEtoApp, EtoExtensions
 
from Eto.Drawing import Padding, Size
from Eto.Forms import Dialog, DropDown, DynamicLayout

from System.Collections.ObjectModel import ObservableCollection

 
dialog = Dialog()
dialog.Width = 300
dialog.Padding = Padding(8)

# One data source for simplicity. Dictionaries are always good.
data = {
    100: [110, 120, 130],

    110: [111, 112, 113],
    120: [121, 122, 123],
    130: [131, 132, 133],

    200: [210, 220, 230],

    210: [211, 212, 213],
    220: [221, 222, 223],
    230: [231, 232, 233],

    300: [310, 320, 330],

    310: [311, 312, 313],
    320: [321, 322, 323],
    330: [331, 332, 333],
}

# ObservableCollection will notify the UI of changes for us
dd1_data = ObservableCollection[object]()
dd1_data.Add(100)
dd1_data.Add(200)
dd1_data.Add(300)
dd2_data = ObservableCollection[object]()
dd3_data = ObservableCollection[object]()

dd1 = DropDown()
dd1.DataStore = dd1_data

dd2 = DropDown()
dd2.DataStore = dd2_data

dd3 = DropDown()
dd3.DataStore = dd3_data

# Cache indexes to avoid unnecessary state updates which can be a bit crashy
dialog.dd1_index = -1
dialog.dd2_index = -1

dialog.busy = False
def update_state(sender, args):
    # Super safe busy check, prevents recursion!
    if (dialog.busy):
        return
    
    dialog.busy = True
    
    # Prevents crashing if there is no data, we should do this more, but I'm lazy
    if dd1.SelectedIndex == -1:
        return

    if (dd1.SelectedIndex != dialog.dd1_index):

        items = data[dd1.SelectedValue]

        # Note we don't set a NEW value, we use the same collection
        dd2_data.Clear()
        for i in items:
            dd2_data.Add(i)
        dd2.SelectedIndex = 0
        dd3.SelectedIndex = 0
        dialog.dd2_index = 0

    # This should run on 1 or 2 changing index
    if (dd2.SelectedIndex != dialog.dd2_index or
        dd1.SelectedIndex != dialog.dd1_index):
        items = data[dd2.SelectedValue]

        # Note we don't set a NEW value, we use the same collection
        dd3_data.Clear()
        for i in items:
            dd3_data.Add(i)
        dd3.SelectedIndex = 0

    dialog.dd2_index = dd2.SelectedIndex
    dialog.dd1_index = dd1.SelectedIndex
    
    # We are no longer busy!
    dialog.busy = False

dd1.SelectedIndexChanged += update_state
dd2.SelectedIndexChanged += update_state
dd1.SelectedIndex = 0
 
# Nice way to set up a UI with equal spacing
dynamic = DynamicLayout()
dynamic.Spacing = Size(4, 4) # Bit cramped otherwise
dynamic.BeginHorizontal()
dynamic.Add(dd1, True)
dynamic.Add(dd2, True)
dynamic.Add(dd3, True)
dynamic.EndHorizontal()

dialog.Content = dynamic

parent = RhinoEtoApp.MainWindowForDocument(sc.doc)
dialog.ShowModal(parent)

Hi Callum,

What can I say I’ve just been totally depressed I have taken 2 days and not got it to work and you have done it in few hours, this is far simpler than my approach.

Please use it as an example on the website as there is no information that I could find other than TreeGrid or add more than one list box in a row in layout.

The other thing that gives me problems are the Ok and Cancel buttons on click event always seems to give me an error could you show how they are added to the script.

I will send you one of my scripts so you can see the approach I have followed from bits of information I have been able to find as it is totally different from what you explain so I need to understand which is the best method.
Geo Import Export Points 8-3.py (14.7 KB)

Thank you for your help, greatly appreciated i’m sure many can learn from it.

Roger

I do do this every day for a living, so I’m not too bad at it :slight_smile:

This example felt a bit wonky and it crashed A LOT which I’d like to avoid with any site examples.
I created a misc examples page, more examples is always good. Rhino - Eto Examples
I could write a page on composition though which might be an idea.

I’ll take a look at these buttons.