Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Drawing a cursor-like element in QtextEdit



  • Hi everyone, I am stuck trying to draw something that looks just like the normal blinking cursor in the textEdit in terms of position with respect to character. I need this because I am trying to display the postion of multiple users working simultaneously on the same document (something like Google Docs).

    The problem come when in the same line there are character of different size and font family. As I understood, the height of the textEdit cursor is not as it is visible: the cursor is as big as the biggest character in the line. As far as I know I can't have the baseline of a character. Althought, I managed this case with the following code (not very tidy but I hope still understandable):

            // Obtain rectangle of 'real' cursor
            // and the biggest font that can be contained
            const QRect curRect = this->cursorRect();
            QFont bigFont=this->font();
            bigFont.setPixelSize(curRect.height());
            QFontMetrics bigFontInfo(bigFont);
        
            // Obtain size of current font
            QFont thisFont=this->font();
            thisFont.setPointSize(this->fontPointSize());
            QFontMetrics thisFontInfo(thisFont);
            int thisFontHeight=thisFontInfo.height();
        
            // Obtain a rectangle that encloses the char, aligned to
            // the bottom of the 'real' cursor rectangle
            QRect thisRect=thisFontInfo.boundingRect(curRect, Qt::AlignBottom, "I");
        
            // Calculate where is the baseline of the current char
            // with respect to the one of the biggest char
            int biggerBaseline=curRect.bottom()-bigFontInfo.descent();
            int thisBaseline=thisRect.bottom()-thisFontInfo.descent();
            int baseLineDiff=abs(thisBaseline-biggerBaseline);
        
            int ty=thisRect.bottom()-thisFontInfo.descent()-thisFontHeight*0.85-baseLineDiff;
    
            labelName->show();
            labelCursor->show();
    
            labelCursor->move(curRect.topLeft().x()-1, ty);
            labelName->move(curRect.topLeft().x()+5, ty);
    

    And here there are some screenshots that show the result I obtain:
    Schermata del 2020-04-20 20-20-07.png Schermata del 2020-04-20 20-19-55.png

    So with sizes the probles is solved. But If I have also different font families (if they are particularly different from the "standard" ones, in the example is "Purisa") in the same line the result is very bad:
    Schermata del 2020-04-20 20-23-10.png Schermata del 2020-04-20 20-22-56.png

    How can I obtain a visual appearance like the first images independently on what are the fonts in the line?

    Hoping someone can help me, kind regards.


Log in to reply