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 2.0k 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
    #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