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. How to get the xy position of a text in a QTextEdit?

How to get the xy position of a text in a QTextEdit?

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 3 Posters 1.2k 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.
  • J Offline
    J Offline
    Joeyy
    wrote on last edited by Joeyy
    #1

    I'm trying to render a square containing the color when its a hex color string:

    2ef1eca6-20cb-4349-883d-ed60d8bfec9b-image.png

    How i could get the xy position of the text passed to the highlightBlock function
    relative to the QTextEdit area?

    I tried using cursorRect but I'm not figuring out how to properly save the text position, and if there's a "better" function for getting the text position.

    Work in progress:

    class TextEdit : public QTextEdit
    {
    public:
        QRect colorRect;
        QColor color;
    
        TextEdit(QWidget* parent) : QTextEdit(parent) {};
    
        void paintEvent(QPaintEvent* event)
        {
    		QTextEdit::paintEvent(event);
            if (color.isValid())
            {
                QPainter painter(viewport());
                painter.setRenderHint(QPainter::Antialiasing);
                painter.setPen(Qt::NoPen);
                painter.setBrush(color);
                painter.drawRect(colorRect);
            }
    	}
    };
    
    
    
    class HtmlSyntax : public QSyntaxHighlighter
    {
    public:
        TextEdit* textEdit;
        QRegularExpression hexColorPattern = QRegularExpression("#[0-9A-Fa-f]{6}\\b");
        HtmlSyntax(TextEdit* parent) : QSyntaxHighlighter(parent), textEdit(parent) {}
    
    protected:
        void highlightBlock(const QString& text) override
        {
            QRegularExpressionMatchIterator matchIterator = hexColorPattern.globalMatch(text);
    
            while (matchIterator.hasNext())
            {
                QRegularExpressionMatch match = matchIterator.next();
                QString hexColor = match.captured(0);
                QColor color(hexColor);
    
                if (color.isValid())
                {
                    qDebug() << hexColor;
                    //qDebug() << text;
                    //if (text == hexColor)
                    //{
                        QRect r = textEdit->cursorRect();
                        textEdit->colorRect = QRect(r.x(), r.y(), 16, 16);
                        textEdit->color = color;
                        textEdit->viewport()->update();
                    //}
    
                    QTextCharFormat colorFormat;
                    colorFormat.setForeground(color);
                    setFormat(match.capturedStart(), match.capturedLength(), colorFormat);
                }
            }
        }
    };
    
    
    
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::QtWidgetsApplication14Class())
    {
        ui->setupUi(this);
    
        TextEdit* textEdit = new TextEdit(this);
        textEdit->setText(R"(
          #ff0000   ddd
    aa #ba00ff sdsd  #00ff00 abbc
    #00ffb4 xxxx
        )");
        setCentralWidget(textEdit);
        HtmlSyntax* htmlSyntax = new HtmlSyntax(textEdit);
    }
    
    jsulmJ 1 Reply Last reply
    0
    • J Joeyy

      I'm trying to render a square containing the color when its a hex color string:

      2ef1eca6-20cb-4349-883d-ed60d8bfec9b-image.png

      How i could get the xy position of the text passed to the highlightBlock function
      relative to the QTextEdit area?

      I tried using cursorRect but I'm not figuring out how to properly save the text position, and if there's a "better" function for getting the text position.

      Work in progress:

      class TextEdit : public QTextEdit
      {
      public:
          QRect colorRect;
          QColor color;
      
          TextEdit(QWidget* parent) : QTextEdit(parent) {};
      
          void paintEvent(QPaintEvent* event)
          {
      		QTextEdit::paintEvent(event);
              if (color.isValid())
              {
                  QPainter painter(viewport());
                  painter.setRenderHint(QPainter::Antialiasing);
                  painter.setPen(Qt::NoPen);
                  painter.setBrush(color);
                  painter.drawRect(colorRect);
              }
      	}
      };
      
      
      
      class HtmlSyntax : public QSyntaxHighlighter
      {
      public:
          TextEdit* textEdit;
          QRegularExpression hexColorPattern = QRegularExpression("#[0-9A-Fa-f]{6}\\b");
          HtmlSyntax(TextEdit* parent) : QSyntaxHighlighter(parent), textEdit(parent) {}
      
      protected:
          void highlightBlock(const QString& text) override
          {
              QRegularExpressionMatchIterator matchIterator = hexColorPattern.globalMatch(text);
      
              while (matchIterator.hasNext())
              {
                  QRegularExpressionMatch match = matchIterator.next();
                  QString hexColor = match.captured(0);
                  QColor color(hexColor);
      
                  if (color.isValid())
                  {
                      qDebug() << hexColor;
                      //qDebug() << text;
                      //if (text == hexColor)
                      //{
                          QRect r = textEdit->cursorRect();
                          textEdit->colorRect = QRect(r.x(), r.y(), 16, 16);
                          textEdit->color = color;
                          textEdit->viewport()->update();
                      //}
      
                      QTextCharFormat colorFormat;
                      colorFormat.setForeground(color);
                      setFormat(match.capturedStart(), match.capturedLength(), colorFormat);
                  }
              }
          }
      };
      
      
      
      MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::QtWidgetsApplication14Class())
      {
          ui->setupUi(this);
      
          TextEdit* textEdit = new TextEdit(this);
          textEdit->setText(R"(
            #ff0000   ddd
      aa #ba00ff sdsd  #00ff00 abbc
      #00ffb4 xxxx
          )");
          setCentralWidget(textEdit);
          HtmlSyntax* htmlSyntax = new HtmlSyntax(textEdit);
      }
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Joeyy said in How to get the xy position of a text in a QTextEdit?:

      but I'm not figuring out how to properly save the text position

      What does this mean? Save where?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      J 1 Reply Last reply
      0
      • jsulmJ jsulm

        @Joeyy said in How to get the xy position of a text in a QTextEdit?:

        but I'm not figuring out how to properly save the text position

        What does this mean? Save where?

        J Offline
        J Offline
        Joeyy
        wrote on last edited by
        #3

        @jsulm Hi, I'm trying to render a colored square in front of each hex string -that represents a color-. I will also use the "square" positions, to detect when any of them get clicked so I can run a custom widget. The code I post is a work in progress, I'm not figuring out how to get each "hex string" position, to use at the QPaintEvent.

        jsulmJ 1 Reply Last reply
        0
        • J Joeyy

          @jsulm Hi, I'm trying to render a colored square in front of each hex string -that represents a color-. I will also use the "square" positions, to detect when any of them get clicked so I can run a custom widget. The code I post is a work in progress, I'm not figuring out how to get each "hex string" position, to use at the QPaintEvent.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Joeyy Maybe https://doc.qt.io/qt-6/qsyntaxhighlighter.html would be better?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          JonBJ 1 Reply Last reply
          0
          • jsulmJ jsulm

            @Joeyy Maybe https://doc.qt.io/qt-6/qsyntaxhighlighter.html would be better?

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

            @jsulm
            User code above already has class HtmlSyntax : public QSyntaxHighlighter, so OP is there already.

            @Joeyy
            I don't know, just an observation. QTextEdit and/or QSyntaxHighlighter are both document-based. That means they expect to work from text. I don't know how easy it will be for you, you are trying to insert and maintain a "graphical rectangle" in the middle of the document text. My thought would be, e.g. at any point the layout of the lines from the text might be changed, how would you keep up with this for your graphical rectangles? I don't suppose such exists, but if the text font can do a "filled-block" character (whose color you can alter) that would seem a better fit.

            J 1 Reply Last reply
            1
            • JonBJ JonB

              @jsulm
              User code above already has class HtmlSyntax : public QSyntaxHighlighter, so OP is there already.

              @Joeyy
              I don't know, just an observation. QTextEdit and/or QSyntaxHighlighter are both document-based. That means they expect to work from text. I don't know how easy it will be for you, you are trying to insert and maintain a "graphical rectangle" in the middle of the document text. My thought would be, e.g. at any point the layout of the lines from the text might be changed, how would you keep up with this for your graphical rectangles? I don't suppose such exists, but if the text font can do a "filled-block" character (whose color you can alter) that would seem a better fit.

              J Offline
              J Offline
              Joeyy
              wrote on last edited by
              #6

              @JonB whats a filled-block character? and how i could draw it, is it a html thing?

              JonBJ 1 Reply Last reply
              0
              • J Joeyy

                @JonB whats a filled-block character? and how i could draw it, is it a html thing?

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

                @Joeyy
                As I wrote I think it would have to be IF the font you are using defines such a character. I have no idea which fonts might do that. I do not know of an HTML entity for that, I think it would have to be a font feature.

                Wait a minute. There is a Unicode character https://www.htmlsymbols.xyz/unicode/U+2588 "Full block" character

                This character is typically used in creating graphical displays on a text-based terminal, for drawing diagrams, or for other graphical representation purposes within a text. It appears as a solid rectangle, filling the entire area of a character space. It's also frequently used in progress bars, bar graphs, and other user interface elements where a block of solid color can represent data or status visually.

                Just what you seem to want! Can you put that into HTML (I don't know)? Oh, yes, it includes there "HTML Forms and Input", looks like <span>&#9608;</span> would do it, produces █ :) Now you need to figure if you can get that into QTextEdit/QSyntaxHighlighter!

                J 1 Reply Last reply
                1
                • JonBJ JonB

                  @Joeyy
                  As I wrote I think it would have to be IF the font you are using defines such a character. I have no idea which fonts might do that. I do not know of an HTML entity for that, I think it would have to be a font feature.

                  Wait a minute. There is a Unicode character https://www.htmlsymbols.xyz/unicode/U+2588 "Full block" character

                  This character is typically used in creating graphical displays on a text-based terminal, for drawing diagrams, or for other graphical representation purposes within a text. It appears as a solid rectangle, filling the entire area of a character space. It's also frequently used in progress bars, bar graphs, and other user interface elements where a block of solid color can represent data or status visually.

                  Just what you seem to want! Can you put that into HTML (I don't know)? Oh, yes, it includes there "HTML Forms and Input", looks like <span>&#9608;</span> would do it, produces █ :) Now you need to figure if you can get that into QTextEdit/QSyntaxHighlighter!

                  J Offline
                  J Offline
                  Joeyy
                  wrote on last edited by Joeyy
                  #8

                  @JonB it would help but I would still need to know their position to detect when any of them get clicked and modify the color in front of it.

                  I'm trying to achieve something like this, from VSCode:

                  2ec4fa04-ae6f-4c2b-ac0c-1eb152811a14-Code_0G9nNbUtTh.gif

                  When a valid hex string is entered it renders a "rectangle", you can click it and it modifies the hex string with the color selected in the widget.

                  JonBJ 1 Reply Last reply
                  0
                  • J Joeyy

                    @JonB it would help but I would still need to know their position to detect when any of them get clicked and modify the color in front of it.

                    I'm trying to achieve something like this, from VSCode:

                    2ec4fa04-ae6f-4c2b-ac0c-1eb152811a14-Code_0G9nNbUtTh.gif

                    When a valid hex string is entered it renders a "rectangle", you can click it and it modifies the hex string with the color selected in the widget.

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

                    @Joeyy
                    But the difference is (I assume) this way it can be done by text coordinates, not trying to draw graphics things. You only need to know what character position the user is clicking into, then you can do something about going back/forward from there to find the block. And I presume QTextEdit can tell you where the cursor is in character rather than coordinate terms.

                    J 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @Joeyy
                      But the difference is (I assume) this way it can be done by text coordinates, not trying to draw graphics things. You only need to know what character position the user is clicking into, then you can do something about going back/forward from there to find the block. And I presume QTextEdit can tell you where the cursor is in character rather than coordinate terms.

                      J Offline
                      J Offline
                      Joeyy
                      wrote on last edited by Joeyy
                      #10

                      @JonB Oh I see, I think I got what you mean.
                      Do you have any idea how I could insert/remove the square according to when it detects a hex string in the highlightBlock function?

                      I have modified the function to:

                          void highlightBlock(const QString& text) override
                          {
                              QRegularExpressionMatchIterator matchIterator = hexColorPattern.globalMatch(text);
                              int offset = 0; // To keep track of the insertion offset
                      
                              while (matchIterator.hasNext())
                              {
                                  QRegularExpressionMatch match = matchIterator.next();
                      
                                  QString hexColor = match.captured(0);
                                  QColor color(hexColor);
                      
                                  if (color.isValid())
                                  {
                                      // Insert the "■" symbol in front of the hexColor string
                                      QString coloredSymbol = "<span style=\"color:" + color.name() + ";\">■</span>";
                                      textEdit->insertHtml(coloredSymbol);
                      
                                      QTextCharFormat colorFormat;
                                      colorFormat.setForeground(color);
                      
                                      // Apply the color format to the hexColor string
                                      setFormat(match.capturedStart() + offset, match.capturedLength(), colorFormat);
                      
                                      // Increment the offset by the length of the inserted symbol
                                      offset += coloredSymbol.length();
                                  }
                              }
                          }
                      

                      Now:
                      QtWidgetsApplication14_Ibc8zfHpNX.gif

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        Joeyy
                        wrote on last edited by
                        #11

                        This a new attempt, I'm not figuring out how to move the cursor to the correct position and also check if it doesn't already contains a ■ after the hex string:

                        class HtmlHighlighter : public QSyntaxHighlighter
                        {
                        public:
                            TextEdit* textEdit;
                            QRegularExpression colorPattern = QRegularExpression("#[0-9A-Fa-f]{6}");
                            HtmlHighlighter(TextEdit* parent) : QSyntaxHighlighter(parent), textEdit(parent) {}
                            
                        protected:
                            void highlightBlock(const QString& text) override
                            {
                                setCurrentBlockState(0);
                        
                                int startIndex = 0;
                                if (previousBlockState() != 1)
                                    startIndex = text.indexOf(colorPattern);
                        
                                while (startIndex >= 0)
                                {
                                    QRegularExpressionMatch match = colorPattern.match(text, startIndex);
                                    int endIndex = match.capturedStart();
                                    int colorLength = 0;
                        
                                    if (endIndex == -1)
                                    {
                                        setCurrentBlockState(1);
                                        colorLength = text.length() - startIndex;
                                    }
                                    else
                                        colorLength = endIndex - startIndex + match.capturedLength();
                        
                                    QString hexColor = match.captured(0);
                                    QColor color(hexColor);
                        
                                    if (color.isValid())
                                    {
                                        QTextCharFormat colorFormat;
                                        colorFormat.setForeground(color);
                                        setFormat(startIndex, colorLength, colorFormat);
                        
                                        startIndex = text.indexOf(colorPattern, startIndex + colorLength);
                        
                                        qDebug() << "startIndex: " << startIndex << "endIndex:" << endIndex;
                                        QTextCursor cursor(document());
                                        cursor.setPosition(endIndex);
                                        cursor.insertHtml("<span style=\"color:" + color.name() + ";\">■</span>");
                                    }
                                }
                            }
                        };
                        
                        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