Advertisement
Guest User

Segfault-generating PyQt5 code

a guest
Nov 7th, 2014
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.18 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. # This is based on Baz Walter's example code for the QsciLexerCustom class.
  4. # The added code producing a segmentation fault is marked below in the
  5. # __init__ method of the MainWindow class.
  6.  
  7. import sys
  8. from PyQt5 import QtCore, QtGui, QtWidgets, Qsci
  9.  
  10.  
  11. class MainWindow(QtWidgets.QMainWindow):
  12.      def __init__(self):
  13.          QtWidgets.QMainWindow.__init__(self)
  14.          self.setWindowTitle('Custom Lexer Example')
  15.          self.setGeometry(QtCore.QRect(50,200,400,400))
  16.          self.editor = Qsci.QsciScintilla(self)
  17.          self.editor.setUtf8(True)
  18.          self.editor.setMarginWidth(2, 15)
  19.          self.editor.setFolding(True)
  20.  
  21.          # The following three lines of code cause this program to generate a
  22.          # segfault for me upon closing the main window. The original code it
  23.          # replaces is:
  24.          #
  25.          # self.setCentralWidget(self.editor)
  26.          self.tabWidget = QtWidgets.QTabWidget()
  27.          self.tabWidget.addTab(self.editor, 'Untitled')
  28.          self.setCentralWidget(self.tabWidget)
  29.  
  30.          self.lexer = CustomLexer(self.editor)
  31.          self.editor.setLexer(self.lexer)
  32.          self.editor.setText('\n# sample source\n\nfoo = 1\nbar = 2\n')
  33.  
  34.  
  35. class CustomLexer(Qsci.QsciLexerCustom):
  36.      def __init__(self, parent):
  37.          Qsci.QsciLexerCustom.__init__(self, parent)
  38.          self._styles = {
  39.              0: 'Default',
  40.              1: 'Comment',
  41.              2: 'Key',
  42.              3: 'Assignment',
  43.              4: 'Value',
  44.              }
  45.          for key in self._styles:
  46.              setattr(self, self._styles[key], key)
  47.  
  48.      def description(self, style):
  49.          return self._styles.get(style, '')
  50.  
  51.      def defaultColor(self, style):
  52.          if style == self.Default:
  53.              return QtGui.QColor('#000000')
  54.          elif style == self.Comment:
  55.              return QtGui.QColor('#C0C0C0')
  56.          elif style == self.Key:
  57.              return QtGui.QColor('#0000CC')
  58.          elif style == self.Assignment:
  59.              return QtGui.QColor('#CC0000')
  60.          elif style == self.Value:
  61.              return QtGui.QColor('#00CC00')
  62.          return Qsci.QsciLexerCustom.defaultColor(self, style)
  63.  
  64.      def styleText(self, start, end):
  65.          editor = self.editor()
  66.          if editor is None:
  67.              return
  68.  
  69.          # scintilla works with encoded bytes, not decoded characters.
  70.          # this matters if the source contains non-ascii characters and
  71.          # a multi-byte encoding is used (e.g. utf-8)
  72.          source = b''
  73.          if end > editor.length():
  74.              end = editor.length()
  75.          if end > start:
  76.              source = editor.text().encode('utf-8')[start:end]
  77.          if not source:
  78.              return
  79.  
  80.          # the line index will also be needed to implement folding
  81.          index = editor.SendScintilla(editor.SCI_LINEFROMPOSITION, start)
  82.          if index > 0:
  83.              # the previous state may be needed for multi-line styling
  84.              pos = editor.SendScintilla(
  85.                        editor.SCI_GETLINEENDPOSITION, index - 1)
  86.              state = editor.SendScintilla(editor.SCI_GETSTYLEAT, pos)
  87.          else:
  88.              state = self.Default
  89.  
  90.          set_style = self.setStyling
  91.          self.startStyling(start, 0x1f)
  92.  
  93.          # scintilla always asks to style whole lines
  94.          for line in source.splitlines(True):
  95.              length = len(line)
  96.              if line.startswith(b'#'):
  97.                  state = self.Comment
  98.              else:
  99.                  # the following will style lines like "x = 0"
  100.                  pos = line.find(b'=')
  101.                  if pos > 0:
  102.                      set_style(pos, self.Key)
  103.                      set_style(1, self.Assignment)
  104.                      length = length - pos - 1
  105.                      state = self.Value
  106.                  else:
  107.                      state = self.Default
  108.              set_style(length, state)
  109.              # folding implementation goes here
  110.              index += 1
  111.  
  112.  
  113. if __name__ == "__main__":
  114.      app = QtWidgets.QApplication(sys.argv)
  115.      app.lastWindowClosed.connect(app.quit)
  116.      win = MainWindow()
  117.      win.show()
  118.      sys.exit(app.exec_())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement