Modules

GUI

TwinCAT UI Elements

TwinCAT widgets are Qt elements that are easily linked to an ADS symbol.

E.g. a label that shows an output value or an input box which changes a parameter.

The @pyqtSlot() is Qt decorator. In many cases it is not essential, but it’s good practice to add it anyway.

TcWidget

class twinpy.ui.TcWidget(*args, **kwargs)[source]

Bases: abc.ABC

Abstract class, to be multi-inherited together with a Qt item.

It is important to call this init() as late as possible from a subclass! The order should be:

  1. Subclass specific stuff (e.g. number formatting)

  2. Call to super().__init__(…) - Now the QWidget stuff has been made ready

  3. QWidget related stuff

Parameters
  • args

  • kwargs – See list below - kwargs are passed along to connect_symbol too

Kwargs
  • symbol: twincat.symbols.Symbol to link to (i.e. to read from

    and/or write to)

  • format: Formatter symbol, e.g. ‘%.1f’ or ‘%d’ or callable

    function with a single argument (‘%.3f’ by default) (ignored when not relevant)

EVENT_NONE = 'none'
EVENT_NOTIFICATION = 'notification'
connect_symbol(new_symbol: Optional[twinpy.twincat.symbols.Symbol] = None, **kwargs)[source]

Connect a symbol (copy is left as property).

By default a device callback is created with an on-change event from TwinCAT. Old callbacks are deleted first. Pass None to only clear callbacks. The notification handles are stored locally. Extend (= override but call the parent first) this method to configure more of the widget, useful if e.g. widget callbacks depend on the symbol.

Parameters
  • new_symbol – Symbol to link to (set None to only clear the previous)

  • kwargs – See list below - Keyword arguments are passed along as device notification settings too

kwargs:

event_type

format(value: Any) str[source]

“Use the stored formatting to created a formatted text.

In case the format specifier is a string and the new value is a list, element-wise string formatting will be concatenated automatically.

abstract twincat_receive(value)[source]

Callback attached to the TwinCAT symbol.

Note: changing a state of a widget (e.g. checkbox being checked through setChecked(True)) will typically fire the on-change events again. So be careful to prevent an event loop when updating a widget based on a remote change: a change could result in a state change, which could result in a remote change, etc.

Parameters

value – New remote value

twincat_send(value: Any)[source]

Set value in symbol (and send to TwinCAT).

TcLabel

class twinpy.ui.TcLabel(*args, **kwargs)[source]

Bases: PyQt5.QtWidgets.QLabel, twinpy.ui.tc_widgets.TcWidget

Label that shows a value.

Parameters
twincat_receive(value)[source]

Callback attached to the TwinCAT symbol.

Note: changing a state of a widget (e.g. checkbox being checked through setChecked(True)) will typically fire the on-change events again. So be careful to prevent an event loop when updating a widget based on a remote change: a change could result in a state change, which could result in a remote change, etc.

Parameters

value – New remote value

value_format: Union[str, Callable[[Any], str]]

TcLineEdit

class twinpy.ui.TcLineEdit(*args, **kwargs)[source]

Bases: PyQt5.QtWidgets.QLineEdit, twinpy.ui.tc_widgets.TcWidget

Readable and writable input box.

Parameters
on_editing_finished()[source]

Called when [Enter] is pressed or box loses focus.

on_text_edited(*_value)[source]

Callback when text was modified (i.e. on key press).

twincat_receive(value) Any[source]

Callback attached to the TwinCAT symbol.

Note: changing a state of a widget (e.g. checkbox being checked through setChecked(True)) will typically fire the on-change events again. So be careful to prevent an event loop when updating a widget based on a remote change: a change could result in a state change, which could result in a remote change, etc.

Parameters

value – New remote value

value_format: Union[str, Callable[[Any], str]]

TcPushButton

class twinpy.ui.TcPushButton(*args, **kwargs)[source]

Bases: PyQt5.QtWidgets.QPushButton, twinpy.ui.tc_widgets.TcWidget

Button that sends value when button is held pressed.

Parameters
  • args

  • kwargs

Kwargs
  • value_pressed: Value on press (default: 1), None for no action

  • value_released: Value on release (default: 0), None for no action

  • See TcWidget

on_pressed()[source]

Callback on pressing button.

on_released()[source]

Callback on releasing button.

twincat_receive(value)[source]

Do nothing, method requires definition anyway.

value_format: Union[str, Callable[[Any], str]]

TcRadioButton

class twinpy.ui.TcRadioButton(*args, **kwargs)[source]

Bases: PyQt5.QtWidgets.QRadioButton, twinpy.ui.tc_widgets.TcWidget

Radiobutton that updates the symbol when it is selected.

The radiobutton will _not_ update the symbol when another selection is made. Instead a write could be performed if that other radio is also a TcWidget.

Use TcRadioButtonGroupBox instead to create a set of radio buttons together that all update the same ADS symbol.

When connecting to a boolean symbol, use 0 and 1 as values for the best result instead of True and False.

Radios need to be in a QButtonGroup together to link together.

Parameters
  • label (str) – Label of this radio button

  • args

  • kwargs

Kwargs
  • value_checked: Value when radio becomes checked (default: 1)

  • See TcWidget

on_toggled()[source]

Callback when radio state is togged (either checked or unchecked).

twincat_receive(value)[source]

Set checked state if the new value is equal to the is-checked value.

value_format: Union[str, Callable[[Any], str]]

TcRadioButtonGroupBox

class twinpy.ui.TcRadioButtonGroupBox(*args, **kwargs)[source]

Bases: PyQt5.QtWidgets.QGroupBox, twinpy.ui.tc_widgets.TcWidget

