Welcome to qtypy’s documentation!¶
Application¶
Overview¶
qtypy.app.Application
- Application class
Settings¶
Overview¶
qtypy.settings.Settings
:- Pythonic wrapper for QSettings
Example¶
from qtypy.settings import Settings
settings = Settings()
with settings.grouped('Geometry'):
mainWindowGeometry = settings.value('MainWindow') if 'MainWindow' in settings else None
for item in settings.array('RecentFiles'):
self.addRecentFile(item.value('Path'))
...
with Settings() as settings: # So that sync() is called on exit
settings.setValue('MainWindow', mainWindowGeometry)
with settings.array('newarray') as items:
for path in self.recentFiles():
items.add(Path=path)
Reference¶
Pythonic wrapper for QSettings
-
class
qtypy.settings.
Settings
[source]¶ Settings class. You can also use this as a context manager so that sync() is called on exit.
-
grouped
(name)[source]¶ Context manager to enter a settings group. So instead of doing
settings.beginGroup('spam') try: ... finally: settings.endGroup()
you can do
with settings.grouped('spam'): ...
-
array
(name)[source]¶ Array support. This is used both to read a settings array (through iteration) and to write to it (using with). Example of reading:
for item in settings.array('myarray'): spam = item.value('spam') eggs = item.value('eggs')
is equivalent to:
for index in range(settings.beginReadArray('myarray')): spam = settings.value('spam') eggs = settings.value('eggs') settings.endArray()
Example of writing:
with settings.array('myarray') as items: items.add(spam='spam', eggs='eggs') items.add(spam=42, eggs=13)
is equivalent to:
settings.beginWriteArray('myarray') settings.setArrayIndex(0) settings.setValue('spam', 'spam') settings.setValue('eggs', 'eggs') settings.setArrayIndex(1) settings.setValue('spam', 42) settings.setValue('eggs', 13) settings.endArray()
-
Layout utilities¶
Overview¶
qtypy.layout.LayoutBuilder
:- Stacking layouts with context managers.
Examples¶

#!/usr/bin/env python3
from PyQt5 import QtCore, QtWidgets
from qtypy.layout import LayoutBuilder
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
builder = LayoutBuilder(self)
with builder.vbox() as vbox:
vbox.addWidget(QtWidgets.QLabel('Title'))
with builder.hbox() as hbox:
hbox.addStretch(1)
hbox.addWidget(QtWidgets.QPushButton('OK')).clicked.connect(self.onOK)
hbox.addWidget(QtWidgets.QPushButton('Cancel')).clicked.connect(self.onCancel)
self.show()
self.raise_()
def onOK(self):
print('== OK')
def onCancel(self):
print('== Cancel')
if __name__ == '__main__':
app = QtWidgets.QApplication([])
win = MainWindow()
app.exec_()
Reference¶
Utilities for working with layouts.
-
class
qtypy.layout.
LayoutBuilder
(target)[source]¶ Layout builder. Use this to ‘stack’ layouts using context managers. For instance, instead of
l1 = QtWidgets.QHBoxLayout() l1.addWidget(...) l2 = QtWidgets.QVBoxLayout() l2.addWidget(...) l2.addLayout(l1) self.setLayout(l2)
you can do
builder = LayoutBuilder(self) with builder.vbox() as l2: l2.addWidget(...) with builder.hbox() as l1: l1.addWidget(...)
The builder class takes care of adding each layout to its parent (defined in the outer context manager), and adding the top-level layout to the target widget.
Methods that create a layout (hbox, vbox, etc) take additional positional and keyword arguments that will be passed to the parent’s addLayout() method. Intermediate container widgets (when the top-level layout must be added to a QMainWindow for instance) are created automatically.
The returned layouts are actually proxies to actual layouts, with the addWidget() method returning the added widget. This allows call chaining without using an intermediate variable, for instance
hbox.addWidget(QtWidgets.QPushButton('OK')).clicked.connect(self.okSlot)
instead of
w = QtWidgets.QPushButton('OK') hbox.addWidget(w) w.clicked.connect(self.okSlot)
Model/view helpers¶
Overview¶
qtypy.model.PythonListModel
- A class that behaves both as a Python list and a QAbstractListModel.
qtypy.model.PythonTreeModel
- A tree model based on PythonListModel which may contain other PythonListModel instances.
qtypy.widgets.view.ColumnedView
A multi-columned view for PythonTreeModel.
qtypy.widgets.view.Column
- Base class for columns
qtypy.widgets.view.CheckableColumnMixin
- Mixin to make a column checkable
qtypy.widgets.view.EditableColumnMixin
- Mixin to make a column editable
qtypy.widgets.view.WidgetColumn
- Column that displays a widget, when all else fails
Examples¶

