pyopticon.generic_widget module

class pyopticon.generic_widget.GenericWidget(parent_dashboard, name, nickname, color, **kwargs)

Bases: object

This is the superclass for all widgets representing physical devices. It contains a lot of the machinery for generating GUI elements, setting up a serial connection, and logging data, so that subclass implementation is mostly defining the input/output fields and the serial communication protocol for a given instrument.

Parameters:
  • parent_dashboard (pyopticon.dashboard.PyOpticonDashboard) – The dashboard object to which this device will be added

  • name (str) – The name that the widget will be labeled with, and under which its data will be logged, e.g. “Methane Mass Flow Controller”

  • nickname (str) – A shortened nickname that can be used to identify the widget in automation scripts, e.g. “CH4 MFC”

  • color (str) – The color of the widget’s frame, as a RGB hex string, e.g. ‘#00FF00’

  • use_serial (bool, optional) – True if this widget needs to have a serial connection; False otherwise. Defaults to True.

  • default_serial_port (str, optional) – The name of the default selected serial port, e.g. ‘COM9’

  • default_serial_port – The name of the default selected serial port, e.g. ‘COM9’. Required unless no_serial is True.

  • baudrate (int, optional) – The baud rate of the serial connection, as an integer, e.g. 19200. Required unless no_serial is True or build_serial_object is overridden.

  • widget_to_share_thread_with (pyopticon.generic_widget.GenericWidget, optional) – A widget whose thread this widget will share, rather than creating its own. If use_serial = True, it’s assumed the widget will share the serial.Serial object.

  • update_every_n_cycles – Set the widget to poll its serial connection for updates every n cycles. Useful for instruments that poll slowly for some reason, or whose state changes infrequently. Defaults to 1.

on_failed_serial_open()

This function is called when the Dashboard attempts to open a Serial port and it fails for some reason. It can be used to set the readout fields to ‘None’ or something, if desired.

on_handshake()

This function gets called whenever the widget is initialized. If the widget uses a Serial connection, you can assume that the serial connection was already initialized successfully. If not, you’ll need to initialize whatever objects are needed to update the widget in this method (say, an OEM Python driver).

By default, it just calls on_update(), assuming that the handshake was successful if (and only if) no exception was raised.

on_update()

This function gets called once every polling interval when the dashboard prompts each device to update itself. It should be overridden in a subclass implementation; if not, it prints a warning.

on_confirm()

This function gets called whenever a widget’s ‘confirm’ button is pressed, which should result in a command (reflecting the latest entries in user input fields) getting sent through the serial connection. This method should be overridden in a subclass implementation, unless the widget has no user input fields. If it’s called without being implemented in the subclass, a warning is printed.

on_serial_close()

This function gets called whenever serial connections are closed. It should be overridden in a subclass implementation. Usually, this function sets readout fields to something like ‘no reading’ after serial communications are closed. Note that while the other user-defined methods run in the widget’s thread, this method runs immediately in the main GUI thread, ensuring that the serial connection closure happens immediately.

add_field(field_type, name, label, default_value=None, **kwargs)

Adds a field (i.e., a text entry box, a dropdown menu, or a text display) to the widget.

Adding a field is like making an instance variable for the widget, except 1) the GUI elements get autogenerated for you and 2) fields’ values are, by default, logged whenever the dashboard’s data logging is active. This method is meant to streamline adding input and output fields, though you can of course define your own instance variables, configure data logging, and add GUI elements by hand to the tkinter frame from widget.get_frame() if you want more granular control. Underlying each field is a tkinter StringVar bound to some tkinter GUI element.

If you add the first input field to a widget, a ‘Confirm’ button will also automatically be generated and placed. Use the move_confirm_button method to change its location.

