Sample for a custom algorithm with a QML UI

This sample algorithm demonstrates the QML UI module functionality for custom algorithms.

QML (Qt Modeling Language) is a user interface markup language. It is a declarative language (similar to CSS and JSON) for designing user interface–centric applications. Inline JavaScript code handles imperative aspects. […] A QML document describes a hierarchical object tree. QML modules shipped with Qt include primitive graphical building blocks (e.g., Rectangle, Image), modeling components (e.g., FolderListModel, XmlListModel), behavioral components (e.g., TapHandler, DragHandler, State, Transition, Animation), and more complex controls (e.g., Button, Slider, Drawer, Menu). These elements can be combined to build components ranging in complexity from simple buttons and sliders, to complete internet-enabled programs.

Reference: Wikipedia

Using QML for creating custom UIs allows to:

Related documentation:

Providing QML UI for custom algorithms

In order to provide a QML UI for custom algorithms it is neccessary to create a …_ca.qml file and place it next to …_ca.py file. No other actions need to be done. optiSLang automatically loads the QML and embeds the UI into custom algorithm dialog widget.

Get and set custom algorithm settings from within the QML UI

optiSLang provides a context object to the QML scope. It is called "backend" and resides in the QML root scope.

Backend object synopsis

				
	class QMLBackEnd : public QObject
	{
		const QString & settings() const;
		void setSettings(const QString &_settings);
		void requestCommitSettings();
	
		QString executeCustom ( const QString & _execute_arg );
		void executeCustom ( const QString & _execute_arg, const QJSValue & _execute_callback );
		
		void emitInfoLogMessage ( const QString & _message );
		void emitWarningLogMessage ( const QString & _message );
		void emitErrorLogMessage ( const QString & _message );

	signals:
		void settingsChanged();
		void commitSettingsRequested();
	};
				
			
It can be used to access the custom algorithm settings:

The backend.onSettingsChanged and backend.onCommitSettingsRequested signals can for example be used in a QML "Connections" declaration:

				
	Connections {
	    target: backend // sender
	    onSettingsChanged: {
	        var settings_json = JSON.parse(backend.settings);
	        // update controls
	    }
	    onCommitSettingsRequested: {
	        var settings_json = JSON.parse(backend.settings);
	        // update settings_json from controls
	        backend.settings = JSON.stringify(settings_json);
	    }
	}					
				
			

Calling custom python functionality

Sometimes it can be neccessary, to execute custom Python functionality from within the QML scope. This can be done by the following procedure:

Example python code:

				
	def ExecuteCustom(args):
		""" 
		Args:
			args[0]: settings
			args[1]: string; Json formated execute args
		Returns:
			string; Json formated execute results
		"""    
		ret = {'success': True, 'args': args[1]}
	    return json.dumps (ret)									
				
			

Example QML code:

				
	Button {
		id: button1
		text: "Execute custom functionality in a separate thread"
		onClicked: {
			var args = { string_arg: "foobar", bool_arg: false };
	        backend.executeCustom ( JSON.stringify(args), function(result) 
			{
	            console.log(result);
	        })
	    }
	}										
				
			

Emitting log messages