Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Syntax highlighter to QPlainTextEdit
Forum Updated to NodeBB v4.3 + New Features

Syntax highlighter to QPlainTextEdit

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 3 Posters 1.9k 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.
  • A Offline
    A Offline
    AndrzejB
    wrote on last edited by AndrzejB
    #1

    How make highlighter? Where are samples of highlighters?
    I am using /usr/include/KF5/KSyntaxHighlighting/
    Highlighters to Kate are in xml format: https://invent.kde.org/frameworks/syntax-highlighting/-/tree/master/data/syntax
    this means, it uses general syntax highlighter which read xml?
    How can I use highlighter without KF5 ?

    JonBJ 1 Reply Last reply
    0
    • A AndrzejB

      How make highlighter? Where are samples of highlighters?
      I am using /usr/include/KF5/KSyntaxHighlighting/
      Highlighters to Kate are in xml format: https://invent.kde.org/frameworks/syntax-highlighting/-/tree/master/data/syntax
      this means, it uses general syntax highlighter which read xml?
      How can I use highlighter without KF5 ?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @AndrzejB said in Syntax highlighter to QPlainTextEdit:

      Where are samples of highlighters?
      How can I use highlighter without KF5.

      https://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html
      https://doc.qt.io/qt-6/qtwidgets-richtext-syntaxhighlighter-example.html

      1 Reply Last reply
      1
      • A Offline
        A Offline
        AndrzejB
        wrote on last edited by
        #3

        Highlighter can also enable code folding? How it implement in highlighter? Code folding can't be implement by regular expression, must be stack?

        JonBJ 1 Reply Last reply
        0
        • A AndrzejB

          Highlighter can also enable code folding? How it implement in highlighter? Code folding can't be implement by regular expression, must be stack?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @AndrzejB said in Syntax highlighter to QPlainTextEdit:

          Highlighter can also enable code folding?

          I don't know, but I doubt it. It's a syntax highlighter, not an editor.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            AndrzejB
            wrote on last edited by
            #5

            Kf5 extension has folding:
            SyntaxHighlighterPrivate::foldingRegion
            in
            https://invent.kde.org/frameworks/syntax-highlighting/-/blob/master/src/lib/syntaxhighlighter.cpp

            JonBJ 1 Reply Last reply
            1
            • A AndrzejB

              Kf5 extension has folding:
              SyntaxHighlighterPrivate::foldingRegion
              in
              https://invent.kde.org/frameworks/syntax-highlighting/-/blob/master/src/lib/syntaxhighlighter.cpp

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @AndrzejB
              Precisely, so why not use it, you are the one who is asking to use plain Qt QSyntaxHighlighter instead.......

              1 Reply Last reply
              0
              • A Offline
                A Offline
                AndrzejB
                wrote on last edited by
                #7

                OK, I prefer KF5 Highlighters, but have issues

                • I want to better know QSyntaxHighlighter and highlighting process
                • sometimes I need only a few syntax but more control with syntax
                • if is possible apply QSyntaxHighlighter not only to QPlainTextEdit, but also to other, for example my viewer?
                • KF5 and Windows? I prefer Linux, but is well to write portable appllcations.
                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi,

                  KF5 is also available on Windows.
                  Out of curiosity, why not use KDE's KTextEditor ?

                  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
                  • A Offline
                    A Offline
                    AndrzejB
                    wrote on last edited by
                    #9

                    I compiled example from
                    Qt/Examples/Qt-6.2.4/widgets/richtext/syntaxhighlighter/
                    In source file Qt/6.2.4/Src/qtbase/src/gui/text/qsyntaxhighlighter.cpp is

                    void QSyntaxHighlighter::setDocument(QTextDocument *doc)
                    {
                        Q_D(QSyntaxHighlighter);
                        if (d->doc) {
                            disconnect(d->doc, SIGNAL(contentsChange(int,int,int)),
                                       this, SLOT(_q_reformatBlocks(int,int,int)));
                    
                            QTextCursor cursor(d->doc);
                            cursor.beginEditBlock();
                            for (QTextBlock blk = d->doc->begin(); blk.isValid(); blk = blk.next())
                                blk.layout()->clearFormats();
                            cursor.endEditBlock();
                        }
                        d->doc = doc;
                        if (d->doc) {
                            connect(d->doc, SIGNAL(contentsChange(int,int,int)),
                                    this, SLOT(_q_reformatBlocks(int,int,int)));
                            if (!d->doc->isEmpty()) {
                                d->rehighlightPending = true;
                                QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
                            }
                        }
                    }
                    

                    Where is defined and set "d" variable? It must be PlainTextEditor or can be my own control?
                    whats is class QTextDocument?

                    JonBJ 1 Reply Last reply
                    0
                    • A AndrzejB

                      I compiled example from
                      Qt/Examples/Qt-6.2.4/widgets/richtext/syntaxhighlighter/
                      In source file Qt/6.2.4/Src/qtbase/src/gui/text/qsyntaxhighlighter.cpp is

                      void QSyntaxHighlighter::setDocument(QTextDocument *doc)
                      {
                          Q_D(QSyntaxHighlighter);
                          if (d->doc) {
                              disconnect(d->doc, SIGNAL(contentsChange(int,int,int)),
                                         this, SLOT(_q_reformatBlocks(int,int,int)));
                      
                              QTextCursor cursor(d->doc);
                              cursor.beginEditBlock();
                              for (QTextBlock blk = d->doc->begin(); blk.isValid(); blk = blk.next())
                                  blk.layout()->clearFormats();
                              cursor.endEditBlock();
                          }
                          d->doc = doc;
                          if (d->doc) {
                              connect(d->doc, SIGNAL(contentsChange(int,int,int)),
                                      this, SLOT(_q_reformatBlocks(int,int,int)));
                              if (!d->doc->isEmpty()) {
                                  d->rehighlightPending = true;
                                  QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
                              }
                          }
                      }
                      

                      Where is defined and set "d" variable? It must be PlainTextEditor or can be my own control?
                      whats is class QTextDocument?

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #10

                      @AndrzejB said in Syntax highlighter to QPlainTextEdit:

                      Where is defined and set "d" variable?

                      From the Q_D(QSyntaxHighlighter); line. See e.g. https://wiki.qt.io/D-Pointer.

                      It must be PlainTextEditor or can be my own control?

                      No.

                      whats is class QTextDocument?

                      See void QSyntaxHighlighter::setDocument(QTextDocument *doc). It is the document the QSyntaxHighlighter is working on.

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        AndrzejB
                        wrote on last edited by AndrzejB
                        #11

                        Example of mpergand in thread "How to use scrollbars in my component?" will good start point for exercise.
                        I wrote simple in-memory text viewer with QScrollArea::
                        main.cpp

                        #include <QApplication>
                        #include <QMainWindow>
                        #include <QScrollArea>
                        #include "FileViewer.h"
                        #include "FileViewer.h"
                        
                        using namespace std;
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication app(argc, argv);
                        
                            QMainWindow textWindow;
                            auto scrollArea=new QScrollArea;
                        
                            textWindow.setCentralWidget(scrollArea);
                        
                            auto fileViewer=new FileViewer;
                            scrollArea->setWidget(fileViewer);
                        
                            string filepath = "../main.cpp";
                        
                            if(!fileViewer->setFile(filepath))   // file path of your big file
                            {
                                qDebug()<<filepath.c_str()<<"Error openning the file!";
                            }
                        
                            textWindow.resize(600, 600);
                            textWindow.show();
                        
                            return app.exec();
                        }
                        

                        FileViewer.h

                        #ifndef FILEVIEWER_H
                        #define FILEVIEWER_H
                        
                        #include <QWidget>
                        
                        class FileViewer : public QWidget
                        {
                        Q_OBJECT
                        public:
                            explicit FileViewer(QWidget *parent = nullptr);
                            bool  setFile(const std::string& filepath);
                        private:
                            std::vector<std::string> lines;
                            static std::vector<std::string> readLines(std::string filename);
                            void  paintEvent(QPaintEvent* ev);
                            int _LineHeight;        // height of a line in pixel
                        };
                        
                        #endif // FILEVIEWER_H
                        
                        

                        FileViewer.cpp

                        #include "FileViewer.h"
                        #include <QFontMetrics>
                        #include <QPainter>
                        #include <QPaintEvent>
                        #include <QDebug>
                        #include <iostream>
                        #include <fstream>
                        
                        using namespace std;
                        
                        FileViewer::FileViewer(QWidget *parent) : QWidget(parent) {
                            //setVisible(true);
                        }
                        
                        bool FileViewer::setFile(const string &filepath)
                        {
                            lines = readLines(filepath);
                            // height of a line in the default font
                            _LineHeight=fontMetrics().height();
                            resize(800, _LineHeight*lines.size());
                            return true;
                        }
                        
                        void FileViewer::paintEvent(QPaintEvent *ev) {
                            QPainter painter(this);
                            painter.setPen(Qt::black);
                            auto reg = ev->region();
                            int originY=reg.boundingRect().topLeft().y();
                            int endY=reg.boundingRect().bottomLeft().y();
                            int firstLine=originY/_LineHeight;
                            int lastLine=endY/_LineHeight+1;
                            //qDebug()<<firstLine<<lastLine;
                        
                            for(int l=firstLine; l<lastLine; l++)
                                {
                                const QString str=QString(lines[l].c_str());
                                    QRect rec=fontMetrics().boundingRect(str);
                                    /*if(rec.width()+20>_WidestLine)
                                        {
                                        _WidestLine=rec.width()+20;
                                        resize(_WidestLine,_lineCount*_LineHeight);
                                        }*/
                        
                                    painter.drawText(QPoint(10,originY+_LineHeight), str);
                                    originY+=_LineHeight;
                        
                                }
                        
                            painter.drawRect(reg.boundingRect().adjusted(1,1,-2,-2));
                        }
                        
                        vector<string> FileViewer::readLines(string filename)
                        {
                            ifstream infile(filename);
                            vector<string> v;
                            string line;
                            bool readedNewline;
                            if (infile.peek() != EOF)
                                while(true) {
                                    readedNewline = std::getline(infile, line).good();
                                    v.push_back(line);
                                    if (!readedNewline) break;
                                }
                            return v;
                        }
                        

                        Is maximum simple, only view lines. How to add syntax highlighter? Fileviewer must be descendant of QTextDocument?
                        Area is repainted even by move window, but not with scroll, how repaint on scroll only needed area?

                        JonBJ 1 Reply Last reply
                        0
                        • A AndrzejB

                          Example of mpergand in thread "How to use scrollbars in my component?" will good start point for exercise.
                          I wrote simple in-memory text viewer with QScrollArea::
                          main.cpp

                          #include <QApplication>
                          #include <QMainWindow>
                          #include <QScrollArea>
                          #include "FileViewer.h"
                          #include "FileViewer.h"
                          
                          using namespace std;
                          
                          int main(int argc, char *argv[])
                          {
                              QApplication app(argc, argv);
                          
                              QMainWindow textWindow;
                              auto scrollArea=new QScrollArea;
                          
                              textWindow.setCentralWidget(scrollArea);
                          
                              auto fileViewer=new FileViewer;
                              scrollArea->setWidget(fileViewer);
                          
                              string filepath = "../main.cpp";
                          
                              if(!fileViewer->setFile(filepath))   // file path of your big file
                              {
                                  qDebug()<<filepath.c_str()<<"Error openning the file!";
                              }
                          
                              textWindow.resize(600, 600);
                              textWindow.show();
                          
                              return app.exec();
                          }
                          

                          FileViewer.h

                          #ifndef FILEVIEWER_H
                          #define FILEVIEWER_H
                          
                          #include <QWidget>
                          
                          class FileViewer : public QWidget
                          {
                          Q_OBJECT
                          public:
                              explicit FileViewer(QWidget *parent = nullptr);
                              bool  setFile(const std::string& filepath);
                          private:
                              std::vector<std::string> lines;
                              static std::vector<std::string> readLines(std::string filename);
                              void  paintEvent(QPaintEvent* ev);
                              int _LineHeight;        // height of a line in pixel
                          };
                          
                          #endif // FILEVIEWER_H
                          
                          

                          FileViewer.cpp

                          #include "FileViewer.h"
                          #include <QFontMetrics>
                          #include <QPainter>
                          #include <QPaintEvent>
                          #include <QDebug>
                          #include <iostream>
                          #include <fstream>
                          
                          using namespace std;
                          
                          FileViewer::FileViewer(QWidget *parent) : QWidget(parent) {
                              //setVisible(true);
                          }
                          
                          bool FileViewer::setFile(const string &filepath)
                          {
                              lines = readLines(filepath);
                              // height of a line in the default font
                              _LineHeight=fontMetrics().height();
                              resize(800, _LineHeight*lines.size());
                              return true;
                          }
                          
                          void FileViewer::paintEvent(QPaintEvent *ev) {
                              QPainter painter(this);
                              painter.setPen(Qt::black);
                              auto reg = ev->region();
                              int originY=reg.boundingRect().topLeft().y();
                              int endY=reg.boundingRect().bottomLeft().y();
                              int firstLine=originY/_LineHeight;
                              int lastLine=endY/_LineHeight+1;
                              //qDebug()<<firstLine<<lastLine;
                          
                              for(int l=firstLine; l<lastLine; l++)
                                  {
                                  const QString str=QString(lines[l].c_str());
                                      QRect rec=fontMetrics().boundingRect(str);
                                      /*if(rec.width()+20>_WidestLine)
                                          {
                                          _WidestLine=rec.width()+20;
                                          resize(_WidestLine,_lineCount*_LineHeight);
                                          }*/
                          
                                      painter.drawText(QPoint(10,originY+_LineHeight), str);
                                      originY+=_LineHeight;
                          
                                  }
                          
                              painter.drawRect(reg.boundingRect().adjusted(1,1,-2,-2));
                          }
                          
                          vector<string> FileViewer::readLines(string filename)
                          {
                              ifstream infile(filename);
                              vector<string> v;
                              string line;
                              bool readedNewline;
                              if (infile.peek() != EOF)
                                  while(true) {
                                      readedNewline = std::getline(infile, line).good();
                                      v.push_back(line);
                                      if (!readedNewline) break;
                                  }
                              return v;
                          }
                          

                          Is maximum simple, only view lines. How to add syntax highlighter? Fileviewer must be descendant of QTextDocument?
                          Area is repainted even by move window, but not with scroll, how repaint on scroll only needed area?

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #12

                          @AndrzejB said in Syntax highlighter to QPlainTextEdit:

                          Fileviewer must be descendant of QTextDocument?

                          These are two totally separate things. Your FileViewer is a QWidget. A visual thing with scrolling etc.

                          A QSyntaxHighlighter works on a text document to highlight according to syntax rules. You must supply it with a QTextDocument:

                          To provide your own syntax highlighting, you must subclass QSyntaxHighlighter and reimplement highlightBlock().

                          When you create an instance of your QSyntaxHighlighter subclass, pass it the QTextDocument that you want the syntax highlighting to be applied to.

                          It is then the QTextDocument which you can show in a widget, e.g. a QTextEdit.

                          Have you looked through https://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html ?

                          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