Parameters:
  • field_type (str) – Valid options are ‘text output’, ‘text input’, ‘dropdown’, or ‘button’

  • name (str) – The name of the field, which will be used to identify it for automation and for data logging

  • label (str) – The text label that will appear to the left of the field. This may differ from the name if you want to include units or abbreviate the label; e.g., the name might be ‘Temperature’ and the label might be ‘Temp. (C)’. If this argument is ‘’ (an empty string), no label is added.

  • default_value (str) – The starting value that appears in the field

  • options (list, optional) – The options in the dropdown option menu. Required if field_type is ‘dropdown’, ignored otherwise.

  • log (bool, optional) – Whether or not to log this field’s contents when the dashboard’s data logging is active. Defaults to True.

  • custom_stringvar (tkinter.StringVar, optional) – If you want to pass a pre-existing tkinter StringVar to be bound to the field’s GUI element, rather than letting this method initialize a new one.

do_threadsafe(to_do)

Feeds the specified function to tkinter’s after() method with a delay of 0, so that it will be executed in a thread-safe way.

Parameters:

to_do (function) – The function to execute.

get_field(which_field)

Get the current value of the specified field.

Parameters:

which_field (str) – The name of the field whose value to get.

Returns:

The current value of the specified field

Return type:

str

set_field(which_field, new_value, hush_warning=False)

Set the value of the specified field to a specified value.

Parameters:
  • which_field (str) – The name of the field whose value to set.

  • new_value (str) – The value to which to set the specified field.

  • hush_warning (True) – Silence the warning when you set a field while a widget’s serial isn’t connected.

log_data()

Generate a dict of data that is sent to the dashboard’s data logging script. The dict contains the current values of all fields that were created using add_field with the option log=True. This method may be overridden in a subclass if you would like to do some kind of preprocessing on data before it’s logged, e.g. stripping out units or typecasting to int or float.

Returns:

A dict of the widget’s loggable fields and their current values

Return type:

dict

disable_field(which_field)

Grey out an input field so that it can’t be interacted with.

Parameters:

which_field (str) – The name of the field that will be greyed out.

enable_field(which_field)

Un-grey out an input field that had previously been greyed out, allowing it to be interacted with again.

Parameters:

which_field (Str) – The name of the field to re-enable.

move_confirm_button(row, column)

Move the confirm button, which is automatically placed when using the add_field method to add an input field.

Parameters:
  • row (int) – The row at which to place the confirm button, indexed from 0

  • column (int) – The column at which to place the confirm button, indexed from 0

override_color(new_color)

Manually change the color of a widget’s frame to something besides its default defined in its constructor.

Parameters:

new_color (str) – The new color, in hex, e.g. ‘#FF00FF’

_run_thread()

Launch a thread to process commands from the widget’s queue. The thread just keeps checking for new commands in its queue forever until the close flag is set. Valid commands are ‘UPDATE’, ‘HANDSHAKE’, and ‘CONFIRM’.

_shutdown_thread()

Shutdown the widget’s thread once the GUI is closed.

_build_serial_object()

This function just calls get_serial_object and assigns its value to self.serial_object

confirm()

Method executed when the Confirm button is pressed. Checks whether serial is connected and unfocuses any input field that’s focused, then calls the on_confirm method that is hopefully defined in a subclass.

_on_confirm()
_update()

Executes every time the widget is prompted to update. Checks whether to update this cycle, checks whether serial is connected, and then calls the on_update method that is hopefully defined in a subclass implementation.

_handshake()

Builds the serial object, if needed, and prompts the widget to handshake with the device, handling errors as needed.

close_serial()

Closes the serial object, if needed, and returns the GUI fields to their default non-connected states. Executes on_serial_close, which is hopefully implemented in a subclass.

get_serial_object()

Get the serial object that this widget is using

Returns:

This widget’s serial object, which is probably a Pyserial Serial object.

Return type:

serial.Serial

show_serial()

Show the serial port selector and status GUI elements, if they were hidden

hide_serial()

Hide the serial port selector and status GUI elements

update_serial_ports(new_serial_options)

Update the dropdown list of available serial ports

Parameters:

new_serial_options (list) – The new list of available serial ports

get_frame()

Get the tkinter frame on which this object is drawn.

Returns:

The widget’s tkinter frame

Return type:

tkinter.Frame