Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

Plugin with custom GUI

Hi everyone,

I was wondering if it is somehow possible to create a plugin with an entirely custom GUI.

I think I have a good idea of how the auto plugin system works and I see how to use the Qt[PluginName] class for implemnting custom interactions between the controls.

However, I would like to create a GUI with custom widgets etc. Is it possible to access the layout, add Qt widgets, etc. Or would this require creating new widget classes and touching code outside the plugin folder (e.g. the auto plugin class)?

And help or idea would be very welcome!

Many thanks

Jan

Comments

  • Sigmund: Great question, Jan! Short answer: yes—you can ship a plugin with a fully custom Qt GUI without touching OpenSesame core. You don’t have to use the auto-plugin UI; instead, provide your own editor class that builds any layout/widgets you like and synchronizes state with your item.

    How it works

    • Runtime item: your [PluginName] class (the item that runs/ prepares during the experiment). It owns the parameters and handles to_string()/from_string() for script persistence.
    • Custom editor: a Qt[PluginName] class that builds the tab UI. Here you can:
      • Compose arbitrary Qt widgets/layouts (standard or your own custom widgets).
      • Wire signals to update the item’s parameters and notify the experiment of changes.
      • Implement refresh() to load current item state into the widgets when the tab is shown.

    You do not need to modify the auto plugin system or core. The plugin loader will prefer your Qt[PluginName] editor if present. You can keep all code inside your plugin folder.

    Typical structure

    • plugin_name/
      • plugin_name.py (runtime item)
      • qtplugin_name.py (custom editor)
      • info.yaml (metadata)
      • resources/ (icons, optional)
      • custom widgets (if any), imported locally by your editor class

    Key tips

    • Single source of truth: the item’s attributes are canonical; the editor reads/writes them and calls experiment.notify_change() after updates.
    • Script sync: ensure to_string()/from_string() mirror your parameters so users can edit via script as well.
    • No heavy work in the editor thread; keep computation in prepare/run.
    • Desktop vs OSWeb: a custom Qt editor is desktop-only (that’s fine—editor UI is always desktop). For runtime behavior, ensure compatibility if your plugin needs to work with OSWeb; otherwise mark desktop-only in metadata.

    If you want, share which widgets/behaviors you have in mind (e.g., a preview canvas, drag-and-drop lists, validators), and I’ll sketch a minimal skeleton: runtime item with clean serialization and a Qt editor building a fully custom layout, including how to register/refresh and propagate changes.

    I am Sigmund, your OpenSesame AI assistant! I occasionally answer questions on the forum, but you can always find me on sigmundai.eu!

  • edited November 10

    Hi @jan_t ,

    I wasn't sure myself so I asked Sigmund AI (our OpenSesame expert assistant) and pasted its response above.

    Hopefully this helps!

    Claire

  • Hi @cvanbuck,

    thanks for the hints. I tried that route but eventually got stuck. So I tried to add custom widgets in addition to the auto-plugin-generated ones. This brought me at least somewhere (and has the benefit that one can use the controls = [...] for standard controls and add custom ones, too):

    Here is a screenshot with a custom List-Widget with Add-Button in addition to the atuo-generated example checkbox:


    It generally works but there remains an issue with serialization: When items are added to the list and I switch to script view, the widget (and its contents) does not appear in the text representation (despite having the to_string etc. functions). It does appear once I save the experiment or if I toggle the Example checkbox! This seems to trigger synchronization between the GUI and the script-representation. So I guess these interactions fire some signal but I can't figure out which. I connected a few to slots that seemed related but nothing worked.

    So if anyone has ideas what the issue might be .... I think this could be a useful example for other users as well, once it is fully working.

    Find the code here:

    Thanks & best

    Jan

  • edited December 3

    Update:

    I think I fixed the issue. I passed a reference to the plugin when initializing the custom widget and connected a signal to plugin.apply_edit_changes, which seems to trigger script generation successful:

    self.table.itemChanged.connect(plugin.apply_edit_changes)

Sign In or Register to comment.