Source code for schrodinger.ui.qt.layout

"""
Contains helpers for creating layouts.

Copyright Schrodinger, LLC. All rights reserved.

"""

#- Imports -------------------------------------------------------------------

from schrodinger.Qt import QtWidgets

#- Globals -------------------------------------------------------------------

STRETCH = 0
ROW_SPAN = 1
COL_SPAN = 2

#- Functions -----------------------------------------------------------------


[docs]def get_widgets(layout): """ Helper function to generate each widget in the supplied layout. """ for i in range(layout.count()): yield layout.itemAt(i).widget()
def _add_to_layout(obj, layout, *args, **kwargs): """ Cycles through adding to a layout. First it tries to add the `obj` as a widget, then as an item and finally as a layout. """ try: layout.addWidget(obj, *args, **kwargs) except TypeError: try: layout.addItem(obj, *args, **kwargs) except TypeError: # If an error occurs here let QT raise the error layout.addLayout(obj, *args, **kwargs) def _apply_box_settings(layout, objects, margins=None, spacing=5): """ Private function to apply common settings to a `QtWidgets.QHBoxLayout` or `QtWidgets.QVBoxLayout` object. :param objects: Objects (widget, item, layout) to add :type objects: mixed (list or single object) :param stretch: Whether or not to add a stretch to the end of the layout :type stretch: bool :param margins: Margins used in `QtWidgets.QHBoxLayout.setContentsMargins` :type margins: tuple """ if not isinstance(objects, (list, tuple)): objects = [objects] margins = margins or (-1, -1, -1, -1) layout.setSpacing(spacing) layout.setContentsMargins(*margins) for obj in objects: if obj == STRETCH: layout.addStretch() else: _add_to_layout(obj, layout) return layout
[docs]def vbox(objects, margins=None, spacing=5): """ Function used to create a `QtWidgets.QVBoxLayout` object. :param objects: Objects (widget, item, layout) to add :type objects: mixed (list or single object) :param margins: Margins used in `QtWidgets.QHBoxLayout.setContentsMargins` :type margins: tuple """ layout = QtWidgets.QVBoxLayout() hbox_layout = _apply_box_settings(layout, objects, margins, spacing) return hbox_layout
[docs]def hbox(objects, margins=None, spacing=5): """ Function used to create a `QtWidgets.QHBoxLayout` object. :param objects: Objects (widget, item, layout) to add :type objects: mixed (list or single object) :param margins: Margins used in `QtWidgets.QHBoxLayout.setContentsMargins` :type margins: tuple """ layout = QtWidgets.QHBoxLayout() hbox_layout = _apply_box_settings(layout, objects, margins, spacing) return hbox_layout
[docs]def grid(objects, stretch=False, margins=None, hspace=5, vspace=5): """ Function used to create a `QtWidgets.QGridLayout` object. The `objects` is a list of objects that will populate the grid. The grid's row count will equal the length of `objects` and it's column count will equal the length of the row with the most items. If you want to skip a column, set it to `None`, and if you want a column to span multiple columns add a `schrodinger.application.bioluminate.layout.ROW_SPAN` to all the preceding columns you want it to occupy. Example:: `objects = [ [ layout.ROW_SPAN, layout.ROW_SPAN, label, None, line_edit], [ double_spinner, push_button, line_edit ] ] grid = layout.grid(objects) ` The above will return a grid layout like:: -------------------------------------------------------------- | label | | line_edit | ------------------------------------------------------------- | double_spinner | push_button | line_edit | | | -------------------------------------------------------------- :param objects: Objects (widget, item, or layout) to add to a single `QtWidgets.QGridLayout` :type objects: list of lists """ margins = margins or (-1, -1, -1, -1) grid_layout = QtWidgets.QGridLayout() # Set the columns up so that blank columns still take space up. # This keeps the layout much cleaner if objects are dynamic col_lens = [len(a) for a in objects] #for i in range(0,max(col_lens)): # grid_layout.setColumnMinimumWidth(i, 50) grid_layout.setHorizontalSpacing(hspace) grid_layout.setVerticalSpacing(vspace) grid_layout.setContentsMargins(*margins) for i, row in enumerate(objects): row_span = 1 # We do not support column spans yet but we still need to add # the variable for when we call _add_to_layout col_span = 1 for j, wid in enumerate(row): if wid is None: continue if wid == ROW_SPAN: row_span += 1 continue j -= (row_span - 1) _add_to_layout(wid, grid_layout, i, j, row_span, col_span) row_span = 1 col_span = 1 return grid_layout