root/branch/twedit/CustomLexer.py

Revision 1337, 4.3 kB (checked in by mswat, 22 months ago)

Added Custom Lexer example

Line 
1import sys
2from PyQt4 import QtCore, QtGui, Qsci
3
4
5class MainWindow(QtGui.QMainWindow):
6      def __init__(self):
7            QtGui.QMainWindow.__init__(self)
8            self.setWindowTitle('Custom Lexer Example')
9            self.setGeometry(QtCore.QRect(50,200,400,400))
10            self.editor = Qsci.QsciScintilla(self)
11            self.editor.setUtf8(True)
12            self.editor.setMarginWidth(2, 15)
13            self.editor.setFolding(True)
14            self.setCentralWidget(self.editor)
15            self.lexer = CustomLexer(self.editor)
16            self.editor.setLexer(self.lexer)
17            self.editor.setText('\n# sample source\n\nfoo = 1\nbar = 2\n')
18
19
20class CustomLexer(Qsci.QsciLexerCustom):
21      def __init__(self, parent):
22            Qsci.QsciLexerCustom.__init__(self, parent)
23            self._styles = {
24                 0: 'Default',
25                 1: 'Comment',
26                 2: 'Key',
27                 3: 'Assignment',
28                 4: 'Value',
29                 }
30            for key,value in self._styles.iteritems():
31                 setattr(self, value, key)
32
33      def description(self, style):
34            return self._styles.get(style, '')
35
36      def defaultColor(self, style):
37            if style == self.Default:
38                 return QtGui.QColor('#000000')
39            elif style == self.Comment:
40                 return QtGui.QColor('#C0C0C0')
41            elif style == self.Key:
42                 return QtGui.QColor('#0000CC')
43            elif style == self.Assignment:
44                 return QtGui.QColor('#CC0000')
45            elif style == self.Value:
46                 return QtGui.QColor('#00CC00')
47            return Qsci.QsciLexerCustom.defaultColor(self, style)
48
49      def styleText(self, start, end):
50            editor = self.editor()
51            if editor is None:
52                 return
53
54            # scintilla works with encoded bytes, not decoded characters.
55            # this matters if the source contains non-ascii characters and
56            # a multi-byte encoding is used (e.g. utf-8)
57            source = ''
58            if end > editor.length():
59                 end = editor.length()
60            if end > start:
61                 if sys.hexversion >= 0x02060000:
62                      # faster when styling big files, but needs python 2.6
63                      source = bytearray(end - start)
64                      editor.SendScintilla(
65                            editor.SCI_GETTEXTRANGE, start, end, source)
66                 else:
67                      source = unicode(editor.text()
68                                            ).encode('utf-8')[start:end]
69            if not source:
70                 return
71
72            # the line index will also be needed to implement folding
73            index = editor.SendScintilla(editor.SCI_LINEFROMPOSITION, start)
74            if index > 0:
75                 # the previous state may be needed for multi-line styling
76                 pos = editor.SendScintilla(
77                              editor.SCI_GETLINEENDPOSITION, index - 1)
78                 state = editor.SendScintilla(editor.SCI_GETSTYLEAT, pos)
79            else:
80                 state = self.Default
81
82            set_style = self.setStyling
83            self.startStyling(start, 0x1f)
84
85            # scintilla always asks to style whole lines
86            for line in source.splitlines(True):
87                 length = len(line)
88                 if line.startswith('#'):
89                      state = self.Comment
90                 else:
91                      # the following will style lines like "x = 0"
92                      pos = line.find('=')
93                      if pos > 0:
94                            set_style(pos, self.Key)
95                            set_style(1, self.Assignment)
96                            length = length - pos - 1
97                            state = self.Value
98                      else:
99                            state = self.Default
100                 set_style(length, state)
101                 # folding implementation goes here
102                 index += 1
103
104
105if __name__ == "__main__":
106      app = QtGui.QApplication(sys.argv)
107      app.connect(app, QtCore.SIGNAL('lastWindowClosed()'),
108                      QtCore.SLOT('quit()'))
109      win = MainWindow()
110      win.show()
111      sys.exit(app.exec_())
Note: See TracBrowser for help on using the browser.