Graphical Dialog and Checkboxes

Hi everyone,

I am trying to create a graphical dialog for the user to select which PVMT property groups to consider in the script. I created this dialog class:

class PvmtDialogPVG:
    def __init__(self, pvg_names: list):
        self.pvg_names = pvg_names  # List of names for checkboxes
        self.check_all = None
        self.check_none = None

    def build(self):
        self.labelFirstName = createLabel("Available Property Groups:", "1/1 <x")
        self.check_all = createCheckBox("SELECT ALL")
        index = 1
        for name in self.pvg_names:
            # Create a main checkbox for each pvg_name
            checkbox_name = f"checkbox_{index}"
            checkbox = createCheckBox(name, False, str(f"1/{index+1} >x"))
            setattr(self, checkbox_name, checkbox)
            index += 1   
        self.check_none = createCheckBox("NONE", False, f"1/{index+1} >x")
    
    def evaluate(self, javaDialog):
        selected_names = []
        if javaDialog.getData(self.check_all):
            selected_names = self.pvg_names
        elif javaDialog.getData(self.check_none):
            selected_names = selected_names
        else:
            index = 1
            for name in self.pvg_names:
                checkbox_name = f"checkbox_{index}"  # access the checkbox
                checkbox = getattr(self, checkbox_name, None)  # Get the checkbox attribute
                if checkbox and javaDialog.getData(checkbox):
                    selected_names.append(name)
                index += 1
        return selected_names

It will have checkboxes with the property groups name and with SELECT ALL and NONE.

When it is evaluated, it returns the name of the property groups whose checkboxes have been selected.

if pl_pvg_names_list:
    instance = PvmtDialogPVG(pl_pvg_names_list)
    title = "PVMT"
    sub_title = "Select the PVMT groups"
    javaDialog = createDialog("instance.build()", title, sub_title);
    result = executeUI("javaDialog.open()");
    if result == 0: 
        selected_pvg_names = instance.evaluate(javaDialog)
        print("Property groups selected: " + str(selected_pvg_names))
    else: 
        raise Exception("Dialog cancelled")

It works with a couple of problems:

  1. I am not able to implement callback Objects for the checkboxes. I would like to improve the SELECT ALL and NONE checkboxes with them.
  2. The position of the checkboxes does not work with the values I give. They are always one after the other
  3. Since I added the for cycle in the build method, the JAVA_API continues to run after I ran the script:
    image

Any advice or suggestions are more than appreciated!

1 Like

Hi,

  1. declare a global method (I was not able to make it work with an instance method):
def checkboxCallback():
    print("Checkbox...")

Then change the checkbox creation to add the call back:

checkbox = createCheckBox(name, False, "checkboxCallback()")
  1. For the layout I’m not sure how it works… "1/1 <x seems to define a grid layout with one column. You can create composite to have more complex layouts see createComposite(String layout).
  2. I didn’t experiement this issue with your code. When I close the dialog the script continue execution and terminate. Maybe you have something in the code after closing the dialog that prevent the completion of the script.
2 Likes

Firstly I would like to share the way to reach to the documentation of each module:

Help → Help Contents → Scripting User Guide → References → Loadable Modules Reference → System → Voila !!! :star_struck:

Below is a small example of checkbox implementation which would help you undertand how to use callback and how to use checkbox, try to run it in your machine for better understanding:

'''
Created on Jan 20, 2025

@author: Dev
'''

# Placeholder functions for UI controls
def addControl(): pass
def createButton(): pass
def createCheckBox(): pass
def createComboViewer(): pass
def createComparator(): pass
def createComposite(): pass
def createDialog(): pass
def createGroup(): pass
def createImage(): pass
def createLabel(): pass
def createLabelProvider(): pass
def createListViewer(): pass
def createProgressBar(): pass
def createRadioButton(): pass
def createScrolledComposite(): pass
def createSeparator(): pass
def createTableViewer(): pass
def createText(): pass
def createTextBox(): pass
def createTreeViewer(): pass
def createView(): pass
def createViewerColumn(): pass
def getComposite(): pass
def getProviderElement(): pass
def getUiEvent(): pass
def popComposite(): pass
def pushComposite(): pass
def removeControl(): pass
def setColumnCount(): pass
def showGrid(): pass

# Import the system modules to use
loadModule('/System/UI Builder')

# Global variables declaration
list = ['a', 'b', 'c', 'd', 'e']  # List of checkbox labels
checkboxs = []  # List to store checkbox objects

# Callback for select all button
def selectall(): 
    print("Selectall triggered")
    for checkbox in checkboxs:
        if checkbox.getSelection() == False:
            checkbox.setSelection(True)

# Callback for deselect all button
def deselectall():
    print("Deselectall triggered")
    for checkbox in checkboxs:
        if checkbox.getSelection() == True:
            checkbox.setSelection(False)

# Creating the main view
createView("Checkbox Explanation")

# Creating checkboxes
for checkbox in list:
    checkboxs.append(createCheckBox(f"{checkbox}", False, f'print("checkbox {checkbox} selected")'))

# Creating buttons for select all and deselect all actions
createButton("Select All", "selectall()")
createButton("Deselect All", "deselectall()")

When you read the documentation in the you will see below figure in the UI Builder module:

I am really happy you are using UI builder and trying to achieve dynamic UI.

and I hope I provided relevant answer to your query, I am not sure of the second query get back to you if I find something :mag:

2 Likes

I tried the index thing you tried to achieve in your code with the minor change in the code provided in above thread:

# Creating checkboxes
index = 1
for checkbox in list:
    checkboxs.append(createCheckBox(f"{checkbox}", False, f'print("checkbox {checkbox} selected")', f'1/{index} x'))
    index += 1 
    
# Creating buttons for select all and deselect all actions
createButton("Select All", "selectall()")
createButton("Deselect All", "deselectall()")
showGrid()

Gave me output:
Output

But reflecting on @YvanLussaud statement below

Changing the code to use composite:

# Creating checkboxes
pushComposite(createComposite("<")) # set the layout because didn't want the default layout

setColumnCount(2) # You can experiment more with it
for checkbox in list:
    checkboxs.append(createCheckBox(f"{checkbox}", False, f'print("checkbox {checkbox} selected")'))   
showGrid()
popComposite()
    
# Creating buttons for select all and deselect all actions
createButton("Select All", "selectall()")
createButton("Deselect All", "deselectall()")
showGrid()

Output:
image

1 Like

@Dev @YvanLussaud Thanks for your answers:

  1. the callback method declared as global instead of instance works! I will now try to implement @Dev 's code with a Dialog and not a View
  2. now that I have all the 4 input parameters for createCheckBox, the layout code works as it should. Probably before I called the placeholder wrongly.
  3. as @Dev pointed out, the script engine is set to be alive after the execution. Do you know how to change this? I tried to getScriptEngine() and terminate it but I get some error: java.lang.reflect.InaccessibleObjectException

Please visit this thread: Not able to creatButton with EASE - #4 by Dev

Do you know how to apply it in the case of a Dialog? I tried this at the end of my script but it does not work:

bundle = org.eclipse.core.runtime.Platform.getBundle("org.eclipse.e4.ui.workbench")
bundleContext = bundle.getBundleContext()
eclipseCtx = org.eclipse.e4.core.contexts.EclipseContextFactory.getServiceContext(bundleContext)
partService = eclipseCtx.get("org.eclipse.e4.ui.workbench.modeling.EPartService")
partService.hidePart(javaDialog, True)

and I have not found something like closeView() bur for Dialog.

When opening a view the script will run until the view is closed. This way the script can handle UI events. In the case of a dialog the script will return (and terminate) when the dialog is closed (OK or Cancel buttons). You can have a look at the view example and the dialog example in the tips and tricks. There are also more advanced examples in the EASE tutorial.

All the examples work. I created some simplier examples and found out:

  • In the case of a View, I have issues when there are multiple buttons and checkboxes with callback methods. If there is only one of them (only one button, only one checkbox with a callback method), all works correctly. With more of them, the scripts continue running after the View is closed.

  • In the case of a Dialog, I just solved removing the use of index in build() and evaluate() methods. I don’t know exactly why

    • [UPDATE] Also with Dialog, multiple cheboxes with callback methods make the script not stopping
1 Like

check_all() method added and working

def check_all():
    if instance.check_all.getSelection():
        for name in instance.pvg_names:
            checkbox_name = f"checkbox_{name}"
            checkbox_instance = getattr(instance, checkbox_name)
            checkbox_instance.setSelection(True)
    else:
        for name in instance.pvg_names:
            checkbox_name = f"checkbox_{name}"
            checkbox_instance = getattr(instance, checkbox_name)
            checkbox_instance.setSelection(False)
  
class PvmtDialogPVG:
    def __init__(self, pvg_names: list):
        self.pvg_names = pvg_names  # List of names for checkboxes
        self.check_all = None
        self.check_none = None
        self.prova = "prova"

    def build(self):
        self.labelFirstName = createLabel("Available Checkboxes:", "1/1 <x")
        
        
        for name in self.pvg_names:
            # Create a main checkbox for each pvg_name
            checkbox_name = f"checkbox_{name}"
            checkbox = createCheckBox(name, False)
            setattr(self, checkbox_name, checkbox)  
            
        self.check_all = createCheckBox("SELECT ALL", False, "check_all()")
    
    def evaluate(self, javaDialog):
        selected_names = []
        if javaDialog.getData(self.check_all):
            selected_names = self.pvg_names
        else:
            for name in self.pvg_names:
                checkbox_name = f"checkbox_{name}"  # access the checkbox
                checkbox = getattr(self, checkbox_name, None)  # Get the checkbox attribute
                if checkbox and javaDialog.getData(checkbox):
                    selected_names.append(name)
        return selected_names
    
    
list_checks = ['a', 'b', 'c', 'd', 'e']  # List of checkbox labels
instance = PvmtDialogPVG(list_checks)
title = "Checkbox Example"
sub_title = "Select the checkboxes"
javaDialog = createDialog("instance.build()", title, sub_title);
result = executeUI("javaDialog.open()");
if result == 0: 
    selected_pvg_names = instance.evaluate(javaDialog)
    print("Selected Checkboxes: " + str(selected_pvg_names))

Looking for a solution to have multiple checkboxes with callback methods

I added an other callback to your script and it also prevent the script from finishing… looks like an issue with EASE.

1 Like