An instance on this class forms a group of radio buttons.

The group of radio buttons together control a single ADS variable.

Instances of QRadioButton will be automatically created through this class. Using literal instances of TcRadioButton is not efficient because of duplicate callbacks.

When the remote value changes to a value that is not listed as an option in the radio_toggle, the displayed value simply won’t change at all.

The options argument is required.

Parameters
  • title (str) – Title of this QGroupBox

  • args

  • kwargs

Kwargs
  • options: List of tuples that form the label-value pairs of the radio,

    e.g. [(‘Low Velocity’, 0.5), (‘High Velocity’, 3.0)]

  • layout_class: Class of the layout used inside the QGroupBox (default:

    QVBoxLayout)

  • See TcWidget

on_click(button: PyQt5.QtWidgets.QAbstractButton)[source]

Callback when a button of the group was pressed.

twincat_receive(value)[source]

Callback for a remote value change.

value_format: Union[str, Callable[[Any], str]]

TcCheckBox

class twinpy.ui.TcCheckBox(*args, **kwargs)[source]

Bases: PyQt5.QtWidgets.QCheckBox, twinpy.ui.tc_widgets.TcWidget

Checkbox to control a symbol.

Set either value to None to send nothing on that state. For the best results, use 1 and 0 for a boolean variable instead of True and False.

Parameters
  • label (str) – Label of this radio button

  • args

  • kwargs

Kwargs
  • value_checked: Value when checkbox becomes checked (default: 1)

  • value_unchecked: Value when checkbox becomes unchecked (default: 0)

  • See TcWidget

on_toggled()[source]

Callback when box state is togged (either checked or unchecked).

twincat_receive(value)[source]

Set checked state if the new value is equal to the is-checked value.

value_format: Union[str, Callable[[Any], str]]

Base GUI

Module containing the Base GUI class.

This class should be extended to make your own GUI.

class twinpy.ui.base_gui.BaseGUI(actuator: Optional[twinpy.twincat.simulink.SimulinkModel] = None, controller: Optional[twinpy.twincat.simulink.SimulinkModel] = None, **kwargs)[source]

Bases: twinpy.ui.base_gui.TcMainWindow

Base TwinCAT GUI, specific for the WE2 actuators and controller model.

Extends this class if you want to use those models. For other models, using twinpy.ui.TcMainWindow might be more appropriate.

Parameters
  • actuator – The WE2_actuators model (or a derivative)

  • controller – The WE2_controller model (or a derivative)

  • kwargs

closeEvent(event)[source]

Callback when window is closed.

on_drives_enabled_change(enabled_list: List[float])[source]

An additional callback for the drive state change.

Manual callback instead of TcWidget symbol connection so we can also change button state and label color.

class twinpy.ui.base_gui.TcMainWindow(**kwargs)[source]

Bases: PyQt5.QtWidgets.QMainWindow

Parent class for TwinCAT GUIs.

Extends QMainWindow. The resulting window is empty, but will have a destructor that neatly closes any TcWidgets first.

To make it easier to navigate the different elements, adhere to:

  • Create objects as late as possible

  • Save objects as property only if that is really necessary

  • Name objects by elements starting with the most general item (e.g. ‘layout_group_drives’)

  • To save space, create a Layout directly with its parent widget:

    button_layout = QLayout(widget_parent)

    # widget_parent.addLayout(button_layout) # < Not needed now

Widgets consist of layouts. Layouts contain widgets.

closeEvent(event)[source]

On window close

find_tc_widgets() List[twinpy.ui.tc_widgets.TcWidget][source]

Find all children of the TcWidget type (recursively).

Base Widgets

These widgets are specific implementations of TcWidgets.

They are not intended to be overridden again. They are separate classes mostly because their specific logic became significant.

TcErrorsLabel

class twinpy.ui.TcErrorsLabel(*args, **kwargs)[source]

Bases: twinpy.ui.tc_widgets.TcLabel

Extension of TcLabel for a list of joint errors.

This is separate class because the amount of logic got a little bit much.

When clicking on the widget, a new window pops up showing the decoded errors.

Parameters
  • args

  • kwargs

Kwargs
  • format: Callback to format errors (default: show hexadecimal representation

    of error values

  • popup: Whether or not to enable a detailed popup window (default: True)

  • See TcLabel

static format_errors_list(error_list: List[int]) str[source]

Set text for errors label.

mousePressEvent(event: PyQt5.QtGui.QMouseEvent) None[source]

On clicking on the label.

QLabel does not have an on-click signal already.

static to_hex(value: int) str[source]

Create human-readable hex from integer.

twincat_receive(value)[source]

Callback on remote value change.

value_format: Union[str, Callable[[Any], str]]

Main - Example

Example of a script using a GUI.

You can run the BaseGUI itself (linked to the WE actuator model) by running

$ python -m twinpy

(I.e. by executing the module.) This provides a quick demo of how such a GUI can work, and a quick check to see everything is working on your system.

This script should not be used in your program! Instead, your application should have it’s own main script and create a GUI instance from there.

class twinpy.__main__.GUI(actuator: Optional[twinpy.twincat.simulink.SimulinkModel] = None, controller: Optional[twinpy.twincat.simulink.SimulinkModel] = None, **kwargs)[source]

Bases: twinpy.ui.base_gui.BaseGUI

Some extension of the BaseGUI.

Custom GUIs should extend the base class.

Parameters
  • actuator – The WE2_actuators model (or a derivative)

  • controller – The WE2_controller model (or a derivative)

  • kwargs

Module Info

TwinPy package.

author

Robert Roos <robert.soor@gmail.com>

license

MIT, see license file or https://opensource.org/licenses/MIT

created on

2021-01-08 16:13:00