Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. QScintilla Solidity custom syntax highlighter not working in Ubuntu
Forum Updated to NodeBB v4.3 + New Features

QScintilla Solidity custom syntax highlighter not working in Ubuntu

Scheduled Pinned Locked Moved Unsolved Qt for Python
7 Posts 2 Posters 533 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    Izabel
    wrote on 14 Sept 2023, 23:30 last edited by
    #1

    Hi!

    I made a custom syntax highlighter for Solidity using QScintilla and the solidity lexer provided by pygments in Python.

    It works perfectly in Windows, but I'm porting my app to Ubuntu and it throws an assertion error.

    This is my code:

    from PyQt6.Qsci import QsciLexerCustom
    from PyQt6.QtGui import QColor, QFont
    from pygments_lexer_solidity import SolidityLexer
    
    class CustomSolidityLexer(QsciLexerCustom):
        def __init__(self, parent):
            super().__init__(parent)
    
            # default text settings
            self.setDefaultColor(QColor("#ff000000"))
            self.setDefaultPaper(QColor("#ffffffff"))
    
            # define custom styles
            self._define_styles([QColor("#ff000000"),QColor("#ff7f0000"), QColor("#ff0000bf"), QColor("#ff007f00")])
    
            self.token_style = {
                'Token.Keyword' : 3,
                'Token.Operator' : 2,
                'Token.Keyword.Declaration' : 3,
                'Token.Keyword.Type' : 2,
                'Token.Name.Builtin' : 3,
                'Token.Keyword.Constant' : 1,
                'Token.Punctuation' : 1,
                'Token.Name.Function' : 2,
                'Token.Comment.Single' : 1
            }
    
        def _define_styles(self, color_list):
            for i, color in enumerate(color_list):
                self.setColor(color, i)
                self.setPaper(QColor("#ffffffff"), i)
                self.setFont(self.parent().window_font)
    
        def language(self):
            return "Solidity"
    
        def description(self, style: int):
    
            if style == 0:
                return "Style_0"
            elif style == 1:
                return "Style_1"
            elif style == 2:
                return "Style_2"
            elif style == 3:
                return "Style_3"
    
        def styleText(self, start: int, end: int):
            lexer = SolidityLexer()
            self.startStyling(start)
    
            text = self.parent().text()[start:end]
    
            # tokenize the text
            token_list = lexer.get_tokens(text)
            token_list = [(token[0], token[1], len(bytearray(token[1], "utf-8"))) for token in token_list]
    
            # style text in a loop
            for token in token_list:
                try:
                    self.setStyling(token[2], self.token_style[str(token[0])])
                except:
                    
                    self.setStyling(token[2], 0)
    

    And the exception is the following:

    error.png

    Thanks!!

    I 1 Reply Last reply 14 Sept 2023, 23:36
    0
    • I Izabel
      14 Sept 2023, 23:30

      Hi!

      I made a custom syntax highlighter for Solidity using QScintilla and the solidity lexer provided by pygments in Python.

      It works perfectly in Windows, but I'm porting my app to Ubuntu and it throws an assertion error.

      This is my code:

      from PyQt6.Qsci import QsciLexerCustom
      from PyQt6.QtGui import QColor, QFont
      from pygments_lexer_solidity import SolidityLexer
      
      class CustomSolidityLexer(QsciLexerCustom):
          def __init__(self, parent):
              super().__init__(parent)
      
              # default text settings
              self.setDefaultColor(QColor("#ff000000"))
              self.setDefaultPaper(QColor("#ffffffff"))
      
              # define custom styles
              self._define_styles([QColor("#ff000000"),QColor("#ff7f0000"), QColor("#ff0000bf"), QColor("#ff007f00")])
      
              self.token_style = {
                  'Token.Keyword' : 3,
                  'Token.Operator' : 2,
                  'Token.Keyword.Declaration' : 3,
                  'Token.Keyword.Type' : 2,
                  'Token.Name.Builtin' : 3,
                  'Token.Keyword.Constant' : 1,
                  'Token.Punctuation' : 1,
                  'Token.Name.Function' : 2,
                  'Token.Comment.Single' : 1
              }
      
          def _define_styles(self, color_list):
              for i, color in enumerate(color_list):
                  self.setColor(color, i)
                  self.setPaper(QColor("#ffffffff"), i)
                  self.setFont(self.parent().window_font)
      
          def language(self):
              return "Solidity"
      
          def description(self, style: int):
      
              if style == 0:
                  return "Style_0"
              elif style == 1:
                  return "Style_1"
              elif style == 2:
                  return "Style_2"
              elif style == 3:
                  return "Style_3"
      
          def styleText(self, start: int, end: int):
              lexer = SolidityLexer()
              self.startStyling(start)
      
              text = self.parent().text()[start:end]
      
              # tokenize the text
              token_list = lexer.get_tokens(text)
              token_list = [(token[0], token[1], len(bytearray(token[1], "utf-8"))) for token in token_list]
      
              # style text in a loop
              for token in token_list:
                  try:
                      self.setStyling(token[2], self.token_style[str(token[0])])
                  except:
                      
                      self.setStyling(token[2], 0)
      

      And the exception is the following:

      error.png

      Thanks!!

      I Offline
      I Offline
      Izabel
      wrote on 14 Sept 2023, 23:36 last edited by
      #2

      I forgot to add, pygment lexer returns a tuple like (<<token type>>, <<token>>, <<token character length>>).

      S 1 Reply Last reply 15 Sept 2023, 19:43
      0
      • I Izabel
        14 Sept 2023, 23:36

        I forgot to add, pygment lexer returns a tuple like (<<token type>>, <<token>>, <<token character length>>).

        S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 15 Sept 2023, 19:43 last edited by
        #3

        Hi,

        Can you provide the procedure you used to prepare your environment as well as a minimal script that triggers your issue ?

        The code itself does not seem wrong per se.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        I 2 Replies Last reply 15 Sept 2023, 20:08
        0
        • S SGaist
          15 Sept 2023, 19:43

          Hi,

          Can you provide the procedure you used to prepare your environment as well as a minimal script that triggers your issue ?

          The code itself does not seem wrong per se.

          I Offline
          I Offline
          Izabel
          wrote on 15 Sept 2023, 20:08 last edited by
          #4

          @SGaist Thanks, I will try to make a reproducible example in the next few days and explain it better!

          1 Reply Last reply
          0
          • S SGaist
            15 Sept 2023, 19:43

            Hi,

            Can you provide the procedure you used to prepare your environment as well as a minimal script that triggers your issue ?

            The code itself does not seem wrong per se.

            I Offline
            I Offline
            Izabel
            wrote on 28 Sept 2023, 22:34 last edited by
            #5

            @SGaist

            I'm sorry I took so long to answer.

            I'm running it inside a virtual environment (venv) and installed requirements with a requirements.txt that in this case should be something like this: (extracted the dependencies that apply to the minimal script)

            Pygments==2.15.1
            pygments-lexer-solidity==0.7.0
            pyparsing==3.1.0
            PyQt6==6.4.0
            PyQt6-QScintilla==2.13.3
            PyQt6-Qt6==6.5.1
            PyQt6-sip==13.5.1
            QScintilla==2.13.3

            And a minimal script that triggers the issue would be this one:

            import sys
            from PyQt6.QtWidgets import *
            from PyQt6.QtCore import *
            from PyQt6.QtGui import *
            from PyQt6.Qsci import *
            import re
            from pygments_lexer_solidity import SolidityLexer
            
            class CustomSolidityLexer(QsciLexerCustom):
                  # insert class definition in the first post
                  pass
            
            myCodeSample = r"""pragma solidity 0.8.0;
            
            contract Test {
                uint count = 0;
                address owner;
            
                constructor() public {
                    owner = msg.sender;
                }
            }"""
            
            class CustomMainWindow(QMainWindow):
                def __init__(self):
                    super(CustomMainWindow, self).__init__()
            
                    self.setGeometry(300, 300, 800, 400)
                    self.setWindowTitle("QScintilla Test")
            
                    # 2. Create frame and layout
                    # ---------------------------
                    self.__frm = QFrame(self)
                    self.__frm.setStyleSheet("QWidget { background-color: #ffeaeaea }")
                    self.__lyt = QVBoxLayout()
                    self.__frm.setLayout(self.__lyt)
                    self.setCentralWidget(self.__frm)
                    self.__myFont = QFont()
                    self.__myFont.setPointSize(14)
            
            
                    self.__editor = QsciScintilla()
                    self.__editor.setText(myCodeSample)     # 'myCodeSample' is a string containing some C-code
                    self.__editor.setLexer(None)            # We install lexer later
                    self.__editor.setUtf8(True)             # Set encoding to UTF-8
                    self.__editor.setFont(self.__myFont)    # Gets overridden by lexer later on
            
                    # 2. End-of-line mode
                    # --------------------
                    self.__editor.setEolMode(QsciScintilla.EolMode.EolUnix)
                    self.__editor.setEolVisibility(False)
            
                    # 3. Indentation
                    # ---------------
                    self.__editor.setIndentationsUseTabs(False)
                    self.__editor.setTabWidth(4)
                    self.__editor.setIndentationGuides(True)
                    self.__editor.setTabIndents(True)
                    self.__editor.setAutoIndent(True)
            
                    # 4. Caret
                    # ---------
                    self.__editor.setCaretForegroundColor(QColor("#ff0000ff"))
                    self.__editor.setCaretLineVisible(True)
                    self.__editor.setCaretLineBackgroundColor(QColor("#1f0000ff"))
                    self.__editor.setCaretWidth(2)
            
                    self.__editor.setMarginType(0, QsciScintilla.MarginType.NumberMargin)
                    self.__editor.setMarginWidth(0, "0000")
                    self.__editor.setMarginsForegroundColor(QColor("#ff888888"))
            
                    self.__lexer = CustomSolidityLexer(self.__editor)
                    self.__editor.setLexer(self.__lexer)
            
                    self.__lyt.addWidget(self.__editor)
                    self.show()
            
            if __name__ == '__main__':
                app = QApplication(sys.argv)
                myGUI = CustomMainWindow()
                sys.exit(app.exec())
            
            
            I 1 Reply Last reply 28 Sept 2023, 22:35
            0
            • I Izabel
              28 Sept 2023, 22:34

              @SGaist

              I'm sorry I took so long to answer.

              I'm running it inside a virtual environment (venv) and installed requirements with a requirements.txt that in this case should be something like this: (extracted the dependencies that apply to the minimal script)

              Pygments==2.15.1
              pygments-lexer-solidity==0.7.0
              pyparsing==3.1.0
              PyQt6==6.4.0
              PyQt6-QScintilla==2.13.3
              PyQt6-Qt6==6.5.1
              PyQt6-sip==13.5.1
              QScintilla==2.13.3

              And a minimal script that triggers the issue would be this one:

              import sys
              from PyQt6.QtWidgets import *
              from PyQt6.QtCore import *
              from PyQt6.QtGui import *
              from PyQt6.Qsci import *
              import re
              from pygments_lexer_solidity import SolidityLexer
              
              class CustomSolidityLexer(QsciLexerCustom):
                    # insert class definition in the first post
                    pass
              
              myCodeSample = r"""pragma solidity 0.8.0;
              
              contract Test {
                  uint count = 0;
                  address owner;
              
                  constructor() public {
                      owner = msg.sender;
                  }
              }"""
              
              class CustomMainWindow(QMainWindow):
                  def __init__(self):
                      super(CustomMainWindow, self).__init__()
              
                      self.setGeometry(300, 300, 800, 400)
                      self.setWindowTitle("QScintilla Test")
              
                      # 2. Create frame and layout
                      # ---------------------------
                      self.__frm = QFrame(self)
                      self.__frm.setStyleSheet("QWidget { background-color: #ffeaeaea }")
                      self.__lyt = QVBoxLayout()
                      self.__frm.setLayout(self.__lyt)
                      self.setCentralWidget(self.__frm)
                      self.__myFont = QFont()
                      self.__myFont.setPointSize(14)
              
              
                      self.__editor = QsciScintilla()
                      self.__editor.setText(myCodeSample)     # 'myCodeSample' is a string containing some C-code
                      self.__editor.setLexer(None)            # We install lexer later
                      self.__editor.setUtf8(True)             # Set encoding to UTF-8
                      self.__editor.setFont(self.__myFont)    # Gets overridden by lexer later on
              
                      # 2. End-of-line mode
                      # --------------------
                      self.__editor.setEolMode(QsciScintilla.EolMode.EolUnix)
                      self.__editor.setEolVisibility(False)
              
                      # 3. Indentation
                      # ---------------
                      self.__editor.setIndentationsUseTabs(False)
                      self.__editor.setTabWidth(4)
                      self.__editor.setIndentationGuides(True)
                      self.__editor.setTabIndents(True)
                      self.__editor.setAutoIndent(True)
              
                      # 4. Caret
                      # ---------
                      self.__editor.setCaretForegroundColor(QColor("#ff0000ff"))
                      self.__editor.setCaretLineVisible(True)
                      self.__editor.setCaretLineBackgroundColor(QColor("#1f0000ff"))
                      self.__editor.setCaretWidth(2)
              
                      self.__editor.setMarginType(0, QsciScintilla.MarginType.NumberMargin)
                      self.__editor.setMarginWidth(0, "0000")
                      self.__editor.setMarginsForegroundColor(QColor("#ff888888"))
              
                      self.__lexer = CustomSolidityLexer(self.__editor)
                      self.__editor.setLexer(self.__lexer)
              
                      self.__lyt.addWidget(self.__editor)
                      self.show()
              
              if __name__ == '__main__':
                  app = QApplication(sys.argv)
                  myGUI = CustomMainWindow()
                  sys.exit(app.exec())
              
              
              I Offline
              I Offline
              Izabel
              wrote on 28 Sept 2023, 22:35 last edited by
              #6

              @Izabel And Python version is 3.10.6 !

              S 1 Reply Last reply 5 Oct 2023, 21:16
              0
              • I Izabel
                28 Sept 2023, 22:35

                @Izabel And Python version is 3.10.6 !

                S Offline
                S Offline
                SGaist
                Lifetime Qt Champion
                wrote on 5 Oct 2023, 21:16 last edited by
                #7

                From the looks of it, the last entry of the token list is the one that makes the styling go past the end.

                I would say don't style the last line feed.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved