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. Change font on QTextCursor before start typing any text
Forum Updated to NodeBB v4.3 + New Features

Change font on QTextCursor before start typing any text

Scheduled Pinned Locked Moved Unsolved General and Desktop
desktoptexteditqtextdocumentqtextcursor
6 Posts 3 Posters 263 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.
  • D Online
    D Online
    Deymos
    wrote last edited by Deymos
    #1

    Hello,

    I'm working on a text editor using QML TextArea and a C++ backend with QTextDocument, QTextCursor, etc.

    I’m facing an issue with font formatting behavior when applying font changes via QTextCursor::setCharFormat() or QTextCursor::mergeCharFormat().

    Here’s the situation:
    When I change the font (e.g., via a combo box) and have no text selected or document is empty, I apply the new font using:

    void DocumentHandler::setFont(const QFont & font){
    
        QTextCursor cursor = textCursor();
        if (!cursor.isNull() && cursor.charFormat().font() == font)
            return;
    
        auto temp = font;
    
        if(font.pointSize() > 0)
        {
            temp.setPointSize(cursor.charFormat().font().pointSize());
        }
        else if(font.pixelSize() > 0){
            temp.setPixelSize(cursor.charFormat().font().pixelSize());
        }
    
        QTextCharFormat format;
        format.setFont(temp);
    
        mergeFormatOnWordOrSelection(format);
        emit fontChanged();
    }
    
    void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
    {
        QTextCursor cursor = textCursor();
        if (!cursor.hasSelection())
            cursor.select(QTextCursor::WordUnderCursor);
        cursor.mergeCharFormat(format);
        // cursor.setBlockCharFormat(format); //!! CRASH, need another way...
    }
    

    However, if I click somewhere in the document (e.g., in an empty line or at the end of the document), the cursor seems to "forget" the previously set font and reverts back to the default font.

    I expect that after setting font via setCharFormat(), and clicking inside the document or starting a new paragraph would preserve the last applied character format , just like in most word processors (e.g., Word, Google Docs).

    What I’ve tried:

    • Using mergeBlockCharFormat() instead of mergeCharFormat()
    • Setting the default font for the entire QTextDocument before editing
    • Checking whether the cursor is in a "valid" position after clicking

    Can I set a QTextCharFormat in QTextCursor that will be supported on the next input?
    there is also no such functionality in the official example, the format can only be changed if a word is highlighted or the cursor is on a word.

    I'm thinking about making a workaround: make pending changes, display them on the UI, and when the user enters the text, immediately apply the pending changes, but I still hope that there is a way to do this natively.

    Thank you.

    jsulmJ 1 Reply Last reply
    0
    • D Deymos

      Hello,

      I'm working on a text editor using QML TextArea and a C++ backend with QTextDocument, QTextCursor, etc.

      I’m facing an issue with font formatting behavior when applying font changes via QTextCursor::setCharFormat() or QTextCursor::mergeCharFormat().

      Here’s the situation:
      When I change the font (e.g., via a combo box) and have no text selected or document is empty, I apply the new font using:

      void DocumentHandler::setFont(const QFont & font){
      
          QTextCursor cursor = textCursor();
          if (!cursor.isNull() && cursor.charFormat().font() == font)
              return;
      
          auto temp = font;
      
          if(font.pointSize() > 0)
          {
              temp.setPointSize(cursor.charFormat().font().pointSize());
          }
          else if(font.pixelSize() > 0){
              temp.setPixelSize(cursor.charFormat().font().pixelSize());
          }
      
          QTextCharFormat format;
          format.setFont(temp);
      
          mergeFormatOnWordOrSelection(format);
          emit fontChanged();
      }
      
      void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
      {
          QTextCursor cursor = textCursor();
          if (!cursor.hasSelection())
              cursor.select(QTextCursor::WordUnderCursor);
          cursor.mergeCharFormat(format);
          // cursor.setBlockCharFormat(format); //!! CRASH, need another way...
      }
      

      However, if I click somewhere in the document (e.g., in an empty line or at the end of the document), the cursor seems to "forget" the previously set font and reverts back to the default font.

      I expect that after setting font via setCharFormat(), and clicking inside the document or starting a new paragraph would preserve the last applied character format , just like in most word processors (e.g., Word, Google Docs).

      What I’ve tried:

      • Using mergeBlockCharFormat() instead of mergeCharFormat()
      • Setting the default font for the entire QTextDocument before editing
      • Checking whether the cursor is in a "valid" position after clicking

      Can I set a QTextCharFormat in QTextCursor that will be supported on the next input?
      there is also no such functionality in the official example, the format can only be changed if a word is highlighted or the cursor is on a word.

      I'm thinking about making a workaround: make pending changes, display them on the UI, and when the user enters the text, immediately apply the pending changes, but I still hope that there is a way to do this natively.

      Thank you.

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote last edited by
      #2

      @Deymos said in Change font on QTextCursor before start typing any text:

      cursor.mergeCharFormat(format);

      Aren't you changing a copy here?

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

      D 1 Reply Last reply
      0
      • jsulmJ jsulm

        @Deymos said in Change font on QTextCursor before start typing any text:

        cursor.mergeCharFormat(format);

        Aren't you changing a copy here?

        D Online
        D Online
        Deymos
        wrote last edited by
        #3

        @jsulm said in Change font on QTextCursor before start typing any text:

        Aren't you changing a copy here?

        Yes, but as I understand it, there is no other way to get a QTextCursor other than

        QTextCursor DocumentHandler::textCursor() const
        {
            QTextDocument *doc = textDocument();
            if (!doc)
                return QTextCursor();
        
            QTextCursor cursor = QTextCursor(doc);
            return cursor;
        }
        
        1 Reply Last reply
        0
        • Axel SpoerlA Offline
          Axel SpoerlA Offline
          Axel Spoerl
          Moderators
          wrote last edited by
          #4

          There is an architectural glitch IMHO.
          The code gets a text cursor, allocated on the heap. The char format is merged and the cursor object goes out of scope. So the function:

          void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
          {
              QTextCursor cursor = textCursor();
              if (!cursor.hasSelection())
                  cursor.select(QTextCursor::WordUnderCursor);
              cursor.mergeCharFormat(format);
              // cursor.setBlockCharFormat(format); //!! CRASH, need another way...
          }
          

          has no effect.

          That's only a speculation by code reading.
          Maybe you can condense it down to a very very small reproducer.

          Software Engineer
          The Qt Company, Oslo

          1 Reply Last reply
          0
          • Axel SpoerlA Offline
            Axel SpoerlA Offline
            Axel Spoerl
            Moderators
            wrote last edited by
            #5

            Correction, my mistake found by @JonB: Allocated on the stack, not on the heap!

            Software Engineer
            The Qt Company, Oslo

            D 1 Reply Last reply
            0
            • Axel SpoerlA Axel Spoerl

              Correction, my mistake found by @JonB: Allocated on the stack, not on the heap!

              D Online
              D Online
              Deymos
              wrote last edited by
              #6

              @Axel-Spoerl
              I took this method from the example of the Qt text editor, it works if any text is selected with this cursor, and continues typing with this cursor with the specified font further.
              But here's the problem, if I want the behavior as in standard text editors, to first set the font modifiers and then start typing, the font in the cursor is reset to the standard one from QTextDocument.
              The option to store the cursor in the heap is unlikely to work, since it is impossible to set the cursor in the QTextDocument.

              At the moment, I have solved the problem using "Pending font", if the cursor does not have any text under it, I write all font changes to the QFont variable, and display font data from it on the UI, and as soon as the user enters something, I immediately apply font settings to the entered character, so far it works quite well.

              But if it is possible to change the font settings for future input without workarounds, I would be glad to know.

              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