New Python Console
@ -97,6 +97,9 @@ SET (QGIS_PYTHON_DIR ${PYTHON_SITE_PACKAGES_DIR}/qgis)
|
||||
|
||||
ADD_CUSTOM_TARGET(compile_python_files ALL)
|
||||
|
||||
ADD_SUBDIRECTORY(iconConsole)
|
||||
ADD_SUBDIRECTORY(helpConsole)
|
||||
|
||||
ADD_CUSTOM_COMMAND(TARGET compile_python_files
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${QGIS_PYTHON_OUTPUT_DIRECTORY}
|
||||
@ -115,3 +118,6 @@ ENDFOREACH(file)
|
||||
PYTHON_INSTALL(__init__.py ${QGIS_PYTHON_DIR})
|
||||
PYTHON_INSTALL(utils.py ${QGIS_PYTHON_DIR})
|
||||
PYTHON_INSTALL(console.py ${QGIS_PYTHON_DIR})
|
||||
PYTHON_INSTALL(console_sci.py ${QGIS_PYTHON_DIR})
|
||||
PYTHON_INSTALL(help.py ${QGIS_PYTHON_DIR})
|
||||
|
||||
|
@ -1,36 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# Some portions of code were taken from managerR plugin.
|
||||
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Implementation of interactive Python console widget for QGIS.
|
||||
|
||||
Has +- the same behaviour as command-line interactive console:
|
||||
- runs commands one by one
|
||||
- supports expressions that span through more lines
|
||||
- has command history, accessible using up/down keys
|
||||
- supports pasting of commands
|
||||
|
||||
TODO:
|
||||
- configuration - init commands, font, ...
|
||||
- python code highlighting
|
||||
/***************************************************************************
|
||||
Python Conosle for QGIS
|
||||
-------------------
|
||||
begin : 2012-09-xx
|
||||
copyright : (C) 2012 by Salvatore Larosa
|
||||
email : lrssvtml (at) gmail (dot) com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
Some portions of code were taken from https://code.google.com/p/pydee/
|
||||
"""
|
||||
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
from qgis.utils import iface
|
||||
from console_sci import PythonEdit
|
||||
from help import HelpDialog
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import code
|
||||
|
||||
|
||||
_init_commands = ["from qgis.core import *", "import qgis.utils"]
|
||||
import os
|
||||
|
||||
_console = None
|
||||
|
||||
@ -47,286 +43,227 @@ def show_console():
|
||||
_console.activateWindow()
|
||||
_console.edit.setFocus()
|
||||
|
||||
|
||||
_old_stdout = sys.stdout
|
||||
_console_output = None
|
||||
|
||||
|
||||
def clearConsole():
|
||||
global _console
|
||||
if _console is None:
|
||||
return
|
||||
_console.edit.clearConsole()
|
||||
|
||||
|
||||
# hook for python console so all output will be redirected
|
||||
# and then shown in console
|
||||
def console_displayhook(obj):
|
||||
global _console_output
|
||||
_console_output = obj
|
||||
global _console_output
|
||||
_console_output = obj
|
||||
|
||||
class QgisOutputCatcher:
|
||||
def __init__(self):
|
||||
self.data = ''
|
||||
def write(self, stuff):
|
||||
self.data += stuff
|
||||
def get_and_clean_data(self):
|
||||
tmp = self.data
|
||||
self.data = ''
|
||||
return tmp
|
||||
def flush(self):
|
||||
pass
|
||||
def __init__(self):
|
||||
self.data = ''
|
||||
def write(self, stuff):
|
||||
self.data += stuff
|
||||
def get_and_clean_data(self):
|
||||
tmp = self.data
|
||||
self.data = ''
|
||||
return tmp
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
sys.stdout = QgisOutputCatcher()
|
||||
|
||||
class PythonConsole(QDockWidget):
|
||||
def __init__(self, parent=None):
|
||||
QDockWidget.__init__(self, parent)
|
||||
self.setObjectName("Python Console")
|
||||
self.setAllowedAreas(Qt.BottomDockWidgetArea)
|
||||
self.widget = QWidget()
|
||||
self.l = QVBoxLayout(self.widget)
|
||||
self.l.setMargin(0)
|
||||
self.edit = PythonEdit()
|
||||
self.l.addWidget(self.edit)
|
||||
self.setWidget(self.widget)
|
||||
self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))
|
||||
# try to restore position from stored main window state
|
||||
if not iface.mainWindow().restoreDockWidget(self):
|
||||
iface.mainWindow().addDockWidget(Qt.BottomDockWidgetArea, self)
|
||||
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(500,300)
|
||||
|
||||
def closeEvent(self, event):
|
||||
QWidget.closeEvent(self, event)
|
||||
|
||||
|
||||
class ConsoleHighlighter(QSyntaxHighlighter):
|
||||
EDIT_LINE, ERROR, OUTPUT, INIT = range(4)
|
||||
def __init__(self, doc):
|
||||
QSyntaxHighlighter.__init__(self,doc)
|
||||
formats = { self.OUTPUT : Qt.black,
|
||||
self.ERROR : Qt.red,
|
||||
self.EDIT_LINE : Qt.darkGreen,
|
||||
self.INIT : Qt.gray }
|
||||
self.f = {}
|
||||
for tag, color in formats.iteritems():
|
||||
self.f[tag] = QTextCharFormat()
|
||||
self.f[tag].setForeground(color)
|
||||
EDIT_LINE, ERROR, OUTPUT, INIT = range(4)
|
||||
def __init__(self, doc):
|
||||
QSyntaxHighlighter.__init__(self,doc)
|
||||
formats = { self.OUTPUT : Qt.black,
|
||||
self.ERROR : Qt.red,
|
||||
self.EDIT_LINE : Qt.darkGreen,
|
||||
self.INIT : Qt.gray }
|
||||
self.f = {}
|
||||
for tag, color in formats.iteritems():
|
||||
self.f[tag] = QTextCharFormat()
|
||||
self.f[tag].setForeground(color)
|
||||
|
||||
def highlightBlock(self, txt):
|
||||
size = txt.length()
|
||||
state = self.currentBlockState()
|
||||
if state == self.OUTPUT or state == self.ERROR or state == self.INIT:
|
||||
self.setFormat(0,size, self.f[state])
|
||||
# highlight prompt only
|
||||
if state == self.EDIT_LINE:
|
||||
self.setFormat(0,3, self.f[self.EDIT_LINE])
|
||||
def highlightBlock(self, txt):
|
||||
size = txt.length()
|
||||
state = self.currentBlockState()
|
||||
if state == self.OUTPUT or state == self.ERROR or state == self.INIT:
|
||||
self.setFormat(0,size, self.f[state])
|
||||
# highlight prompt only
|
||||
if state == self.EDIT_LINE:
|
||||
self.setFormat(0,3, self.f[self.EDIT_LINE])
|
||||
|
||||
class PythonConsole(QDockWidget):
|
||||
def __init__(self, parent=None):
|
||||
QDockWidget.__init__(self, parent)
|
||||
self.setObjectName("Python Console")
|
||||
#self.setAllowedAreas(Qt.BottomDockWidgetArea)
|
||||
|
||||
self.widgetButton = QWidget()
|
||||
self.widgetEdit = QWidget()
|
||||
|
||||
self.toolBar = QToolBar()
|
||||
self.toolBar.setEnabled(True)
|
||||
#self.toolBar.setFont(font)
|
||||
self.toolBar.setFocusPolicy(Qt.NoFocus)
|
||||
self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
|
||||
self.toolBar.setLayoutDirection(Qt.LeftToRight)
|
||||
self.toolBar.setIconSize(QSize(24, 24))
|
||||
self.toolBar.setOrientation(Qt.Vertical)
|
||||
self.toolBar.setMovable(True)
|
||||
self.toolBar.setFloatable(True)
|
||||
#self.toolBar.setAllowedAreas(Qt.LeftToolBarArea)
|
||||
#self.toolBar.setAllowedAreas(Qt.RightToolBarArea)
|
||||
#self.toolBar.setObjectName(_fromUtf8("toolMappa"))
|
||||
|
||||
self.b = QVBoxLayout(self.widgetButton)
|
||||
self.e = QHBoxLayout(self.widgetEdit)
|
||||
|
||||
self.e.setMargin(0)
|
||||
self.b.setMargin(0)
|
||||
|
||||
## Action for Clear button
|
||||
self.clearButton = QAction(parent)
|
||||
self.clearButton.setCheckable(False)
|
||||
self.clearButton.setEnabled(True)
|
||||
self.clearButton.setIcon(QIcon("icon/iconClearConsole.png"))
|
||||
self.clearButton.setMenuRole(QAction.PreferencesRole)
|
||||
self.clearButton.setIconVisibleInMenu(True)
|
||||
self.clearButton.setToolTip('Clear console')
|
||||
## Action for paste snippets code
|
||||
self.clearButton = QAction(parent)
|
||||
self.clearButton.setCheckable(False)
|
||||
self.clearButton.setEnabled(True)
|
||||
self.clearButton.setIcon(QIcon(os.path.dirname(__file__) + "/iconConsole/iconClearConsole.png"))
|
||||
self.clearButton.setMenuRole(QAction.PreferencesRole)
|
||||
self.clearButton.setIconVisibleInMenu(True)
|
||||
self.clearButton.setToolTip('Clear console')
|
||||
## Action for paste snippets code
|
||||
# self.currentLayerButton = QAction(parent)
|
||||
# self.currentLayerButton.setCheckable(False)
|
||||
# self.currentLayerButton.setEnabled(True)
|
||||
# self.currentLayerButton.setIcon(QIcon("icon/iconTempConsole.png"))
|
||||
# self.currentLayerButton.setMenuRole(QAction.PreferencesRole)
|
||||
# self.currentLayerButton.setIconVisibleInMenu(True)
|
||||
##
|
||||
self.loadIfaceButton = QAction(parent)
|
||||
self.loadIfaceButton.setCheckable(False)
|
||||
self.loadIfaceButton.setEnabled(True)
|
||||
self.loadIfaceButton.setIcon(QIcon(os.path.dirname(__file__) + "/iconConsole/iconTempConsole.png"))
|
||||
self.loadIfaceButton.setMenuRole(QAction.PreferencesRole)
|
||||
self.loadIfaceButton.setIconVisibleInMenu(True)
|
||||
self.loadIfaceButton.setToolTip('Import iface class')
|
||||
## Action for Open File
|
||||
self.openFileButton = QAction(parent)
|
||||
self.openFileButton.setCheckable(False)
|
||||
self.openFileButton.setEnabled(True)
|
||||
self.openFileButton.setIcon(QIcon(os.path.dirname(__file__) + "/iconConsole/iconOpenConsole.png"))
|
||||
self.openFileButton.setMenuRole(QAction.PreferencesRole)
|
||||
self.openFileButton.setIconVisibleInMenu(True)
|
||||
self.openFileButton.setToolTip('Open script file')
|
||||
## Action for Save File
|
||||
self.saveFileButton = QAction(parent)
|
||||
self.saveFileButton.setCheckable(False)
|
||||
self.saveFileButton.setEnabled(True)
|
||||
self.saveFileButton.setIcon(QIcon(os.path.dirname(__file__) + "/iconConsole/iconSaveConsole.png"))
|
||||
self.saveFileButton.setMenuRole(QAction.PreferencesRole)
|
||||
self.saveFileButton.setIconVisibleInMenu(True)
|
||||
self.saveFileButton.setToolTip('Save to file')
|
||||
## Action for Run script
|
||||
self.runButton = QAction(parent)
|
||||
self.runButton.setCheckable(False)
|
||||
self.runButton.setEnabled(True)
|
||||
self.runButton.setIcon(QIcon(os.path.dirname(__file__) + "/iconConsole/iconRunConsole.png"))
|
||||
self.runButton.setMenuRole(QAction.PreferencesRole)
|
||||
self.runButton.setIconVisibleInMenu(True)
|
||||
self.runButton.setToolTip('Run command')
|
||||
## Help action
|
||||
self.helpButton = QAction(parent)
|
||||
self.helpButton.setCheckable(False)
|
||||
self.helpButton.setEnabled(True)
|
||||
self.helpButton.setIcon(QIcon(os.path.dirname(__file__) + "/iconConsole/iconHelpConsole.png"))
|
||||
self.helpButton.setMenuRole(QAction.PreferencesRole)
|
||||
self.helpButton.setIconVisibleInMenu(True)
|
||||
self.helpButton.setToolTip('Help')
|
||||
|
||||
self.toolBar.addAction(self.clearButton)
|
||||
#self.toolBar.addAction(self.currentLayerButton)
|
||||
self.toolBar.addAction(self.loadIfaceButton)
|
||||
self.toolBar.addAction(self.openFileButton)
|
||||
self.toolBar.addAction(self.saveFileButton)
|
||||
self.toolBar.addAction(self.helpButton)
|
||||
self.toolBar.addAction(self.runButton)
|
||||
|
||||
self.b.addWidget(self.toolBar)
|
||||
self.edit = PythonEdit()
|
||||
|
||||
self.setWidget(self.widgetEdit)
|
||||
|
||||
self.e.addWidget(self.widgetButton)
|
||||
self.e.addWidget(self.edit)
|
||||
|
||||
self.edit.setFocus()
|
||||
|
||||
self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))
|
||||
self.clearButton.activated.connect(self.edit.clearConsole)
|
||||
#self.currentLayerButton.activated.connect(self.cLayer)
|
||||
self.loadIfaceButton.activated.connect(self.iface)
|
||||
self.runButton.activated.connect(self.edit.entered)
|
||||
self.openFileButton.activated.connect(self.openScriptFile)
|
||||
self.saveFileButton.activated.connect(self.saveScriptFile)
|
||||
self.helpButton.activated.connect(self.openHelp)
|
||||
# try to restore position from stored main window state
|
||||
if not iface.mainWindow().restoreDockWidget(self):
|
||||
iface.mainWindow().addDockWidget(Qt.BottomDockWidgetArea, self)
|
||||
|
||||
def cLayer(self):
|
||||
self.edit.commandConsole('cLayer')
|
||||
|
||||
def iface(self):
|
||||
self.edit.commandConsole('iface')
|
||||
|
||||
def openScriptFile(self):
|
||||
scriptFile = QFileDialog.getOpenFileName(
|
||||
self, "Open File", "", "Script file (*.py)")
|
||||
if scriptFile.isEmpty() == False:
|
||||
oF = open(scriptFile, 'r')
|
||||
listScriptFile = []
|
||||
for line in oF:
|
||||
if line != "\n":
|
||||
listScriptFile.append(line)
|
||||
self.edit.insertTextFromFile(listScriptFile)
|
||||
|
||||
|
||||
def saveScriptFile(self):
|
||||
scriptFile = QFileDialog()
|
||||
scriptFile.setDefaultSuffix(".py")
|
||||
fName = scriptFile.getSaveFileName(
|
||||
self, "Save file", QString(), "Script file (*.py)")
|
||||
|
||||
if fName.isEmpty() == False:
|
||||
filename = str(fName)
|
||||
if not filename.endswith(".py"):
|
||||
fName += ".py"
|
||||
sF = open(fName,'w')
|
||||
listText = self.edit.getTextFromEditor()
|
||||
is_first_line = True
|
||||
for s in listText:
|
||||
if s[0:3] in (">>>", "..."):
|
||||
s.replace(">>> ", "")
|
||||
s.replace("... ", "")
|
||||
if is_first_line:
|
||||
# see, no write() in this branch
|
||||
is_first_line = False
|
||||
else:
|
||||
# we've just written a line; add a newline
|
||||
sF.write('\n')
|
||||
sF.write(s)
|
||||
sF.close()
|
||||
|
||||
class PythonEdit(QTextEdit, code.InteractiveInterpreter):
|
||||
def openHelp(self):
|
||||
dlg = HelpDialog()
|
||||
dlg.exec_()
|
||||
|
||||
def __init__(self,parent=None):
|
||||
QTextEdit.__init__(self, parent)
|
||||
code.InteractiveInterpreter.__init__(self, locals=None)
|
||||
|
||||
self.setTextInteractionFlags(Qt.TextEditorInteraction)
|
||||
self.setAcceptDrops(False)
|
||||
self.setMinimumSize(30, 30)
|
||||
self.setUndoRedoEnabled(False)
|
||||
self.setAcceptRichText(False)
|
||||
monofont = QFont("Monospace")
|
||||
monofont.setStyleHint(QFont.TypeWriter)
|
||||
self.setFont(monofont)
|
||||
|
||||
self.buffer = []
|
||||
|
||||
self.insertInitText()
|
||||
|
||||
for line in _init_commands:
|
||||
self.runsource(line)
|
||||
|
||||
self.displayPrompt(False)
|
||||
|
||||
self.history = QStringList()
|
||||
self.historyIndex = 0
|
||||
|
||||
self.high = ConsoleHighlighter(self)
|
||||
|
||||
def insertInitText(self):
|
||||
self.insertTaggedText(QCoreApplication.translate("PythonConsole", "To access Quantum GIS environment from this console\n"
|
||||
"use qgis.utils.iface object (instance of QgisInterface class).\n\n"),
|
||||
ConsoleHighlighter.INIT)
|
||||
|
||||
|
||||
def clearConsole(self):
|
||||
self.clear()
|
||||
self.insertInitText()
|
||||
|
||||
def displayPrompt(self, more=False):
|
||||
self.currentPrompt = "... " if more else ">>> "
|
||||
self.currentPromptLength = len(self.currentPrompt)
|
||||
self.insertTaggedLine(self.currentPrompt, ConsoleHighlighter.EDIT_LINE)
|
||||
self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
|
||||
|
||||
def isCursorInEditionZone(self):
|
||||
cursor = self.textCursor()
|
||||
pos = cursor.position()
|
||||
block = self.document().lastBlock()
|
||||
last = block.position() + self.currentPromptLength
|
||||
return pos >= last
|
||||
|
||||
def currentCommand(self):
|
||||
block = self.cursor.block()
|
||||
text = block.text()
|
||||
return text.right(text.length()-self.currentPromptLength)
|
||||
|
||||
def showPrevious(self):
|
||||
if self.historyIndex < len(self.history) and not self.history.isEmpty():
|
||||
self.cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.MoveAnchor)
|
||||
self.cursor.movePosition(QTextCursor.StartOfBlock, QTextCursor.KeepAnchor)
|
||||
self.cursor.removeSelectedText()
|
||||
self.cursor.insertText(self.currentPrompt)
|
||||
self.historyIndex += 1
|
||||
if self.historyIndex == len(self.history):
|
||||
self.insertPlainText("")
|
||||
else:
|
||||
self.insertPlainText(self.history[self.historyIndex])
|
||||
|
||||
def showNext(self):
|
||||
if self.historyIndex > 0 and not self.history.isEmpty():
|
||||
self.cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.MoveAnchor)
|
||||
self.cursor.movePosition(QTextCursor.StartOfBlock, QTextCursor.KeepAnchor)
|
||||
self.cursor.removeSelectedText()
|
||||
self.cursor.insertText(self.currentPrompt)
|
||||
self.historyIndex -= 1
|
||||
if self.historyIndex == len(self.history):
|
||||
self.insertPlainText("")
|
||||
else:
|
||||
self.insertPlainText(self.history[self.historyIndex])
|
||||
|
||||
def updateHistory(self, command):
|
||||
if isinstance(command, QStringList):
|
||||
for line in command:
|
||||
self.history.append(line)
|
||||
elif not command == "":
|
||||
if len(self.history) <= 0 or \
|
||||
not command == self.history[-1]:
|
||||
self.history.append(command)
|
||||
self.historyIndex = len(self.history)
|
||||
|
||||
def keyPressEvent(self, e):
|
||||
self.cursor = self.textCursor()
|
||||
# if the cursor isn't in the edition zone, don't do anything except Ctrl+C
|
||||
if not self.isCursorInEditionZone():
|
||||
if e.modifiers() & Qt.ControlModifier or e.modifiers() & Qt.MetaModifier:
|
||||
if e.key() == Qt.Key_C or e.key() == Qt.Key_A:
|
||||
QTextEdit.keyPressEvent(self, e)
|
||||
else:
|
||||
# all other keystrokes get sent to the input line
|
||||
self.cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
|
||||
else:
|
||||
# if Return is pressed, then perform the commands
|
||||
if e.key() == Qt.Key_Return or e.key() == Qt.Key_Enter:
|
||||
self.entered()
|
||||
# if Up or Down is pressed
|
||||
elif e.key() == Qt.Key_Down:
|
||||
self.showPrevious()
|
||||
elif e.key() == Qt.Key_Up:
|
||||
self.showNext()
|
||||
# if backspace is pressed, delete until we get to the prompt
|
||||
elif e.key() == Qt.Key_Backspace:
|
||||
if not self.cursor.hasSelection() and self.cursor.columnNumber() == self.currentPromptLength:
|
||||
return
|
||||
QTextEdit.keyPressEvent(self, e)
|
||||
# if the left key is pressed, move left until we get to the prompt
|
||||
elif e.key() == Qt.Key_Left and self.cursor.position() > self.document().lastBlock().position() + self.currentPromptLength:
|
||||
anchor = QTextCursor.KeepAnchor if e.modifiers() & Qt.ShiftModifier else QTextCursor.MoveAnchor
|
||||
move = QTextCursor.WordLeft if e.modifiers() & Qt.ControlModifier or e.modifiers() & Qt.MetaModifier else QTextCursor.Left
|
||||
self.cursor.movePosition(move, anchor)
|
||||
# use normal operation for right key
|
||||
elif e.key() == Qt.Key_Right:
|
||||
anchor = QTextCursor.KeepAnchor if e.modifiers() & Qt.ShiftModifier else QTextCursor.MoveAnchor
|
||||
move = QTextCursor.WordRight if e.modifiers() & Qt.ControlModifier or e.modifiers() & Qt.MetaModifier else QTextCursor.Right
|
||||
self.cursor.movePosition(move, anchor)
|
||||
# if home is pressed, move cursor to right of prompt
|
||||
elif e.key() == Qt.Key_Home:
|
||||
anchor = QTextCursor.KeepAnchor if e.modifiers() & Qt.ShiftModifier else QTextCursor.MoveAnchor
|
||||
self.cursor.movePosition(QTextCursor.StartOfBlock, anchor, 1)
|
||||
self.cursor.movePosition(QTextCursor.Right, anchor, self.currentPromptLength)
|
||||
# use normal operation for end key
|
||||
elif e.key() == Qt.Key_End:
|
||||
anchor = QTextCursor.KeepAnchor if e.modifiers() & Qt.ShiftModifier else QTextCursor.MoveAnchor
|
||||
self.cursor.movePosition(QTextCursor.EndOfBlock, anchor, 1)
|
||||
# use normal operation for all remaining keys
|
||||
else:
|
||||
QTextEdit.keyPressEvent(self, e)
|
||||
self.setTextCursor(self.cursor)
|
||||
self.ensureCursorVisible()
|
||||
|
||||
def insertFromMimeData(self, source):
|
||||
self.cursor = self.textCursor()
|
||||
if source.hasText():
|
||||
pasteList = QStringList()
|
||||
pasteList = source.text().split("\n")
|
||||
# move the cursor to the end only if the text is multi-line or is going to be pasted not into the last line
|
||||
if (len(pasteList) > 1) or (not self.isCursorInEditionZone()):
|
||||
self.cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor, 1)
|
||||
self.setTextCursor(self.cursor)
|
||||
# with multi-line text also run the commands
|
||||
for line in pasteList[:-1]:
|
||||
self.insertPlainText(line)
|
||||
self.runCommand(unicode(self.currentCommand()))
|
||||
# last line: only paste the text, do not run it
|
||||
self.insertPlainText(unicode(pasteList[-1]))
|
||||
|
||||
def entered(self):
|
||||
self.cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
|
||||
self.setTextCursor(self.cursor)
|
||||
self.runCommand( unicode(self.currentCommand()) )
|
||||
|
||||
def insertTaggedText(self, txt, tag):
|
||||
|
||||
if len(txt) > 0 and txt[-1] == '\n': # remove trailing newline to avoid one more empty line
|
||||
txt = txt[0:-1]
|
||||
|
||||
c = self.textCursor()
|
||||
for line in txt.split('\n'):
|
||||
b = c.block()
|
||||
b.setUserState(tag)
|
||||
c.insertText(line)
|
||||
c.insertBlock()
|
||||
|
||||
def insertTaggedLine(self, txt, tag):
|
||||
c = self.textCursor()
|
||||
b = c.block()
|
||||
b.setUserState(tag)
|
||||
c.insertText(txt)
|
||||
|
||||
def runCommand(self, cmd):
|
||||
|
||||
self.updateHistory(cmd)
|
||||
|
||||
self.insertPlainText("\n")
|
||||
|
||||
self.buffer.append(cmd)
|
||||
src = "\n".join(self.buffer)
|
||||
more = self.runsource(src, "<input>")
|
||||
if not more:
|
||||
self.buffer = []
|
||||
|
||||
output = sys.stdout.get_and_clean_data()
|
||||
if output:
|
||||
self.insertTaggedText(output, ConsoleHighlighter.OUTPUT)
|
||||
self.displayPrompt(more)
|
||||
|
||||
def write(self, txt):
|
||||
""" reimplementation from code.InteractiveInterpreter """
|
||||
self.insertTaggedText(txt, ConsoleHighlighter.ERROR)
|
||||
def closeEvent(self, event):
|
||||
QWidget.closeEvent(self, event)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = QApplication(sys.argv)
|
||||
show_console()
|
||||
a.exec_()
|
||||
a = QApplication(sys.argv)
|
||||
show_console()
|
||||
a.exec_()
|
||||
|
456
python/console_sci.py
Normal file
@ -0,0 +1,456 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
/***************************************************************************
|
||||
Python Conosle for QGIS
|
||||
-------------------
|
||||
begin : 2012-09-xx
|
||||
copyright : (C) 2012 by Salvatore Larosa
|
||||
email : lrssvtml (at) gmail (dot) com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
Some portions of code were taken from https://code.google.com/p/pydee/
|
||||
"""
|
||||
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.Qsci import *
|
||||
from PyQt4.Qsci import QsciScintilla, QsciScintillaBase, QsciLexerPython
|
||||
#from qgis.utils import iface
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import code
|
||||
|
||||
_init_commands = ["from qgis.core import *", "import qgis.utils"]
|
||||
|
||||
_console = None
|
||||
|
||||
_old_stdout = sys.stdout
|
||||
_console_output = None
|
||||
|
||||
class PythonEdit(QsciScintilla, code.InteractiveInterpreter):
|
||||
def __init__(self, parent=None):
|
||||
#QsciScintilla.__init__(self, parent)
|
||||
super(PythonEdit,self).__init__(parent)
|
||||
code.InteractiveInterpreter.__init__(self, locals=None)
|
||||
|
||||
self.current_prompt_pos = None
|
||||
self.new_input_line = True
|
||||
|
||||
self.setMarginWidth(0, 0)
|
||||
self.setMarginWidth(1, 0)
|
||||
self.setMarginWidth(2, 0)
|
||||
|
||||
self.buffer = []
|
||||
|
||||
self.insertInitText()
|
||||
|
||||
self.setCursorPosition(4,4)
|
||||
|
||||
self.displayPrompt(False)
|
||||
|
||||
for line in _init_commands:
|
||||
self.runsource(line)
|
||||
|
||||
self.history = QStringList()
|
||||
self.historyIndex = 0
|
||||
|
||||
# Brace matching: enable for a brace immediately before or after
|
||||
# the current position
|
||||
self.setBraceMatching(QsciScintilla.SloppyBraceMatch)
|
||||
#self.moveToMatchingBrace()
|
||||
#self.selectToMatchingBrace()
|
||||
|
||||
# Current line visible with special background color
|
||||
self.setCaretLineVisible(True)
|
||||
self.setCaretLineBackgroundColor(QColor("#ffe4e4"))
|
||||
self.setCaretWidth(2)
|
||||
|
||||
# Set Python lexer
|
||||
# Set style for Python comments (style number 1) to a fixed-width
|
||||
# courier.
|
||||
self.setLexers(True)
|
||||
|
||||
# Indentation
|
||||
#self.setAutoIndent(True)
|
||||
#self.setIndentationsUseTabs(False)
|
||||
#self.setIndentationWidth(4)
|
||||
#self.setTabIndents(True)
|
||||
#self.setBackspaceUnindents(True)
|
||||
#self.setTabWidth(4)
|
||||
|
||||
self.setAutoCompletionThreshold(1)
|
||||
self.setAutoCompletionSource(self.AcsAPIs)
|
||||
|
||||
# Don't want to see the horizontal scrollbar at all
|
||||
# Use raw message to Scintilla here (all messages are documented
|
||||
# here: http://www.scintilla.org/ScintillaDoc.html)
|
||||
self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)
|
||||
|
||||
# not too small
|
||||
#self.setMinimumSize(500, 300)
|
||||
|
||||
self.SendScintilla(QsciScintilla.SCI_SETWRAPMODE, 1)
|
||||
self.SendScintilla(QsciScintilla.SCI_EMPTYUNDOBUFFER)
|
||||
|
||||
def clearConsole(self):
|
||||
"""Clear the contents of the console."""
|
||||
self.setText('')
|
||||
self.insertInitText()
|
||||
self.displayPrompt(False)
|
||||
self.setFocus()
|
||||
|
||||
def commandConsole(self, command):
|
||||
line, pos = self.getCurLine()
|
||||
selCmd= self.text(line).length()
|
||||
self.setSelection(line, 4, line, selCmd)
|
||||
self.removeSelectedText()
|
||||
if command == "iface":
|
||||
"""Import QgisInterface class"""
|
||||
self.append('from qgis.utils import iface')
|
||||
self.move_cursor_to_end()
|
||||
elif command == "cLayer":
|
||||
"""Retrive current Layer from map camvas"""
|
||||
self.append('cLayer = iface.mapCanvas().currentLayer()')
|
||||
self.move_cursor_to_end()
|
||||
self.setFocus()
|
||||
|
||||
def setLexers(self, lexer):
|
||||
if lexer:
|
||||
font = QFont()
|
||||
font.setFamily('Courier New') ## Courier New
|
||||
font.setFixedPitch(True)
|
||||
font.setPointSize(10)
|
||||
self.setFont(font)
|
||||
self.setMarginsFont(font)
|
||||
self.lexer = QsciLexerPython()
|
||||
self.lexer.setDefaultFont(font)
|
||||
#self.lexer.setDefaultFont(QFont('Mono', 10, 0, False))
|
||||
#self.lexer.setDefaultColor(Qt.darkGray)
|
||||
self.lexer.setColor(Qt.red, 1)
|
||||
self.lexer.setColor(Qt.darkGreen, 5)
|
||||
self.lexer.setColor(Qt.darkBlue, 15)
|
||||
self.lexer.setFont(font, 1)
|
||||
self.lexer.setFont(font, 3)
|
||||
self.lexer.setFont(font, 4)
|
||||
self.api = QsciAPIs(self.lexer)
|
||||
self.api.load("API/PyQGIS_1.8.api")
|
||||
self.api.load("API/osgeo_gdal-ogr_1.9.1-1.api")
|
||||
|
||||
self.api.prepare()
|
||||
self.lexer.setAPIs(self.api)
|
||||
self.setLexer(self.lexer)
|
||||
|
||||
## TODO: show completion list for file and directory
|
||||
# def show_completion_list(self, completions, text):
|
||||
# """Private method to display the possible completions"""
|
||||
# if len(completions) == 0:
|
||||
# return
|
||||
# if len(completions) > 1:
|
||||
# self.showUserList(1, QStringList(sorted(completions)))
|
||||
# self.completion_chars = 1
|
||||
# else:
|
||||
# txt = completions[0]
|
||||
# if text != "":
|
||||
# txt = txt.replace(text, "")
|
||||
# self.insert(txt)
|
||||
# self.completion_chars = 0
|
||||
#
|
||||
# def show_file_completion(self):
|
||||
# """Display a completion list for files and directories"""
|
||||
# cwd = os.getcwdu()
|
||||
# self.show_completion_list(self.listdir_fullpath('/'), cwd)
|
||||
#
|
||||
# def listdir_fullpath(self, d):
|
||||
# return [os.path.join(d, f) for f in os.listdir(d)]
|
||||
|
||||
|
||||
def insertInitText(self):
|
||||
#self.setLexers(False)
|
||||
txtInit = ("## To access Quantum GIS environment from this console\n"
|
||||
"## use qgis.utils.iface object (instance of QgisInterface class).\n\n")
|
||||
initText = self.setText(txtInit)
|
||||
|
||||
def getCurrentPos(self):
|
||||
""" Get the position (as an int) of the cursor.
|
||||
getCursorPosition() returns a (linenr, index) tuple.
|
||||
"""
|
||||
return self.SendScintilla(self.SCI_GETCURRENTPOS)
|
||||
|
||||
def getText(self):
|
||||
""" Get the text as a unicode string. """
|
||||
value = self.getBytes().decode('utf-8')
|
||||
# print (value) printing can give an error because the console font
|
||||
# may not have all unicode characters
|
||||
return value
|
||||
|
||||
def getBytes(self):
|
||||
""" Get the text as bytes (utf-8 encoded). This is how
|
||||
the data is stored internally. """
|
||||
len = self.SendScintilla(self.SCI_GETLENGTH)+1
|
||||
bb = QByteArray(len,'0')
|
||||
N = self.SendScintilla(self.SCI_GETTEXT, len, bb)
|
||||
return bytes(bb)[:-1]
|
||||
|
||||
def getTextLength(self):
|
||||
return self.SendScintilla(QsciScintilla.SCI_GETLENGTH)
|
||||
|
||||
def getLine(self, linenr):
|
||||
""" Get the bytes on the given line number. """
|
||||
len = self.SendScintilla(QsciScintilla.SCI_LINELENGTH)+1
|
||||
bb = QByteArray(len,'0')
|
||||
N = self.SendScintilla(QsciScintilla.SCI_GETLINE, len, bb)
|
||||
return bytes(bb)[:-1]
|
||||
|
||||
def getCurLine(self):
|
||||
""" Get the current line (as a string) and the
|
||||
position of the cursor in it. """
|
||||
linenr, index = self.getCursorPosition()
|
||||
#line = self.getLine(linenr) #.decode('utf-8')
|
||||
return linenr, index
|
||||
|
||||
def get_end_pos(self):
|
||||
"""Return (line, index) position of the last character"""
|
||||
line = self.lines() - 1
|
||||
return (line, self.text(line).length())
|
||||
|
||||
def is_cursor_at_end(self):
|
||||
"""Return True if cursor is at the end of text"""
|
||||
cline, cindex = self.getCursorPosition()
|
||||
return (cline, cindex) == self.get_end_pos()
|
||||
|
||||
def move_cursor_to_end(self):
|
||||
"""Move cursor to end of text"""
|
||||
line, index = self.get_end_pos()
|
||||
self.setCursorPosition(line, index)
|
||||
self.ensureCursorVisible()
|
||||
|
||||
def on_new_line(self):
|
||||
"""On new input line"""
|
||||
self.move_cursor_to_end()
|
||||
self.current_prompt_pos = self.getCursorPosition()
|
||||
self.new_input_line = False
|
||||
|
||||
def is_cursor_on_last_line(self):
|
||||
"""Return True if cursor is on the last line"""
|
||||
cline, _ = self.getCursorPosition()
|
||||
return cline == self.lines() - 1
|
||||
|
||||
def new_prompt(self, prompt):
|
||||
"""
|
||||
Print a new prompt and save its (line, index) position
|
||||
"""
|
||||
self.write(prompt, prompt=True)
|
||||
# now we update our cursor giving end of prompt
|
||||
self.current_prompt_pos = self.getCursorPosition()
|
||||
self.ensureCursorVisible()
|
||||
|
||||
def check_selection(self):
|
||||
"""
|
||||
Check if selected text is r/w,
|
||||
otherwise remove read-only parts of selection
|
||||
"""
|
||||
if self.current_prompt_pos is None:
|
||||
self.move_cursor_to_end()
|
||||
return
|
||||
line_from, index_from, line_to, index_to = self.getSelection()
|
||||
pline, pindex = self.current_prompt_pos
|
||||
if line_from < pline or \
|
||||
(line_from == pline and index_from < pindex):
|
||||
self.setSelection(pline, pindex, line_to, index_to)
|
||||
|
||||
def displayPrompt(self, more=False):
|
||||
self.append("... ") if more else self.append(">>> ")
|
||||
self.move_cursor_to_end()
|
||||
|
||||
def updateHistory(self, command):
|
||||
if isinstance(command, QStringList):
|
||||
for line in command:
|
||||
self.history.append(line)
|
||||
elif not command == "":
|
||||
if len(self.history) <= 0 or \
|
||||
not command == self.history[-1]:
|
||||
self.history.append(command)
|
||||
self.historyIndex = len(self.history)
|
||||
|
||||
def showPrevious(self):
|
||||
if self.historyIndex < len(self.history) and not self.history.isEmpty():
|
||||
line, pos = self.getCurLine()
|
||||
selCmd= self.text(line).length()
|
||||
self.setSelection(line, 4, line, selCmd)
|
||||
self.removeSelectedText()
|
||||
self.historyIndex += 1
|
||||
if self.historyIndex == len(self.history):
|
||||
self.insert("")
|
||||
pass
|
||||
else:
|
||||
self.insert(self.history[self.historyIndex])
|
||||
self.move_cursor_to_end()
|
||||
#self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
|
||||
|
||||
|
||||
def showNext(self):
|
||||
if self.historyIndex > 0 and not self.history.isEmpty():
|
||||
line, pos = self.getCurLine()
|
||||
selCmd = self.text(line).length()
|
||||
self.setSelection(line, 4, line, selCmd)
|
||||
self.removeSelectedText()
|
||||
self.historyIndex -= 1
|
||||
if self.historyIndex == len(self.history):
|
||||
self.insert("")
|
||||
else:
|
||||
self.insert(self.history[self.historyIndex])
|
||||
self.move_cursor_to_end()
|
||||
#self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
|
||||
|
||||
def keyPressEvent(self, e):
|
||||
linenr, index = self.getCurLine()
|
||||
if not self.is_cursor_on_last_line() or index < 4:
|
||||
if e.modifiers() & Qt.ControlModifier or e.modifiers() & Qt.MetaModifier:
|
||||
if e.key() == Qt.Key_C or e.key() == Qt.Key_A:
|
||||
QsciScintilla.keyPressEvent(self, e)
|
||||
else:
|
||||
# all other keystrokes get sent to the input line
|
||||
self.move_cursor_to_end()
|
||||
#pass
|
||||
else:
|
||||
if (e.key() == Qt.Key_Return or e.key() == Qt.Key_Enter) and not self.isListActive():
|
||||
self.entered()
|
||||
elif e.key() == Qt.Key_Backspace:
|
||||
curPos, pos = self.getCursorPosition()
|
||||
line = self.lines() -1
|
||||
if curPos < line -1 or pos < 5:
|
||||
return
|
||||
#else:
|
||||
#self.move_cursor_to_end()
|
||||
QsciScintilla.keyPressEvent(self, e)
|
||||
elif e.key() == Qt.Key_Delete:
|
||||
if self.hasSelectedText():
|
||||
self.check_selection()
|
||||
self.removeSelectedText()
|
||||
elif self.is_cursor_on_last_line():
|
||||
self.SendScintilla(QsciScintilla.SCI_CLEAR)
|
||||
e.accept()
|
||||
elif e.key() == Qt.Key_Down and not self.isListActive():
|
||||
self.showPrevious()
|
||||
elif e.key() == Qt.Key_Up and not self.isListActive():
|
||||
self.showNext()
|
||||
elif e.key() == Qt.Key_Left:
|
||||
e.accept()
|
||||
if e.modifiers() & Qt.ShiftModifier:
|
||||
if e.modifiers() & Qt.ControlModifier:
|
||||
self.SendScintilla(QsciScintilla.SCI_WORDLEFTEXTEND)
|
||||
else:
|
||||
self.SendScintilla(QsciScintilla.SCI_CHARLEFTEXTEND)
|
||||
else:
|
||||
if e.modifiers() & Qt.ControlModifier:
|
||||
self.SendScintilla(QsciScintilla.SCI_WORDLEFT)
|
||||
else:
|
||||
self.SendScintilla(QsciScintilla.SCI_CHARLEFT)
|
||||
elif e.key() == Qt.Key_Right:
|
||||
e.accept()
|
||||
if e.modifiers() & Qt.ShiftModifier:
|
||||
if e.modifiers() & Qt.ControlModifier:
|
||||
self.SendScintilla(QsciScintilla.SCI_WORDRIGHTEXTEND)
|
||||
else:
|
||||
self.SendScintilla(QsciScintilla.SCI_CHARRIGHTEXTEND)
|
||||
else:
|
||||
if e.modifiers() & Qt.ControlModifier:
|
||||
self.SendScintilla(QsciScintilla.SCI_WORDRIGHT)
|
||||
else:
|
||||
self.SendScintilla(QsciScintilla.SCI_CHARRIGHT)
|
||||
## TODO: press event for auto-completion file directory
|
||||
#elif e.key() == Qt.Key_Tab:
|
||||
#self.show_file_completion()
|
||||
#else:
|
||||
#self.on_new_line()
|
||||
else:
|
||||
QsciScintilla.keyPressEvent(self, e)
|
||||
|
||||
def paste(self):
|
||||
"""Reimplement QScintilla method"""
|
||||
# Moving cursor to the end of the last line
|
||||
self.move_cursor_to_end()
|
||||
#QsciScintilla.paste(self)
|
||||
QMessageBox.warning(self, "Python Console",
|
||||
"Currently the action paste in console is not supported!")
|
||||
return
|
||||
|
||||
## Drag and drop
|
||||
def dragEnterEvent(self, e):
|
||||
if e.mimeData().hasFormat('text/plain'):
|
||||
e.accept()
|
||||
else:
|
||||
e.ignore()
|
||||
|
||||
def dropEvent(self, e):
|
||||
stringDrag = e.mimeData().text()
|
||||
pasteList = QStringList()
|
||||
pasteList = stringDrag.split("\n")
|
||||
for line in pasteList[:-1]:
|
||||
self.append(line)
|
||||
self.move_cursor_to_end()
|
||||
#self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
|
||||
self.runCommand(unicode(self.currentCommand()))
|
||||
self.append(unicode(pasteList[-1]))
|
||||
self.move_cursor_to_end()
|
||||
|
||||
def getTextFromEditor(self):
|
||||
text = self.text()
|
||||
textList = QStringList()
|
||||
textList = text.split("\n")
|
||||
return textList
|
||||
|
||||
def insertTextFromFile(self, listOpenFile):
|
||||
for line in listOpenFile[:-1]:
|
||||
self.append(line)
|
||||
self.move_cursor_to_end()
|
||||
self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
|
||||
self.runCommand(unicode(self.currentCommand()))
|
||||
self.append(unicode(listOpenFile[-1]))
|
||||
self.move_cursor_to_end()
|
||||
self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
|
||||
|
||||
def entered(self):
|
||||
self.move_cursor_to_end()
|
||||
self.runCommand( unicode(self.currentCommand()) )
|
||||
self.setFocus()
|
||||
#self.SendScintilla(QsciScintilla.SCI_EMPTYUNDOBUFFER)
|
||||
|
||||
def currentCommand(self):
|
||||
linenr, index = self.getCurLine()
|
||||
#for i in range(0, linenr):
|
||||
txtLength = self.text(linenr).length()
|
||||
string = self.text()
|
||||
cmdLine = string.right(txtLength - 4)
|
||||
cmd = str(cmdLine)
|
||||
return cmd
|
||||
|
||||
def runCommand(self, cmd):
|
||||
self.updateHistory(cmd)
|
||||
self.SendScintilla(QsciScintilla.SCI_NEWLINE)
|
||||
self.buffer.append(cmd)
|
||||
src = "\n".join(self.buffer)
|
||||
more = self.runsource(src, "<input>")
|
||||
if not more:
|
||||
self.buffer = []
|
||||
|
||||
output = sys.stdout.get_and_clean_data()
|
||||
if output:
|
||||
self.append(output)
|
||||
|
||||
self.move_cursor_to_end()
|
||||
self.displayPrompt(more)
|
||||
|
||||
def write(self, txt):
|
||||
self.SendScintilla(QsciScintilla.SCI_SETSTYLING, len(txt), 1)
|
||||
self.append(txt)
|
||||
self.SendScintilla(QsciScintilla.SCI_SETSTYLING, len(txt), 1)
|
37
python/help.py
Normal file
@ -0,0 +1,37 @@
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
import os
|
||||
|
||||
class HelpDialog(QtGui.QDialog):
|
||||
|
||||
def __init__(self):
|
||||
QtGui.QDialog.__init__(self)
|
||||
self.setModal(True)
|
||||
self.setupUi()
|
||||
|
||||
def setupUi(self):
|
||||
self.resize(500, 300)
|
||||
self.webView = QtWebKit.QWebView()
|
||||
self.setWindowTitle("Help Python Console")
|
||||
self.verticalLayout= QtGui.QVBoxLayout()
|
||||
self.verticalLayout.setSpacing(2)
|
||||
self.verticalLayout.setMargin(0)
|
||||
self.verticalLayout.addWidget(self.webView)
|
||||
self.closeButton = QtGui.QPushButton()
|
||||
self.closeButton.setText("Close")
|
||||
self.closeButton.setMaximumWidth(150)
|
||||
self.horizontalLayout= QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setSpacing(2)
|
||||
self.horizontalLayout.setMargin(0)
|
||||
self.horizontalLayout.addStretch(1000)
|
||||
self.horizontalLayout.addWidget(self.closeButton)
|
||||
QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), self.closeWindow)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
self.setLayout(self.verticalLayout)
|
||||
filename = os.path.dirname(__file__) + "/helpConsole/help.htm"
|
||||
url = QtCore.QUrl(filename)
|
||||
self.webView.load(url)
|
||||
|
||||
def closeWindow(self):
|
||||
self.close()
|
2
python/helpConsole/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
FILE(GLOB HTML_FILES *.htm)
|
||||
INSTALL(FILES ${HTML_FILES} DESTINATION ${QGIS_PYTHON_DIR}/helpConsole)
|
59
python/helpConsole/help.htm
Normal file
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Help Python Console</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: verdana,arial,helvetica,sans-serif;
|
||||
/*font-family:Verdana,Geneva,sans-serif;*/
|
||||
font-size : 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<img src="../iconConsole/imgHelpDialog.png" />
|
||||
</td>
|
||||
<td>
|
||||
<h2>Python Console for QGIS</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p align="justify">
|
||||
To access Quantum GIS environment from this console
|
||||
use qgis.utils.iface object (instance of QgisInterface class).
|
||||
To import the class QgisInterface can also use the dedicated
|
||||
button on the toolbar on the left.
|
||||
<br><br>
|
||||
The following is a description of the tools in the toolbar:
|
||||
</p>
|
||||
<table width="100%" bordercolor="#000" border="1">
|
||||
<tr>
|
||||
<td><img src="../iconConsole/iconClearConsole.png" /></td>
|
||||
<td>Tool to clear python console</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../iconConsole/iconTempConsole.png" /></td>
|
||||
<td>Tool to import iface class</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../iconConsole/iconOpenConsole.png" /></td>
|
||||
<td>Tool to open a python script and load in console</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../iconConsole/iconSaveConsole.png" /></td>
|
||||
<td>Tool to save a python script</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../iconConsole/iconHelpConsole.png" /></td>
|
||||
<td>This! ;-)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../iconConsole/iconRunConsole.png" /></td>
|
||||
<td>Run commnand (like Enter key pressed)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
12
python/iconConsole/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
SET(ICON_FILES
|
||||
iconClearConsole.png
|
||||
iconOpenConsole.png
|
||||
iconRunConsole.png
|
||||
iconTempConsole.png
|
||||
iconSaveConsole.png
|
||||
iconHelpConsole.png
|
||||
imgHelpDialog.png
|
||||
)
|
||||
|
||||
FILE(GLOB ICON_FILES *.png)
|
||||
INSTALL(FILES ${ICON_FILES} DESTINATION ${QGIS_PYTHON_DIR}/iconConsole)
|
BIN
python/iconConsole/iconClearConsole.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
python/iconConsole/iconHelpConsole.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
python/iconConsole/iconOpenConsole.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
python/iconConsole/iconRunConsole.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
python/iconConsole/iconSaveConsole.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
python/iconConsole/iconTempConsole.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
python/iconConsole/imgHelpDialog.png
Normal file
After Width: | Height: | Size: 3.6 KiB |