Results 1 to 9 of 9

Thread: Custom LineEdit - need help!

  1. #1
    Join Date
    Nov 2009
    Posts
    22
    Thanks
    2

    Default Custom LineEdit - need help!

    Greetings. Instead of using QStyle, I have sub-classed QLineEdit and reimplemented the paintEvent function (don't ask why) for custom look. It looks almost finished, but I have a problem with the cursor. The position of the cursor is not being rendered correctly, and I've tried different things without success. If I directly draw the cursor position then it gets better, but it still starts to show problems when the line is filled with more text. It gets much worse with QTextLayout, and I don't find the documentation very helpful.

    Here is what I've got so far. Much of it I got from Qt after studying the source code. I've intentionally given the LineEdit a fixed size to make sure the alignment is as it should be.

    Qt Code:
    1. #include <QtGui>
    2. #include <QtCore>
    3.  
    4. class Edit : public QLineEdit{
    5.  
    6. public:
    7. Edit(const QString &t, QWidget *pParent = 0) : QLineEdit(t, pParent){
    8. font = QFont("Sans");
    9. font.setPixelSize(12);
    10. setFixedSize(640, 220);
    11. setTextMargins(4, 0, 4, 0);
    12. }
    13.  
    14. protected:
    15. void paintEvent(QPaintEvent *pEvent){
    16.  
    17. QPainter painter(this);
    18. QRect r = rect();
    19.  
    20. //frame
    21. int x2 = r.width() - 1, y2 = r.height() - 1;
    22. painter.fillRect(r, QBrush(QColor(79, 79, 104, 255)));
    23. painter.setPen(QPen(QColor(64, 64, 64, 255), 1));
    24. painter.drawLine(0, 0, x2, 0);
    25. painter.drawLine(0, 0, 0, y2);
    26. painter.setPen(QPen(QColor(92, 92, 92, 255), 1));
    27. painter.drawLine(x2, y2, 1, y2);
    28. painter.drawLine(x2, y2, x2, 1);
    29. painter.setPen(QPen(QColor(19, 19, 19, 255), 1));
    30. painter.drawRect(QRect(1, 1, r.width() - 3, r.height() - 3));
    31.  
    32. //set clipping
    33. int lm, tm, rm, bm;
    34. getTextMargins(&lm, &tm, &rm, &bm);
    35. r.setX(r.x() + lm);
    36. r.setY(r.y() + tm);
    37. r.setRight(r.right() - rm);
    38. r.setBottom(r.bottom() - bm);
    39. painter.setClipRect(r);
    40.  
    41. painter.setPen(QPen(QColor(196, 196, 196, 255), 1));
    42. QFontMetrics fm(font);
    43. QTextLayout tl(text(), font, this);
    44. tl.beginLayout();
    45. QTextLine line = tl.createLine();
    46. if( !line.isValid() ){ return; }
    47. tl.endLayout();
    48. QRect lineRect(r.x(), r.y() + (r.height() - qRound(line.height()) + 1) / 2,
    49. r.width() - 1, qRound(line.height()));
    50. //painter.drawRect(lineRect);
    51. int ccc = cursorPosition();
    52. int cix = qRound(line.cursorToX(&ccc));
    53. int minLB = qMax(0, -fm.minLeftBearing());
    54. int minRB = qMax(0, -fm.minRightBearing());
    55. int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB;
    56. int hscroll;
    57.  
    58. if( (minLB + widthUsed) <= lineRect.width() ){
    59. hscroll = 0;
    60. hscroll -= minLB;
    61. }else if( cix - hscroll >= lineRect.width() ){
    62. hscroll = cix - lineRect.width() + 1;
    63. }else if( cix - hscroll < 0 && hscroll < widthUsed ){
    64. hscroll = cix;
    65. }else if( widthUsed - hscroll < lineRect.width() ){
    66. hscroll = widthUsed - lineRect.width() + 1;
    67. }
    68. QPoint topLeft = lineRect.topLeft() -
    69. QPoint(hscroll, line.ascent() - fm.ascent());
    70.  
    71. QVector<QTextLayout::FormatRange> selections;
    72. QTextLayout::FormatRange o;
    73. if( hasSelectedText() ){
    74. o.start = selectionStart();
    75. o.length = selectedText().length();
    76. o.format.setBackground(QColor(88, 101, 134, 255));
    77. o.format.setForeground(QColor(196, 196, 196, 255));
    78. selections.append(o);
    79. }
    80. tl.draw(&painter, topLeft, selections);
    81. painter.setPen(QPen(QColor(200, 0, 0, 255), 2));
    82. //painter.drawLine(cix, lineRect.y(), cix, lineRect.y() + lineRect.height());
    83. tl.drawCursor(&painter, topLeft, cix, 2);
    84. }
    85.  
    86. private:
    87. QFont font;
    88. };
    89.  
    90. int main(int argc, char *argv[]){
    91.  
    92. QApplication a(argc, argv);
    93.  
    94. QWidget *w = new QWidget;
    95. w->setPalette(QPalette(QColor(77, 77, 77, 255)));
    96. QHBoxLayout *l = new QHBoxLayout(w);
    97. Edit *e1 = new Edit(QString("test1"));
    98. QLineEdit *e2 = new QLineEdit(QString("test2"));
    99. e2->setFixedSize(640, 220);
    100. l->addWidget(e1);
    101. l->addWidget(e2);
    102. w->show();
    103.  
    104. return a.exec();
    105. }
    To copy to clipboard, switch view to plain text mode 

    Any idea why QTextLayout doesn't render the cursor properly?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Custom LineEdit - need help!

    Could you provide some info on what you get and what you want? An image would be nice...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Nov 2009
    Posts
    22
    Thanks
    2

    Default Re: Custom LineEdit - need help!

    It would be difficult with a picture, that's why I wrote a small program, but the problem is this: The cursor (the red vertical line) isn't rendered where you click the text. Also, trying to move the cursor with the left and right keys makes the cursor jump several characters and it never goes where it's supposed to.

    It's as if QLineEdit::cursorPosition() doesn't return the correct value, but it does as far as I can tell. For some reason QTextLayout::drawCursor() doesn't render the cursor properly.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Custom LineEdit - need help!

    Maybe the painter is prepared incorrectly?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Nov 2009
    Posts
    22
    Thanks
    2

    Default Re: Custom LineEdit - need help!

    If you uncomment the last commented-out line, the painter draws a vertical line where the cursor should go. That's much more accurate than what the QTextLayout::draw() renders, but it's still off. Somehow there is a miscalculation.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Custom LineEdit - need help!

    Check the implementation of drawCursor(), maybe it does some painter transformations prior to drawing the cursor. Maybe this will fix the difference between your line and drawCursor(). If the line itself is at a wrong position then I'd assume your earlier calculations don't take some aspect into consideration. Check the source code for QLineEdit again and see if you didn't miss something.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Nov 2009
    Posts
    22
    Thanks
    2

    Default Re: Custom LineEdit - need help!

    pfff... finally, I fixed it. I had to reimplement the QLineEdit::mousePressEvent() and QLineEdit::mouseMoveEvent() methods to calculate the cursor position and call setCursorPosition().

  8. #8
    Join Date
    Nov 2009
    Location
    Sacramento, CA
    Posts
    24
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Custom LineEdit - need help!

    Could you post your code for the mouse events?

  9. #9
    Join Date
    Jan 2008
    Location
    Brasil
    Posts
    131
    Thanks
    18
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Custom LineEdit - need help!

    Send image for us.

Similar Threads

  1. setFocus() on Lineedit
    By qtuser20 in forum Qt Programming
    Replies: 1
    Last Post: 26th February 2010, 19:54
  2. Custom Model? Custom View? Custom Delegate?
    By Doug Broadwell in forum Newbie
    Replies: 4
    Last Post: 11th February 2010, 21:23
  3. Help on using QTableWidget with LineEdit.
    By narendra in forum Qt Programming
    Replies: 3
    Last Post: 31st December 2009, 16:30
  4. lineedit in qpainter
    By Devoraz in forum Newbie
    Replies: 9
    Last Post: 5th August 2009, 02:52
  5. Get Color from LineEdit
    By raphaelf in forum Newbie
    Replies: 4
    Last Post: 15th May 2007, 16:30

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.