QCAD
Open Source 2D CAD
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Persistent Widgets

With the QCAD Application Framework you can easily create a dialog or widget that can store and restore its user input. In this tutorial we will create a dialog with two input widgets: X Position and Y Position.

Creating the Folder Structure

Create a new action called "PersistentWidgets" as described in CreatingActions.

Creating the UI file

With Qt Designer we create the UI file for the dialog called "PersistentWidgets.ui".

position_dialog.png
  • Set the object name of the dialog to "PersistentWidgets".
  • Set the object name of the upper QLineEdit widget to "PositionX".
  • Set the object name of the lower QLineEdit widget to "PositionY".
  • All input widgets should have meaningful default values. In this example set both values to "0.00".

Saving and Restoring User Input

Thanks to the introspection facilities of Qt, storing and restoring dialog data is a one-liner.

include("scripts/WidgetFactory.js");
PersistentWidgets.prototype.beginEvent = function() {
Tutorials.prototype.beginEvent.call(this);
// Create the dialog from the .ui file using the helper
// function WidgetFactory.createWidget().
var dialog = WidgetFactory.createWidget(
"PersistentWidgets.ui");
// Restore the previous user data or display default values as
// set in Qt Designer:
WidgetFactory.restoreState(dialog);
// Display and execute the dialog:
if (!dialog.exec()) {
dialog.destroy();
// User hit cancel:
this.terminate();
return;
}
// User hit OK. Store the new user input:
WidgetFactory.saveState(dialog);
var widgets = getWidgets(dialog);
var positionX = widgets["PositionX"].text;
var positionY = widgets["PositionY"].text;
// Print the user input to the QCAD console:
var appWin = EAction.getMainWindow();
appWin.handleUserMessage("Position X: " + positionX);
appWin.handleUserMessage("Position Y: " + positionY);
dialog.destroy();
this.terminate();
};

Start QCAD and choose Persistent Widgets from the menu Examples. Enter numeric values e.g. for x "0.1" and for y "0.2". Then close the dialog and start the same action again. The input fields now shows 0.1 for x resp. 0.2 for y. You can also quit QCAD, restart it and start the action again. The dialog input fields are set to the last used valued.

Behind the Scene

The Widget Factory uses QSettings to save or restore values. The values set above are stored in a file called "QCAD3.conf" located in the QCAD configuration folder ($HOME/.config/RibbonSoft under Unix systems including Linux and Mac OS X or HKEY_CURRENT_USER under Windows).

Inside this file our dialog has its own group where values are stored. By definition the name of the group is the same as the dialog object name set in Qt Designer: PersistentWidgets. The same applies to the widget values. They are named after the object name set in Qt Designer.

...
PositionX=0.1
PositionY=0.2
...

In this tutorial a QDialog is used as top level widget. However you can use a simple QWidget, a QDockWidget or any other widget. The mechanism and procedure are always the same. Always make sure that WidgetFactory.restoreState() is called before the widget is shown, and analogically WidgetFactory.saveState() is called before the widget is destroyed.

The Complete Script

include("scripts/WidgetFactory.js");
include("../Tutorials.js");
function PersistentWidgets(guiAction) {
Tutorials.call(this, guiAction);
}
PersistentWidgets.prototype = new Tutorials();
PersistentWidgets.prototype.beginEvent = function() {
Tutorials.prototype.beginEvent.call(this);
// Create the dialog from the .ui file using the helper
// function WidgetFactory.createWidget().
var dialog = WidgetFactory.createWidget(
"PersistentWidgets.ui");
// Restore the previous user data or display default values as
// set in Qt Designer:
WidgetFactory.restoreState(dialog);
// Display and execute the dialog:
if (!dialog.exec()) {
dialog.destroy();
// User hit cancel:
this.terminate();
return;
}
// User hit OK. Store the new user input:
WidgetFactory.saveState(dialog);
var widgets = getWidgets(dialog);
var positionX = widgets["PositionX"].text;
var positionY = widgets["PositionY"].text;
// Print the user input to the QCAD console:
var appWin = EAction.getMainWindow();
appWin.handleUserMessage("Position X: " + positionX);
appWin.handleUserMessage("Position Y: " + positionY);
dialog.destroy();
this.terminate();
};
PersistentWidgets.init = function(basePath) {
var action = new RGuiAction(qsTr("&Persistent Widgets"), RMainWindowQt.getMainWindow());
action.setRequiresDocument(true);
action.setScriptFile(basePath + "/PersistentWidgets.js");
action.setGroupSortOrder(80100);
action.setSortOrder(200);
action.setWidgetNames(["TutorialsMenu"]);
};