1. Overview
The intention of QtVCP is to supply an infrastructure to support screen and VCP panel building for LinuxCNC.
By providing a diverse widget set and supporting custom coding, QtVCP hopes that development energy will be expended in one toolkit rather than continuous re-invention.
By using the same toolkit across many screens/panels, users should have an easier time customizing/creating these, and developers should find it easier to help trouble shoot with less effort.
QtVCP uses a Qt Designer built .ui
file and a Python handler file
-
to load and control a screen/panel that displays Qt widgets and
-
to control LinuxCNC’s motion controller or HAL pins.
There are builtin screens and panels, easily loaded by a user, or users can build/modify one of their own.
QtVCP uses libraries and custom widgets to hide some of the complexity of interfacing to LinuxCNC. By using QtVCP’s library rather than LinuxCNC’s, we can mitigate minor LinuxCNC code changes.
2. Builtin Locations
Builtin screens and panels are stored in separate folders:
-
Screens in
share/qtvcp/screens
-
Panels in
share/qtvcp/panels
-
Stock images in
share/qtvcp/images
Screens and panels are sorted by their folder name, which is also the name used to load them.
Inside the folder would be:
-
the
.ui
file, -
the handler file, and
-
possibly the
.qss
theme file.
3. QtVCP Startup To Shutdown
QtVCP source is located in +src/emc/usr_intf/qtvcp+
folder of LinuxCNC source tree.
3.1. QtVCP Startup
When QtVCP first starts:
-
It must decide if this object is a screen or a panel.
-
It searches for and collects information about paths of required files and useful folders.
-
It then:
-
Builds the HAL component,
-
Loads the window instance,
-
Adds handler extensions,
-
Installs an event filter.
-
Now the window/widgets are instantiated, the HAL pins are built. This also initiates the +_init_hal()+
function of the widgets.
. The +initialized__()+
handler function is called
. The STATUS
library is forced to update.
. HAL component is set ready at this point.
. A variety of optional switch arguments are set, including calling a POSTGUI
HAL file (if a screen).
. Terminate signals are trapped and QtVCP now polls for events.
3.2. QtVCP Shutdown
Finally when QtVCP is asked to shutdown:
-
It calls shutdown functions in the handler file,
-
STATUS
monitoring is shut down -
HAL component gets killed
4. Path Information
When QtVCP loads it collects paths information.
This is available in the handler file’s +__init__()+
function as path
:
-
IMAGEDIR
-
Path of builtin images
-
SCREENDIR
-
Path of builtin motion controller screens
-
PANELDIR
-
Path of builtin accessory panels
-
WORKINGDIR
-
Path of where QtVCP was launched from
-
CONFIGPATH
-
Path of the launched configuration
-
BASEDIR
-
General path, used to derive all paths
-
BASENAME
-
Generic name used to derive all paths
-
LIBDIR
-
Path of QtVCP’s Python library
-
HANDLER
-
Path of handler file
-
XML
-
Path of .ui file
-
DOMAIN
-
Path of translation
-
IS_SCREEN
-
Screen/panel switch
5. Idiosyncrasies
These try to cover non-obvious situations.
5.1. Error Code Collecting
LinuxCNC’s error code collecting can only be read from one place.
When read, it is consumed, i.e. no other object can read it.
In QtVCP screens, it is recommended to use the ScreenOptions
widget to set up error reading.
Errors are then sent to other objects via STATUS
signals.
5.2. Jog Rate
LinuxCNC has no internal record of jog rate: you must specify it at the time of jogging.
QtVCP uses the STATUS
library to keep track of the latest linear and angular jog rates.
It is always specified in machine units per minute and must be converted when in non-machine units mode.
So, if your machine is imperial based but you are in metric mode, changes to jog rate sent to ACTION
functions must be converted to imperial.
In the same manner, if the machine is metric based and you are in imperial mode, changes to jog rate must be sent to ACTION
functions in metric units.
For angular jog rates the units don’t change in metric/imperial mode so you can send them to ACTION
functions without conversion.
While you are free to ignore this jogging record while building screens, anyone modifying your screen and using the builtin jog rate widgets would not get the desired results as the ACTION
library’s DO_JOG
function gets it’s jog rate from the STATUS
library.
5.3. Keybinding
Attention
|
Keybinding is always a difficult-to-get-right-in-all-cases affair. |
Custom keybinding functions are to be defined in the handler file.
Most importantly widgets that require regular key input and not jogging, should be checked for in the processed_key_event__
function.
5.4. Preference File
Some QtVCP widgets use the preference file to record important information.
This requires the preference file to be set up early in the widget initialization process.
The easiest way to do this is to use the ScreenOptions
widget.
5.5. Widget Special Setup Functions
QtVCP looks for and calls the +_hal_init()+
function when the widget is first loaded.
It is not called when using Qt Designer editor.
After this function is called the widget has access to some special variables:
-
self.HAL_GCOMP
-
The HAL component instance
-
self.HAL_NAME
-
This widget’s name as a string
-
self.QT_OBJECT_
-
This widget’s PyQt object instance
-
self.QTVCP_INSTANCE_
-
The very top level parent of the screen
-
self.PATHS_
-
The instance of QtVCP’s path library
-
self.PREFS_
-
The instance of an optional preference file
-
self.SETTINGS_
-
The
Qsettings
object
When making a custom widget, _import and sub class _the +_HalWidgetBase+
class for this behavior.
5.6. Dialogs
Dialogs (AKA "pop up windows") are best loaded with the ScreenOptions
widget, but they can be placed on the screen in Qt Designer.
It doesn’t matter where on the layout but to make them hidden, cycle the state
property to true then false.
By default, if there is a preference file, the dialogs will remember their last size/placement.
It is possible to override this so they open in the same location each time.
5.7. Styles (Themes)
While it is possible to set styles in Qt Designer, it is more convenient to change them later if they are all set in a separate .qss
file. The file should be put in the same location as the handler file.