#!/usr/bin/env python3
from PyQt5 import QtCore, QtWidgets
from qtypy.settings import Settings
from qtypy.widgets.view import ColumnedView
from qtypy.model import PythonListModel
from qtypy.widgets.view import Column, WidgetColumn, CheckableColumnMixin, EditableColumnMixin
class Item(PythonListModel):
def __init__(self, n):
super().__init__()
self.n = n
self.checked = False
self.text = 'Edit me'
if n == 7:
for i in range(5):
self.append(Item(i))
class SimpleColumn(Column):
def __init__(self, name):
self._name = name
super().__init__()
def name(self):
return self._name
def id(self):
# For saveState/restoreState
return self._name
def labelForItem(self, item):
return 'Item #%d in col %s (%s)' % (item.n, self._name, item.text)
class CheckColumn(CheckableColumnMixin, SimpleColumn):
def checkState(self, item):
return QtCore.Qt.Checked if item.checked else QtCore.Qt.Unchecked
def setCheckState(self, item, state):
print('== Check state for item "%s": %d' % (self.labelForItem(item), state))
item.checked = state == QtCore.Qt.Checked
def appliesToChildrenOf(self, parent):
return parent is not None # Only for non-toplevel items
class EditColumn(EditableColumnMixin, SimpleColumn):
def value(self, item):
return item.text
def setValue(self, item, value):
print('== Set value for item "%s": %s' % (self.labelForItem(item), value))
item.text = value
def appliesToChildrenOf(self, parent):
return parent is not None
class ComboColumn(WidgetColumn):
def widgetFactory(self, item, parent):
combo = QtWidgets.QComboBox(parent)
combo.addItem('One')
combo.addItem('Two')
combo.addItem('Three')
return combo
def appliesToChildrenOf(self, parent):
return parent is not None # Only for non-toplevel items
class CustomView(ColumnedView):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.setStandardButtons(self.BTN_ADD|self.BTN_DEL)
self.addButtonClicked.connect(self._onAdd)
self.delButtonClicked.connect(self._onDel)
def _onAdd(self, selection):
if selection:
for item in selection:
item.append(Item(42))
else:
self.model().append(Item(42))
def _onDel(self, selection):
for item in selection:
parent = self.itemContainer(item)
if parent is not None: # The parent itself may already have been removed
parent.remove(item)
def createContextMenu(self):
# Column visibility menu
menu = QtWidgets.QMenu(self)
self.populateContextMenu(menu)
return menu
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
model = PythonListModel()
view = CustomView(model=model, parent=self)
view.addColumn(SimpleColumn('Basic')).setResizeMode(Column.Interactive)
view.addColumn(CheckColumn('Checkable')).setResizeMode(Column.Contents)
view.addColumn(ComboColumn('Widget')).setResizeMode(Column.Interactive)
view.addColumn(EditColumn('Editable')).setResizeMode(Column.Stretch)
self.setCentralWidget(view)
for n in range(10):
model.append(Item(n))
with Settings().grouped('model') as settings:
if 'state' in settings:
view.restoreState(settings['state'])
self.show()
self.raise_()
def closeEvent(self, event):
with Settings().grouped('model') as settings:
settings['state'] = self.centralWidget().saveState()
event.accept()
if __name__ == '__main__':
app = QtWidgets.QApplication([])
app.setApplicationName('qtypy example')
win = MainWindow()
app.exec_()
Reference¶
Models¶
Classes for Qt’s model/view programming, with a Pythonic touch.
-
class
qtypy.model.
PythonListModel
(parent=None, value=None)[source]¶ Python list-like object that implements QAbstractListModel. Most list operations like iterating, slicing, etc are supported except for
- reverse()
- sort()
- Slices with step
Items may define an itemDataChanged() signal, that is to be emitted whenever the item’s data changes.
-
class
qtypy.model.
PythonTreeModel
(model=None, parent=None)[source]¶ This is an implementation of QAbstractItemModel based on a
PythonListModel
. Elements of the list model that are themselves instances ofPythonListModel
will have children.
Views¶
-
class
qtypy.widgets.view.
ColumnedView
(model, parent=None)[source]¶ A multi-column view for a
PythonTreeModel
orPythonListModel
.-
BTN_ADD
= 1¶ Standard Add button
-
BTN_DEL
= 2¶ Standard Remove button
-
selectionChanged
= None¶ Signal emitted when the selection changes
-
addButtonClicked
= None¶ Signal emitted when the “Add” button is clicked; current selection is passed as argument.
-
delButtonClicked
= None¶ Signal emitted when the “Remove” button is clicked; current selection is passed as argument.
-
setStandardButtons
(buttons)[source]¶ Show standard buttons. The argument is an ORed combination of BTN_* values. The order and position of buttons will depend on the current platform’s HIG.
-
addButtonEnabled
(selection)[source]¶ Called to check if the ‘Add’ button should be enabled; return a boolean. The argument is a set of currently selected items (model objects). The default returns True.
-
delButtonEnabled
(selection)[source]¶ Called to check if the ‘Remove’ button should be enabled; return a boolean. The argument is a set of currently selected items (model objects). The default returns True if the selection is not empty.
-
saveState
()[source]¶ Returns a bytes object encapsulating the current state (column visibility, order, etc). You can save this in your settings and use it later to restore the state using restoreState.
-
restoreState
(state)[source]¶ Restore the state saved through saveState. If the versions do not match, nothing is done. Returns True if the state was restored.
-
addColumn
(column, visible=True)[source]¶ Append a column (instance of a
Column
subclass). Returns the column instance, for chaining.
-
createContextMenu
()[source]¶ This is called when then user right-clicks the view header. Return None for no context menu. You can use populateContextMenu to add actions to show/hide columns.
-
-
class
qtypy.widgets.view.
Column
[source]¶ Represents a column in a tree view. When you want to display data from a
PythonTreeModel
, use aColumnedView
and add instances of subclasses of this class to define columns.Various mixins are available for common behavior (checkable, editable, etc).
Constant values for setResizeMode:
Variables: - Interactive – Column is user-resizable
- Stretch – Column takes all available space
- Contents – Column is resized according to contents
-
nameChanged
= None¶ This signal should be emitted if the column name changes
-
id
()[source]¶ Return a persistent string identifier for this column; this is used by saveState/restoreState in ColumnedView.
-
setVisible
(visible)[source]¶ Sets the current column visibility. This must be called after the column has been added to a view.
-
setResizeMode
(mode)[source]¶ Sets the resize mode. Possible values are either class attributes Interactive, Stretch or Contents, or an integer for a fixed size.
Note
by default all columns are user-resizable, except for the last one which is stretched.
-
labelForItem
(item)[source]¶ Returns the text for this column for the given item. The default is to cast the item to str.
-
data
(item, role)[source]¶ Called when the model needs the item’s data for this column. Mixins override this and provide specific methods (like checkState() in
CheckableColumnMixin
).
-
setData
(item, role, value)[source]¶ Called when the item’s data for this column has been changed by the user and must be updated. Mixins override this and provide specific methods (like setCheckState() in
CheckableColumnMixin
).
-
class
qtypy.widgets.view.
EditableColumnMixin
[source]¶ Mixin to make a column editable with the default editor.
-
class
qtypy.widgets.view.
EditableTextColumn
(column_name, attr_name)[source]¶ Concrete column class to display an editable text attribute
-
class
qtypy.widgets.view.
CheckColumn
(column_name, attr_name)[source]¶ Concrete column class to display a checkbox
Tag list widget¶
Overview¶
qtypy.widgets.taglist.TagList
- A tag list widget
Examples¶

