Getting started

This page is a gentle introduction to the pyQode framework.

Before reading this, you should have pyqode.core and PySide/PyQt4/PyQt5 installed on your system.

Packages

Here is a brief overview of the content of pyqode.core and how to import it.

pyqode.core is made up of a series of subpackages. Each subpackage defines its own api (classes defined in a module of a subpackage are available at the subpackage level).

Here are the main subpackages:

  • api: contains the bases classes of the API
  • backend: classes for controlling the backend process
  • modes: contains all available modes
  • panels: contains all available panels
  • styles: contains a series of pygments styles specific to pyQode
  • widgets: contains a series of useful widgets.

Note

Not all subpackages are presented here, internal package or very specific one have been left out. You can read more about them in the API reference section.

To use pyQode, simply import one of those packages:

from pyqode.core import api
from pyqode.core import backend
from pyqode.core import modes
from pyqode.core import panels
from pyqode.core import widgets

# then you start using pyqode, e.g:
editor = api.CodeEdit()
editor.modes.append(modes.CodeCompletionMode())
editor.panels.append(panels.LineNumberPanel())

tabWidget = widgets.TabWidget()
tabWidget.add_code_edit(editor)

Selecting a Qt bindings

The first thing to do when using pyQode is to specify the Qt bindings you want to use in your application.

By default, pyQode will try to use PyQt5 and will fallback to PyQt4 or PySide in case of import errors. You can enforce the use of a specific bindings by setting up the QT_API environment variable.

For example, to use PySide:

import os
os.environ['QT_API'] = 'PySide'
from pyqode.core.qt import QtCore, QtGui, QtWidgets
print('Qt version:%s' % QtCore.__version__)
print(QtCore.QEvent)
print(QtGui.QPainter)
print(QtWidgets.QWidget)

Note

You can also use the qt package of pyqode.core to write a bindings independent application but you have to be aware that pyqode.core.qt does not wrap the entire Qt API (it only what was required to write pyQode).

The backend

pyQode is a client server API, the GUI side is called the frontend and the background process used to perfom heavyweight computation is called the backend.

When writing a pyQode application, you have to write both the frontend script and the backend script. Fortunately, writing the backend script is an easy task. All you have to do is to configure the server script (sys.path, workers,...) and call pyqode.core.backend.serve_forever()

Here is an example of server script:

from pyqode.core import backend

if __name__ == '__main__':
    backend.CodeCompletionWorker.providers.append(
        backend.DocumentWordsProvider())
    backend.serve_forever()

The frontend

Writing the pyqode frontend is not more complicated than writing the backend.

All you have to do is:

  1. create a pyqode.core.api.CodeEdit
  2. start the backend process
  3. configure CodeEdit
  4. open a file or set some text
  5. run the Qt main loop

Here is a simple example of a frontend script:

import sys
from pyqode.core import api
from pyqode.core import modes
from pyqode.core import panels
from pyqode.core.qt import QtWidgets


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    # create editor and window
    window = QtWidgets.QMainWindow()
    editor = api.CodeEdit()
    window.setCentralWidget(editor)

    # start the backend as soon as possible
    editor.backend.start('server.py')

    # append some modes and panels
    editor.modes.append(modes.CodeCompletionMode())
    editor.modes.append(modes.PygmentsSyntaxHighlighter(editor.document()))
    editor.modes.append(modes.CaretLineHighlighterMode())
    editor.panels.append(panels.SearchAndReplacePanel(),
                      api.Panel.Position.BOTTOM)

    # open a file
    editor.file.open(__file__)

    # run
    window.show()
    app.exec_()

CodeEdit

The editor widget is a simple extension to QPlainTextEdit.

It adds a few utility signals/methods and introduces the concept of Managers, Modes and Panels.

A mode/panel is an editor extension that, once added to a CodeEdit instance, may modify its behaviour and appearance:

  • Modes are simple objects which connect to the editor signals to append new behaviours (such as automatic indentation, code completion, syntax checking,...)

  • Panels are the combination of a Mode and a QWidget. They are displayed in the QCodeEdit’s content margins.

    When you install a Panel on a CodeEdit, you can choose to install it in one of the four following zones:

    _images/editor_widget.png

A manager is an object that literally manage a specific aspect of pyqode.core.api.CodeEdit. There are managers to manage the list of modes/panels, to open/save file and to control the backend:

Controlling the backend

To use the backend (from the frontend), you need to use pyqode.core.managers.BackendManager.

To start the backend, use pyqode.core.managers.BackendManager.start. You can specify a custom interpreter if needed (useful in python for working with a python2 interpreter or when using a virtual environment):

code_editor.backend.start('path/to/server_script.py',
                          interpreter='/usr/bin/python2.7')

To request some work to be done on the backend, just use pyqode.core.managers.BackendManager.send_request. You can specify a callback to be called when the work has finished (i.e. to retrieve the job results):

code_editor.backend.send_request(my_worker, {'parameters': None,}, my_callback)

To stop the backend, just use pyqode.core.managers.BackendManager.stop:

code_editor.backend.stop()

You should not need to call it manually as the backend is automatically stopped when the editor got deleted by the python interpreter.

Opening and saving files

Opening and saving files is made easy by using the pyqode.core.managers.FileManager.

Opening a file:

code_edit.file.open('/path/to/file.py')

Saving a file:

code_editor.file.save()

Saving a file as:

code_editor.file.save('/path/to/new_file.py')

You can always replace a manager by your own version if you’re not happy with it or if you want to extend it.

Using modes and panels

To use modes and panels, you must use the corresponding managers:

Those managers are available as attributes of CodeEdit:

To install a mode/panel, use the append method:

code_editor.modes.append(MyMode())

To retrieve a mode/panel, use the get method. This method accepts either the mode name or the mode class:

m_name = code_editor.modes.get('MyMode')
m_class = code_editor.modes.get(MyMode)
assert m_name == m_class

Note

The order of installation of modes is important because some modes have interdependances. Also it is worth noting that the order of installation of modes define the order of reaction to a specific events.

Usually, this kind of restriction is documented for a specific modes in its class documentation.

Changing editor style and properties

You can change any property of CodeEdit, or any of its modes, at runtime.

E.g.:

# change color scheme
code_editor.modes.get(PygmentsSyntaxHighlighter).pygments_style = 'monokai'
# change property
code_editor.show_white_spaces = True
# change action shortcut
code_editor.action_duplicate_line.setShortcut('Ctrl+Shift+Down')