dtlibs.qt Classes

QXActions

class dtlibs.qt.QXActions(parent[, *args])

Create a new actions group.

Parameters:
  • parent – The parent widget of all created QActions.
  • args – List of classes to scan for actions. If omitted, then the parent is used.
Seealso:

actions

getAction(self, name)

Return an action by searching for name. The search is case-insensitive and ignores all occurrences of ‘&’ and leading and trailing whitespace.

group(self, *args)

Group existing actions into menus. The arguments supplied defined how the actions are grouped, An even number of arguments are expected, in the form:

group('group1', [list-of-action-names], 'group2', ...)

The first of every pair of arguments is the name of the menu, and the second is a list of named actions. The list may contain similar group pairs, indicating nested menus, e.g.:

group('group', ['subgroup', [list-of-actions]])

If an item in the list evaluates to False, then a separator is added. For example, each of the the following commands insert a separator between ‘New’ and ‘Open’:

group('File', ['New', '', 'Open])
group('File', ['New', None, 'Open])
group('File', ['New', False, 'Open])

Action names are compared to the text property of the action. Leading and trailing whitespace are stripped, any occurence of ‘&’ is removed and case is ignored. So 'New' and ' &new ' match.

menubar()

Return a QMenuBar containing the grouped actions.

toolbars()

Return a list of QToolbars containing the grouped actions.

QXAppendProxyModel

class dtlibs.qt.QXAppendProxyModel([recordFactory=None, model=None])

This proxy model provides an interface to append rows.

Parameters:
  • recordFactory – A callable which converts a dict into a record as used by the source table model. Be default, the dict is returned unchanged.
  • model – The source model for the proxy model.

For the most part, data is mapped straight the source model. However, this model always provides an additional empty row at the end which can be used to enter new data. Every time the data is changed in this row, the source model’s addRecord method is called with a single argument, the return value of recordFactory.

The source model must supply a field method which returns a QXField object for a column, and an addRecord method which accepts a record. Records are created by recordFactory(), which can be set to any function that will convert a dict into a new record object. If no exceptions are raised while creating and adding the record, the addition is assumed to be successful. ValueError exceptions should be used to indicate failure and they will be silently ignored (although an information message will be logged.) The source model is not responsible for emitting rowsInserted and related signals.

recordFactory()

Return the factory used to create new records.

setRecordFactory(value)

Set the record factory.

clear([column=None])

Clear pending data in column. If column is None, then clear everything.

flags(index)

Return the source model’s flags for all but the last row. The last row returns ItemIsEnabled and, for those columns which are not readonly, ItemIsEditable.

QXApplication

class dtlibs.qt.QXApplication([args])

A singleton subclass of QApplication.

Basic usage of this class is the same as for QApplication, but it also supports a few extra features:

  1. If no arguments are specified in the constructor, sys.argv is used. This allows it to be initialised without arguments.

    >>> app = QXApplication()
    
  2. It is a singleton, meaning that it only every has one instance. Combines with the optional constructor arguments, this allows the following sort of usage.

    >>> app = QXApplication()
    >>> app.setApplicationName('MyApp')
    >>> QXApplication().applicationName()
    'MyApp'
    >>> QXApplication() is QXApplication()
    True
    >>> QXApplication() is app
    True
    
  3. It recognises the main window for an application. This allows global functions, such as message to use it as a parent.

    >>> app = QXApplication()
    >>> win = 'a widget'
    >>> app.setMainWindow('a widget')
    >>> app.mainWindow()
    'a widget'
    
  4. It is automatically created when qt is imported, to ensure that there is always a running application

  5. The application provides support for saving and restoring settings through QSettings. QSettings requires that the organisation and application names are set, so for convenience, the organisation is set to ‘dtlibs’ by default. The first time QXApplication.settings is called, a new instance of QSettings is created. A new instance is also created whenever it is called with arguments.

mainWindow()

Return the main window, or None if it has not been set.

setMainWindow(value)

Set the main window to value.

settings([organisation=None, application=None])

Return a QSettings instance for this applications settings.

On the first call to this function, and every other call with arguments, a new QSettings instance is created. If either argument is None then the application properties organisationName and applicationName are used. If organisation and application are omitted or None and the method has already been called, the previously created QSettings instance is returned.

saveGeometry(window[, name])

Save the geometry of window. name is the section name to save the settings under. If it is omitted, the window’s objectName property is used.

restoreGeometry(window[, name])

Restore the geometry of window. name is the section name under which the settings are saved. If it is omitted, the window’s objectName property is used. If no settings have yet been saved, this does nothing and returns False.

saveState(self, obj[, name])

Save the state of obj by calling obj.saveState. name is the section name under which to save the settings. If it is omitted, the objects’s objectName property is used.

restoreState(self, obj[, name])

Restore the state of obj by calling obj.restoreState. name is the section name under which the settings are saved. If it is omitted, the object’s objectName property is used. If no settings have yet been saved, this does nothing and returns False.

addStateObject(self, obj[, name])

Register an object as having a saveable state. If the object has already been added, then the name is updated.

addStateObjects(self, objects):

Register a dict of objects as having a saveable state.

saveStates()

Save the state of all objects registered through addStateObject.

restoreStates()

Restore the state of all objects registered through addStateObject.

QXDateTimeDelegate

class dtlibs.qt.QXDateTimeDelegate(parent[, fmt, usetime=False])

A delegate for datetime values.

Parameters:
getWidget(parent, option, index)

Return a QXStdDateEdit or QXStdDateTimeEdit depending whether usetime is True.

QXDocument

class dtlibs.qt.QXDocument

A class representing the state of a single document.

This framework provides methods for working with documents and files, specifically dealing with operations such as opening and saving them. The QXDocument class should be inherited to create a new type of document, and newDocument(), openDocument(), saveDocument() and closeDocument() reimplemented.

Acceptable file filters are stored using setSaveFilters() and setOpenFilters, and are in the same format as used by QFileDialog.filters, e.g., "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)

The new, open, save, saveAs and close methods of this class are defined with __info__ (see dtlibs.core.info), and are set up to be used with QXActions.

documentOpened

Signal emitted when a document is opened

documentClosed

Signal emitted when a document is closed

saveFilters()

Return a list of filters to use in the save file dialog.

setSaveFilters(filters)

Set a list of filters to use in the save file dialog.

openFilters()

Return a list of filters to use in the open file dialog.

setOpenFilters(filters)

Set a list of filters to use in the open file dialog.

name()

Return the name of the currently opened file.

This returns the name portion of the full path. If no named file is opened, an empty string is returned. Note that an empty return value does not mean that the document is empty; a new one may be open which has not yet been saved.

fullName()

Return the full name of the currently opened file.

path()

Return the folder path to the currently opened file.

ext()

Return the extension of the currently opened file.

isOpen()

Return true if there is a currently open document.

saveDocument(path)

Save a document to disk and return True success.

This method should be re-implemented by subclasses and should perform the necessary operations to write the document data to path. All GUI operations, such as querying the name are handled prior to calling this function, but no checks are made as to whether path exists or is accessible. It is recommended that dtlibs.xos.safewriter() be used instead of open(), since it handles failure and race conditions.

If the undo framework is used, then undo.Stack.savepoint should be called here to set the savepoint.

The default implementation does nothing and returns True.

openDocument(path)

Load a document into memory by name and return True for success.

This method should be re-implemented by subclasses and should perform the necessary operations (i.e. opening the file, locking it, etc) to load the document data from path. All GUI operations, such as querying the name are handled prior to calling this function, but no checks are made as to whether path exists or is accessible.

The default implementation does nothing and returns True.

newDocument()

Initialise a new, empty document and return True for success.

This method should be re-implemented by subclasses and should perform the necessary operations to create new document data. Before this is called, QXDocument ensures that there is no open document, so document data can be assumed to be in the default state, or as left by closeDocument().

The default implementation does nothing and returns True.

closeDocument()

Close an open document and return True for success.

This method should be re-implemented by subclasses and should perform the necessary operations to clear document data. Operations such as saving the document are handled prior to calling this function, so it can be assumed that it is safe to clear the data.

The default implementation does nothing and returns True.

new()

Create a new document.

This method should be called by the GUI when a new document is required. It checks if a document is already open, and if so gives the option to save it and close it. It then calls newDocument to do any initialisation needed. True is returned on success.

open()

Open an existing document.

This method should be called by the GUI to open an existing document. It first checks if a document is already open, and if so gives the option to save it and close it. It then uses QFileDialog to get the filename of the document and calls openDocument to open it. True is returned on success.

save()

Save an open document.

This method should be called by the GUI to save the current document. If there is no open document, it does nothing and returns False. If the current document has a name, it is saved silently, otherwise saveAs is called. True is returned on success.

saveAs()

Save an open document under a new name.

This method should be called by the GUI to save the current document with a new name. If there is no open document, it does nothing and returns False. QFileDialog is used to get the new name, and saveDocument is called to write it. True is returned on success.

close()

Close an open document.

This method should be called by the GUI to close the current document. If there is no open document, it does nothing and returns False, otherwise it asks whether to save it first, and if so calls save. It then calls closeDocument to perform any closing actions required. True is returned on success.

QXDocumentWindow

class dtlibs.qt.QXDocumentWindow([document=None])

This is a QMainWindow subclass designed specifically to integrate with a QXDocument instance, and is often used as the main application window.

Subclasses should reimplement openGUI and closeGUI to update the interface with a document is opened or closed.

setDocument(document)

Set the QXDocument instance handled by the window.

document()

Return the QXDocument instance handled by the window.

openGUI()

Called immediately after a document is sucessfully opened. This should be reimplemented by subclasses. The default implementation does nothing.

closeGUI()

Called immediately after a document is sucessfully opened. This should be reimplemented by subclasses. The default implementation does nothing.

addSimpleDockWidget(title, widget)

Add a QDockWidget with a single child widget. The new dock widget is returned.

This method is the same as:

dock = QDockWidget(title)
dock.setObjectName(title)
dock.setWidget(widget)
mainwindow.addDockWidget(Qt.LeftDockWidgetArea, dock)
addToolBars(self, toolbars):

Add all toolbars to the window. This can conveniently be called with the output of QXActions.toolbars:

actions = QXActions(...)
actions.group(...)
self.addToolBars(actions.toolbars)

QXDropdownFilterModel

class dtlibs.qt.QXDropdownFilterModel(model[, column=0, role=Qt.DisplayRole])

A list model presenting filter options based on another model.

This is a list model which shows a the unique values in a column of another model. It also added a tristate “Select All” item, and makes all other checkable. This would comonly be used as the model of a combo or list widget to allow the user to filter out values from the original model. By default, all items are selected and any new ones added are automatically selected.

This is initialised from a parent model containing data in column which is presented in the filter. role sets the ItemRole to use for reading values.

When the filter changes, a filterChanged signal is emitted with a set of unselected values.

filterChanged(values)

This signal is emitted with a set of unselected values when the filter changes

sourceDataChanged()

This slot is connected to the source model’s dataChanged signal.

aboutToReset()

Called before rows in the source model are added or removed.

reset()

Called after rowas in the source model are added or removed.

sourceItems()

Return a sorted list of unique items in the source model.

selectedState()

Return the check state of the Select All option

QXField

class dtlibs.qt.QXField(name[, readonly, default, title, enum, calc, alignment])

Control a column in a QXTabularModel.

The purpose of a field is to control how data is displayed, edited, validated and stored for a single column in the table. Fields are identified by a name. The name should be a valid python identifier, and should be unique in the table. The field name is also used by the parent model to look up values in the backend datastore.

QXField objects have several writable properties which define them, all of which can be set as constructor keyword arguments.

Property Default Notes
readonly False  
default None  
alignment Left One of the Qt alignment flags, used for display.
title name The value displayed in table headers
enum None This may be set as either a list or callable which returns a list. In both cases, field.enum returns a list.
calc None A callable which converts a returns the calculated value in the field given a record.

For convenience, the following alignment flags are defined as class attributes:

TopLeft
TopCenter
TopRight
Left
Center
Right
BottomLeft
BottomCenter
BottomRight
editFormat(value)

Convert value to an editable format for this field.

value is the actual value. The default behaviour is to convert value to a dtlibs.xcollections.SelectList if enum is not None, or to return value unchanged.

displayFormat(value)

Convert value to a display format for this field.

Numbers are not converted to strings. This is the responsibility of the delegate.

valueFormat(editValue)

Convert from edit format to stored format. Depending on the source of editValue, it may be text regardless of the expected type. This method should handle any type conversions necessary.

QXFloatDelegate

class dtlibs.qt.QXFloatDelegate(parent[, prefix='', decimals=None, suffix=''])

A delegate for float values.

Parameters:
  • prefix – A text prefix to add to numbers displayed, and strip from numbers entered.
  • decimals – The number of decimal places to use when displaying the number. If omitted, then all decimals are shown.
  • suffix – A text suffic to append to numbers displayed, and strip from numbers entered.

For example:

>>> widget = QWidget()
>>> dg = QXFloatDelegate(widget, '$ ', 1, ' million')
>>> dg.displayText(12.345678, None)
'$ 12.3 million'
getWidget(parent, option, index)

Return a QXStdFloatEdit with decimals set as in the constructor.

QXListDelegate

class dtlibs.qt.QXListDelegate(parent)

A delegate for option lists.

When using this delegate, the model’s data method is expected to return a SelectList object for EditRole and a string for DisplayRole.

getWidget(parent, option, index)

Return a QXStdOptionsBox.

QXSortFilterProxyModel

class dtlibs.qt.QXSortFilterProxyModel

Applies per column filtering to QSortFilterProxyModel.

This behaves almost exactly the same as QSortFilterProxyModel, but allows separate filters for each column. Also, the filters are callables which take a value and return True (display) or False (hide).

setFilter(column, func[, role=Qt.DisplayRole])

Assign a filter function to a column.

QXStdCheckBox

class dtlibs.qt.QXStdCheckBox([value=False, parent=None])

A standard check box implementing QXStdWidgetABC

Inherits: QLineEdit
Datatype: bool

None is an acceptable value for setValue and getValue and indicates that the check box is partially checked.

QXStdComboBox

class dtlibs.qt.QXStdComboBox([value='', parent=None])

An editable combo box implementing QXStdWidgetABC which reports on the current text.

Inherits: QComboBox
Datatype: str

None is an acceptable value for setValue and is converted to an empty string. None is returned by getValue if no index is selected.

QXStdDateEdit

class dtlibs.qt.QXStdDateEdit([value=None, parent=None])

A standard date edit widget implementing QXStdWidgetABC.

Inherits: QDateEdit
Datatype: datetime.date

None is an acceptable value for setValue and is converted to the default date used by QDateEdit. None is never returned by getValue.

QXStdDateTimeEdit

class dtlibs.qt.QXStdDateTimeEdit([value=None, parent=None])
A standard date and time edit widget implementing QXStdWidgetABC.
Inherits: QDateTimeEdit

None is an acceptable value for setValue and is converted to the default value used by QDateTimeEdit. None is never returned by getValue.

QXStdFloatEdit

class dtlibs.qt.QXStdFloatEdit([value=None, parent=None, decimals=None])

A standard line edit widget for floats implementing QXStdWidgetABC.

Inherits: QLineEdit
Datatype: float

If given, decimals sets the number of decimals to round the value to.

None is an acceptable value for setValue and is converted to an empty string. None is returned by getValue if the value cannot be converted to a float.

QXStdIntEdit

class dtlibs.qt.QXStdIntEdit([value=None, parent=None])

A standard line edit widget for integers implementing QXStdWidgetABC

Inherits: QLineEdit
Datatype: int

None is an acceptable value for setValue and is converted to an empty string. None is returned by getValue if the value cannot be converted to an integer.

QXStdOptionsBox

class dtlibs.qt.QXStdOptionsBox([value=None, parent=None])

A combo box which allows a single selection from a list of options.

Inherits QComboBox

None is an acceptable value for setValue and is converted to an empty SelectList. None is never returned by getValue. The SelectList passed to setValue is copied and the selected option tracked by index. This means that non-string types in setValue will be returned by getValue intact.

QXStdTextEdit

class dtlibs.qt.QXStdTextEdit([value='', parent=None])

A standard line edit for strings implementing QXStdWidgetABC.

Inherits: QLineEdit
Datatype: str

None is an acceptable value for setValue and is converted to an empty string. None is never returned by getValue.

QXStdWidgetABC

class dtlibs.qt.QXStdWidgetABC

Define the API of a standard editing widget.

Qt has many widgets which behave in a very similar manner, but have slightly different APIs. An example is QLineEdit and QCheckBox. Both of these represent a single piece of data and support read and write operations. However, QLineEdit does this through text() and setText() methods while QCheckBox uses checkState() and setCheckState(). These method names are very descriptive, but make generic programming for unknown widgets quite complicated. dtlibs.qt solves this by providing subclasses of the regular PyQt4 widgets with a defined API.

Each widget supports a specific set of types, defined by its types class method. They may also handle and return None, which indicates an invalid value. It is up to the subclass implementation to deal with type checking and conversions. While all of these classes support setting the value to None, they do not necessarily have to return None. This behaviour depends on the specific class.

valueChanged

This signal is emitted whenever the value changes. It is similar to the textChanged signal in a QLineEdit.

emitValueChanged()

Called by subclasses to raise the valueChanged signal.

getValue()

Return the value of the widget. This is similar to QLineEdit.text.

setValue(value)

Set the value of the widget. This is similar to QLineEdit.setText.

classmethod types()

Return a list of types supported by the widget.

QXTableView

class dtlibs.qt.QXTableView([*proxies, parent=None])

This is an extension to QTableView with the following changes:

  • The default delegate is QXTypedDelegate.
  • The default row height is 1.5 times the text height.
  • selectionMode is set to ContiguousSelection.
  • When editing on a cell is complete, the current cell moves down one row.

In addition, the following new features are added:

  • Hooks can be used to notify the model when it is applied to the view. When a model is set, its setView method is called, if it exists. Similarly, unsetView is called when the model is removed from the view.

  • Copy and paste support is provided by the view through copy, and paste methods.

  • A new signal, currentRowChanged is emitted by the view when the row changes.

  • The view can be pre-configured to use a list of proxy models, specified in the order in which they should be applied. When setModel is called, the proxies will be inserted in the order they are given. For example, if the proxies are given as (proxy1, proxy2) then setModel(model) results in the following actions:

    super().setModel(proxy1)
    proxy1.setSourceModel(proxy2)
    proxy2.setSourceModel(model)
    

    Note that setView and unsetView will be called on the model actually set to the view, i.e. the first proxy.

currentRowChanged(newIndex, oldIndex)

This is emitted after the current row changes in the view.

copy()

Copy the selected cells to the system clipboard.

copyRole()

Return the ItemRole used in the model’s data method when copying data.

nextCell()

Move the current row to the next cell down if possible. Otherwise, this does nothing.

paste([text])

Paste tab-separated data into the table, overwriting existing.

The data is written to each cell using model().setData(), with the role specified in pasteRole. Note that no data conversion is done and all the data is pasted as text.

The exact operation of this depends on the selection: If a range of cells is selected, then pasteToSelection is used. If nothing is selected, pasteAll is used.

If text is not specified, the contents of the system clipboard are used.

pasteAll(data)

Paste data to the current index, filling down and right.

data is an iterable of rows, each row being an iterable of columns. As much of the data is pasted as possible, filling down and right from the current index. Pasting stops either when rows and columns run out or when the data runs out. It is pasted a row at a time, and a check is made after each row to determine if there is space for more. This allows QXAppendProxyModel to be used to append new rows.

pasteRole()

Return the ItemRole used in the model’s setData method when pasting data.

pasteToSelection(data)

Paste data to overwrite the selected indexes.

data is an iterable of rows, each row being an iterable of columns. The data is pasted to fill the selected range, repeating as necessary. The selection is assumed to be contiguous between the smallest and largest selected indexes.

restoreState(state)

Restore the state of the view from state. This is typically taken directly from QXApplication.restoreState.

saveState()

Return the state of the object to save. This is typically passed directly to QXApplication.saveState.

setColumnWidth(column, width)

Sets the width of the given column to the width specified.

width may be a string, in which case the width set to the width of the string painted in the QXTableView’s font.

setCopyRole(value)

Set the ItemRole used in the model’s data method when copying data.

setPasteRole(value)

Set the ItemRole used in the model’s setData method when pasting data.

setProxyModels(*models)

Set proxy models which will be used in this view.

QXTabularModel

class dtlibs.qt.QXTabularModel(records)

This model works on the principal that the table consists of records and fields, where each record is an object representing a unit of information and each field defines the type and representation of data stored in it. Each record is a single python object, and the default behaviour assumes that its field data are accessible using attribute lookup on the field name. This can be overridden by setting valueGetter. The simplest form of a record is a nameddict, but is usually a custom object of some sort.

Each column is represented by a QXField object defining how the data should be handled. The field does not actually know anything about the data itself.

When this model is instantiated, it is provided with a source of data which is a mutable sequence containing individual records. Records can be added to the model using addRecord or deleted using deleteRow, and propagates to the underlying data source.

The data for the following example is stored as a list of named tuples.

>>> from dtlibs.xcollections import nameddict
>>> Record = nameddict('Record', 'id name age')
>>> data = [Record(id=1, name='Eric', age=43),
...         Record(id=2, name='Matt', age=19)]

The first field (id)is readonly, and the last field (age) should have a default of 0.

>>> fields = [QXField('id', readonly=True),
...           QXField('name'),
...           QXField('age', default=0)]

The model is then created using this information.

>>> model = QXTabularModel(data)
>>> model.setFields(fields)

Now we can check that the model does contain the data it was initialised with.

>>> model.rowCount()
2
>>> model.columnCount()
3
>>> model.data(model.index(0, 1), Qt.DisplayRole)
'Eric'
>>> bool(Qt.ItemIsEditable & model.flags(model.index(0, 0)))
False

The age of Matt can be changed to 20, a new row can be added, and the first row deleted.

>>> model.setValue(model.index(1, 2), 20)
>>> newindex = model.addRecord(Record(id=3, name='Peter', age=35))
>>> model.deleteRow(0)

The original data list will reflect these changes

>>> for row in data:
...     print(row.id, row.name, row.age)
2 Matt 20
3 Peter 35
valueGetter()

Return a callable which returns the value given a record object and field name. By default it is getattr.

setValueGetter()

Set a callable which returns the value given a record object and field name.

pauseRowSignals()

Return a context manager which suppresses all insert row signals.

setFields(fields)

Set the fields to be displayed. fields must be a list of instances of QXField objects.

fields()

Return a tuple of the QXField objects displayed.

fieldnames()

Return a tuple of the field names displayed.

field(column)

Return the Field object for a column.

column(field)

Return the number of the column containing field. field can be either a field name or QXField instance.

record(row)

Return the record at a row.

row(record)

Return the number of the row containing record.

value(index)

Return the actual value stored at index.

setValue(index, editValue):

Set the value in the record at index. If the field is read-only or the value is unchanged, then a ValueError is raised. If the value is successfully changed, the dataChanged signal is emitted.

This method supports the undo framework.

addRecords(records)

Append a list of record to the model.

The return value is the index of the first column in the first added row. If the append fails, a ValueError is raised.

This method supports the undo framework.

addRecord(record)

Append a record to the model.

The return value is the index of the first column in the added row. If the append fails, a ValueError is raised. This should be called within any subclass implementations,

This method supports the undo framework.

deleteRow(row)

Remove a row by row number.

This method supports the undo framework.

QXTypedDelegate

class dtlibs.qt.QXTypedDelegate(parent)

A delegate which handles various python types.

Subclasses should provide at least an implementation of getWidget, which returns a new instance of a widget to use for editing. The delegate removes the widget frame for better style consistency.

The default implementation allows the widget to be set by the model using Qx.WidgetRole and falls back on guessing the widget based on the data type returned by EditRole, using guessWidget. If the data type is known, however, it is better to use one of the strictly typed delegates, QXFloatDelegate, QXDateTimeDelegate or QXListDelegate.

getWidget(parent, option, index)

Return the widget to use for editing.