#!/usr/bin/env python3
from PyQt5 import QtCore, QtWidgets
from qtypy.widgets.taglist import TagList
from qtypy.model import PythonListModel
class StringListModel(PythonListModel):
def data(self, index, role):
text = super().data(index, QtCore.Qt.UserRole)
if role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole):
return text
def flags(self, index):
flags = super().flags(index)
if index.row() == 0:
return int(flags)
flags = int(flags | QtCore.Qt.ItemIsEditable)
if index.row() == 1:
pass
if index.row() in (2, 4):
flags |= TagList.ItemIsClosable
if index.row() in (3, 4):
flags |= TagList.ItemHasMenu
return flags
def setData(self, index, role, text):
self[index.row()] = text
class MyTagList(TagList):
def __init__(self, parent):
super().__init__(StringListModel(value=['read only', 'editable', 'deletable', 'menu', 'both']), parent)
cmpl = QtWidgets.QCompleter(['one', 'two', 'three', 'four'])
self.setCompleter(cmpl)
def addTag(self, text):
self.model().append(text)
def removeTag(self, index):
self.model().pop(index)
def popupMenu(self, index, pos):
menu = QtWidgets.QMenu(self)
menu.addSection(self.model()[index])
menu.addSeparator()
menu.addAction('Action #1')
menu.addAction('Action #2')
menu.popup(pos)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
container = QtWidgets.QWidget(self)
layout = QtWidgets.QFormLayout()
layout.addRow('Tags', MyTagList(self))
layout.addRow('Whatever', QtWidgets.QLabel('spam'))
layout.setFieldGrowthPolicy(layout.ExpandingFieldsGrow)
container.setLayout(layout)
self.setCentralWidget(container)
self.resize(800, 600)
self.show()
self.raise_()
if __name__ == '__main__':
app = QtWidgets.QApplication([])
win = MainWindow()
app.exec_()
Classes¶
Search widget¶
Overview¶
qtypy.widgets.search.SearchCtrl
- A search widget
Examples¶

#!/usr/bin/env python3
from PyQt5 import QtWidgets
from qtypy.widgets.search import SearchCtrl
from qtypy.layout import LayoutBuilder
class SearchWidget(QtWidgets.QWidget):
def __init__(self, parent):
super().__init__(parent)
bld = LayoutBuilder(self)
with bld.vbox() as layout:
search = SearchCtrl(self)
layout.addWidget(search)
echo = QtWidgets.QLineEdit(self)
layout.addWidget(echo)
echo.setReadOnly(True)
search.textChanged.connect(echo.setText)
search.addAction(QtWidgets.QAction('Action 1', self))
search.addAction(QtWidgets.QAction('Action 2', self), select=True)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setCentralWidget(SearchWidget(self))
self.show()
self.raise_()
if __name__ == '__main__':
app = QtWidgets.QApplication([])
win = MainWindow()
app.exec_()