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 create a QTextEdit with space for a caption in the border?
Forum Updated to NodeBB v4.3 + New Features

How to create a QTextEdit with space for a caption in the border?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 5 Posters 655 Views
  • 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.
  • N Offline
    N Offline
    n34rt
    wrote on last edited by
    #1

    How i could create a QTextEdit with a space for a caption like seen on gmail:

    enter image description here

    The result I got with the code below:

    enter image description here

    I figured a way to calculate where the top border should end (Before Email) and start again (after phone), but I not figured how to clear the border in the area where 'caption' is drawn.

    Example:


    // textedit.h
    class TextEdit : public QTextEdit
    {
        Q_OBJECT
    
    public:
        QLabel* caption;
        TextEdit(QWidget* parent = 0) : QTextEdit(parent)
        {
            caption = new QLabel(this);
            caption->setText("Email or phone");
            
            caption->setStyleSheet(R"(
                    font: 14px;
                    font-weight: 900;
                    color: #3762ab;
                    
                    border-radius: 4px;
                    background-color: rgba(0, 0, 0, 30);
                    margin-left: 32px;
            )");
            
            caption->adjustSize();
    
            auto caption_rect = caption->contentsRect();
    
            int caption_x = caption_rect.x();
            int caption_width = caption_rect.x() + caption_rect.width();
    
            qDebug() << "Position where the left border should end:\n" 
                << caption_x << "\n";
            qDebug() << "Position where the border start after the caption:\n" 
                << caption_width << "\n";        
        }
    };
    

    #include "textedit.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this);
        
        QTextEdit* textEdit = new TextEdit(this);
    
        ui.centralWidget->setStyleSheet("#centralWidget { background-color: #121212; }");
        textEdit->setStyleSheet(R"(
            QTextEdit
            {
                border-radius: 4px;
                border: 3px solid #3762ab; 
                background-color: transparent;
                margin-top: 10px;
            }
        )");
    
        textEdit->setGeometry(100, 50, 300, 70);
    }
    

    I think to achieve this I would need to draw the borders in the paintEvent, so i tried:

        void paintEvent(QPaintEvent* event)
        {
    
            QTextEdit::paintEvent(event);
            QPainter painter(viewport());
    
            int borderWidth = 4;
    
            QPen pen;
            pen.setWidth(borderWidth);
            //pen.setBrush(radialGrad);
            painter.setRenderHint(QPainter::Antialiasing, true);
    
            QPoint center = viewport()->rect().center();
            auto r = this->contentsRect();
    
            QPainterPath path;
            //path.lineTo(0, 0);
            //path.moveTo(r.width(), 4);
            //painter.setClipPath(path);
             
    
    
            // Top border
            pen.setColor(Qt::red);
            painter.setPen(pen);
    
            // Line before the caption
            painter.drawLine(QLine(0, 0, caption_x, borderWidth));
            // Line after the caption
            painter.drawLine(QLine(caption_width, 0, r.width(), borderWidth));
    
            
    
            // Left border
            pen.setColor(Qt::white);
            painter.setPen(pen);
            painter.drawLine(QLine(0, 0, borderWidth, r.height()));
    
    
    
            // Bottom border
            pen.setColor(Qt::green);
            painter.setPen(pen);
            painter.drawLine(QLine(0, r.height() - borderWidth, r.width(), r.height()));
    
    
    
            // Right border
            pen.setColor(Qt::blue);
            painter.setPen(pen);
            painter.drawLine(QLine(r.width() - borderWidth, 0, r.width(), r.height()));
    
        }
    

    Result:

    enter image description here

    I use different colors just to figure if each border was being drawn correctly...

    Btw, the borders looks weird, looks like they are being drawn with a different thickness, and i'm not sure how to draw the lines curved.

    JonBJ 1 Reply Last reply
    0
    • B Offline
      B Offline
      Bonnie
      wrote on last edited by
      #2

      Why don't use a QGroupBox with a QTextEdit inside it?

      1 Reply Last reply
      2
      • N n34rt

        How i could create a QTextEdit with a space for a caption like seen on gmail:

        enter image description here

        The result I got with the code below:

        enter image description here

        I figured a way to calculate where the top border should end (Before Email) and start again (after phone), but I not figured how to clear the border in the area where 'caption' is drawn.

        Example:


        // textedit.h
        class TextEdit : public QTextEdit
        {
            Q_OBJECT
        
        public:
            QLabel* caption;
            TextEdit(QWidget* parent = 0) : QTextEdit(parent)
            {
                caption = new QLabel(this);
                caption->setText("Email or phone");
                
                caption->setStyleSheet(R"(
                        font: 14px;
                        font-weight: 900;
                        color: #3762ab;
                        
                        border-radius: 4px;
                        background-color: rgba(0, 0, 0, 30);
                        margin-left: 32px;
                )");
                
                caption->adjustSize();
        
                auto caption_rect = caption->contentsRect();
        
                int caption_x = caption_rect.x();
                int caption_width = caption_rect.x() + caption_rect.width();
        
                qDebug() << "Position where the left border should end:\n" 
                    << caption_x << "\n";
                qDebug() << "Position where the border start after the caption:\n" 
                    << caption_width << "\n";        
            }
        };
        

        #include "textedit.h"
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
        {
            ui.setupUi(this);
            
            QTextEdit* textEdit = new TextEdit(this);
        
            ui.centralWidget->setStyleSheet("#centralWidget { background-color: #121212; }");
            textEdit->setStyleSheet(R"(
                QTextEdit
                {
                    border-radius: 4px;
                    border: 3px solid #3762ab; 
                    background-color: transparent;
                    margin-top: 10px;
                }
            )");
        
            textEdit->setGeometry(100, 50, 300, 70);
        }
        

        I think to achieve this I would need to draw the borders in the paintEvent, so i tried:

            void paintEvent(QPaintEvent* event)
            {
        
                QTextEdit::paintEvent(event);
                QPainter painter(viewport());
        
                int borderWidth = 4;
        
                QPen pen;
                pen.setWidth(borderWidth);
                //pen.setBrush(radialGrad);
                painter.setRenderHint(QPainter::Antialiasing, true);
        
                QPoint center = viewport()->rect().center();
                auto r = this->contentsRect();
        
                QPainterPath path;
                //path.lineTo(0, 0);
                //path.moveTo(r.width(), 4);
                //painter.setClipPath(path);
                 
        
        
                // Top border
                pen.setColor(Qt::red);
                painter.setPen(pen);
        
                // Line before the caption
                painter.drawLine(QLine(0, 0, caption_x, borderWidth));
                // Line after the caption
                painter.drawLine(QLine(caption_width, 0, r.width(), borderWidth));
        
                
        
                // Left border
                pen.setColor(Qt::white);
                painter.setPen(pen);
                painter.drawLine(QLine(0, 0, borderWidth, r.height()));
        
        
        
                // Bottom border
                pen.setColor(Qt::green);
                painter.setPen(pen);
                painter.drawLine(QLine(0, r.height() - borderWidth, r.width(), r.height()));
        
        
        
                // Right border
                pen.setColor(Qt::blue);
                painter.setPen(pen);
                painter.drawLine(QLine(r.width() - borderWidth, 0, r.width(), r.height()));
        
            }
        

        Result:

        enter image description here

        I use different colors just to figure if each border was being drawn correctly...

        Btw, the borders looks weird, looks like they are being drawn with a different thickness, and i'm not sure how to draw the lines curved.

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

        @n34rt
        As @Bonnie has said, have a look at QGroupBox. See if it suits your requirement, I'm not sure it looks identical on every platform but it's much simpler if it's acceptable to you.

        N 1 Reply Last reply
        0
        • JonBJ JonB

          @n34rt
          As @Bonnie has said, have a look at QGroupBox. See if it suits your requirement, I'm not sure it looks identical on every platform but it's much simpler if it's acceptable to you.

          N Offline
          N Offline
          n34rt
          wrote on last edited by
          #4

          @JonB hello i would like to get everything done inside of the TextEdit subclass instead of creating a QGroupBox for each TextEdit existing in the GUI.

          Do you have any idea why the borders are being drawn like that in the PaintEvent?

          Christian EhrlicherC 1 Reply Last reply
          0
          • N n34rt

            @JonB hello i would like to get everything done inside of the TextEdit subclass instead of creating a QGroupBox for each TextEdit existing in the GUI.

            Do you have any idea why the borders are being drawn like that in the PaintEvent?

            Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @n34rt said in How to create a QTextEdit with space for a caption in the border?:

            i would like to get everything done inside of the TextEdit subclass instead of creating a QGroupBox for each TextEdit existing in the GUI.

            I don't see a difference deriving from QLineEdit and using this custom widget or deriving from QWidget, add a QGroupBox and a QLineEdit in there and use this custom widget...

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            1
            • JoeCFDJ Offline
              JoeCFDJ Offline
              JoeCFD
              wrote on last edited by JoeCFD
              #6

              Basically the border of qtextedit covers the label since the label is a child of this=qtextedit. You need to overlay the label on top of the border of QTextEdit(this). Try to create caption with parent, not this=qtextedit. Then move it to the right position and no repaint is needed.

              With qgroupbox + lineedit without border will do the trick as well.

              1 Reply Last reply
              0
              • N Offline
                N Offline
                n34rt
                wrote on last edited by
                #7

                @JoeCFD said in How to create a QTextEdit with space for a caption in the border?:

                Basically the border of qtextedit covers the label since the label is a child of this=qtextedit. You need to overlay the label on top of the border of QTextEdit(this). Try to create caption with parent, not this=qtextedit. Then move it to the right position and no repaint is needed.

                Create the caption with what parent? as her parent is the TextEdit

                JoeCFDJ 1 Reply Last reply
                0
                • N n34rt

                  @JoeCFD said in How to create a QTextEdit with space for a caption in the border?:

                  Basically the border of qtextedit covers the label since the label is a child of this=qtextedit. You need to overlay the label on top of the border of QTextEdit(this). Try to create caption with parent, not this=qtextedit. Then move it to the right position and no repaint is needed.

                  Create the caption with what parent? as her parent is the TextEdit

                  JoeCFDJ Offline
                  JoeCFDJ Offline
                  JoeCFD
                  wrote on last edited by
                  #8

                  @n34rt

                     QLabel* caption;
                     TextEdit(QWidget* parent = 0) : QTextEdit(parent)
                     {
                         caption = new QLabel(parent);
                  
                  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