I use following intro for stand-alone applications:
# the_app.py
import os
import sys
from qgis.core import *
from PyQt4.QtGui import *
def main():
QgsApplication.setPrefixPath(os.environ['QGIS_PREFIX'], True)
QgsApplication.initQgis()
# app specific code
...
QgsApplication.exitQgis()
sys.exit(result)
if __name__ == '__main__':
main()
When the app do not need a GUI (eg do some geoprocessing), replace the ellipsis with something like that:
# app specific code (console)
print 'starting test'
layer1 = QgsVectorLayer('LineString', 'anewlayer', 'memory')
print layer.isValid()
QgsMapLayerRegistry.instance().addMapLayer(layer1, False)
print 'layer added to map layer registry'
aLayer = QgsMapLayerRegistry.instance().mapLayersByName('anewlayer')[0]
print aLayer.name()
To work with one or more layers you do not have to add them to map layer registry, just reference them by their variable name (here layer1).
When you use a GUI, for example a mapper window, this would be a python class derived from QMainWindow, typically designed with QtDesigner. The ellipsis have to be replaced with code as in the next example:
# app specific code (GUI)
app = QApplication(sys.argv)
# create gui window
window = Main()
window.show()
result = app.exec_()
app.deleteLater()
To test this approach without actually having a GUI try this modified console version:
# app specific code (GUI ready)
app = QApplication(sys.argv)
layer1 = QgsVectorLayer('LineString', 'anewlayer', 'memory')
QgsMapLayerRegistry.instance().addMapLayer(layer1, False)
aLayer = QgsMapLayerRegistry.instance().mapLayersByName('anewlayer')[0]
print aLayer.name()
app.qApp.quit()
result = app.exec_()
app.deleteLater()
It is almost the same as the console version (as there are actually no graphical objects), but regard the quit() which stops the application.
To start such app on Linux:
#!/bin/sh
export PYTHONPATH="/usr/share/qgis/python"
export LD_LIBRARY_PATH="/usr/lib64/qgis"
export QGIS_PREFIX="/usr"
python the_app.py
And on a Windows machine:
SET OSGEO4W_ROOT=D:\OSGeo4W64
SET QGISNAME=qgis
SET QGIS=%OSGEO4W_ROOT%\apps\%QGISNAME%
SET QGIS_PREFIX=%QGIS%
CALL %OSGEO4W_ROOT%\bin\o4w_env.bat
SET PATH=%PATH%;%QGIS%\bin
SET PYTHONPATH=%QGIS%\python;%PYTHONPATH%
python the_app.py
A very basic GUI may look like this:
# hand-made window with simple toolbar
class Ui_DemoWindow(object):
def setupUi(self, window):
window.setWindowTitle('Demo')
self.centralWidget = QWidget(window)
self.centralWidget.setFixedSize(640, 480)
window.setCentralWidget(self.centralWidget)
window.move(0, 0)
self.layout = QVBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
self.centralWidget.setLayout(self.layout)
self.toolBar = QToolBar(window)
window.addToolBar(Qt.TopToolBarArea, self.toolBar)
# quit action
self.actionQuit = QAction('Quit', window)
self.actionQuit.setShortcut(QKeySequence.Quit)
# do something, here call function to create some geometries
self.actionCreateGeom = QAction('Geometry', window)
# link action to GUI elements
self.toolBar.addAction(self.actionQuit)
self.toolBar.addSeparator()
self.toolBar.addAction(self.actionCreateGeom)
class Main(QMainWindow, Ui_DemoWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setupUi(self)
self.canvas = QgsMapCanvas()
self.layout.addWidget(self.canvas)
self.connect(self.actionQuit, SIGNAL('triggered()'), self.quit)
self.connect(self.actionCreateGeom, SIGNAL('triggered()'), self.some_geoms)
# quick and dirty: create layer with some features, add layer
# to map canvas, and zoom canvas to full view
def some_geoms(self):
layer = QgsVectorLayer('LineString', 'anewlayer', 'memory')
# add some features
prov = layer.dataProvider()
feats = []
feat = QgsFeature()
feat.setGeometry(QgsGeometry().fromPolyline([QgsPoint(-1,1), QgsPoint(1, -1)]))
feats.append(feat)
prov.addFeatures(feats)
layer.updateExtents()
QgsMapLayerRegistry.instance().addMapLayer(layer)
self.canvas.setLayerSet([QgsMapCanvasLayer(layer)])
self.canvas.zoomToFullExtent()
def quit(self):
qApp.quit()
How its look after pressing button Geometry:

Starting with this simple example you may wish to implement the legend widget, property dialogs, layer dialogs, selection and editing behaviour, and so on.
Traceback (most recent call last): File "test.py", line 25, in <module> main() File "test.py", line 15, in main window = Main() NameError: global name 'Main' is not defined– GreatEmerald Jan 22 '16 at 09:36qAppfromapp.qApp.quit(), since that doesn't exist) as I get the right output, but it doesn't seem to connect or start a visible QGIS instance, so I don't see the layer in it. Also, once again it just gets stuck and I need to kill it, it doesn't actually quit. – GreatEmerald Jan 22 '16 at 15:17qgis.corefunctions, but alsoqgis.utils.ifacefunctions, likeqgis.utils.iface.addVectorLayer("testing.shp", "anewlayer", "ogr"). – GreatEmerald Jan 25 '16 at 16:03ifaceis only available in QGIS itself. For a standalone application you have to build all interface stuff from scratch using the API (Qgis and Qt). To help you starting I extend the answer to include a very basic Main() class to show some of this API calls. – Detlev Jan 25 '16 at 17:46ImportError: No module named qgis.coreerror. Could someone please help? – wondim Jan 18 '19 at 21:42