C++ (Qt)label->setText( tr( "Text <b>Bold text</b> <font color=red>Red text</font>" ) );
C++ (Qt)#include <QtGui/QTextLayout>#include <QtGui/private/qlineedit_p.h>#include <QtGui/QLineEdit>...class myEdit : public QLineEdit{ Q_OBJECTpublic: myEdit(QWidget *parent) : QLineEdit(parent) { } ~myEdit(){} using QObject::d_ptr;};... myEdit *edit = new myEdit(this); edit->setText("test"); edit->show(); QLineEditPrivate *pedit = (QLineEditPrivate *)edit->d_ptr; QTextLayout &lay = pedit->textLayout; qDebug() << lay.text();
C++ (Qt)// hardcoded in qlineedit.cpp#define verticalMargin 1#define horizontalMargin 2 /*!\reimp*/void MyLineEdit::paintEvent(QPaintEvent *){ Q_D(QLineEdit); QPainter p(this); QRect r = rect(); QPalette pal = palette(); QStyleOptionFrameV2 panel; initStyleOption(&panel); style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this); r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);#if QT_VERSION >= 0x040500 int left, top, right, bottom; getTextMargins(&left, &top, &right, &bottom); r.adjust(left, top, -right, -bottom);#endif p.setClipRect(r); QFontMetrics fm = fontMetrics(); Qt::Alignment va = QStyle::visualAlignment(layoutDirection(), QFlag(d->alignment)); switch (va & Qt::AlignVertical_Mask) { case Qt::AlignBottom: d->vscroll = r.y() + r.height() - fm.height() - verticalMargin; break; case Qt::AlignTop: d->vscroll = r.y() + verticalMargin; break; default: //center d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2; break; } QRect lineRect(r.x() + horizontalMargin, d->vscroll, r.width() - 2*horizontalMargin, fm.height()); QTextLine line = d->textLayout.lineAt(0); int cursor = d->cursor; if (d->preeditCursor != -1) cursor += d->preeditCursor; // locate cursor position int cix = qRound(line.cursorToX(cursor)); // horizontal scrolling. d->hscroll is the left indent from the beginning // of the text line to the left edge of lineRect. we update this value // depending on the delta from the last paint event; in effect this means // the below code handles all scrolling based on the textline (widthUsed, // minLB, minRB), the line edit rect (lineRect) and the cursor position // (cix). int minLB = qMax(0, -fm.minLeftBearing()); int minRB = qMax(0, -fm.minRightBearing()); int widthUsed = qRound(line.naturalTextWidth()) + 1 + minRB; if ((minLB + widthUsed) <= lineRect.width()) { // text fits in lineRect; use hscroll for alignment switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) { case Qt::AlignRight: d->hscroll = widthUsed - lineRect.width() + 1; break; case Qt::AlignHCenter: d->hscroll = (widthUsed - lineRect.width()) / 2; break; default: // Left d->hscroll = 0; break; } d->hscroll -= minLB; } else if (cix - d->hscroll >= lineRect.width()) { // text doesn't fit, cursor is to the right of lineRect (scroll right) d->hscroll = cix - lineRect.width() + 1; } else if (cix - d->hscroll < 0 && d->hscroll < widthUsed) { // text doesn't fit, cursor is to the left of lineRect (scroll left) d->hscroll = cix; } else if (widthUsed - d->hscroll < lineRect.width()) { // text doesn't fit, text document is to the left of lineRect; align // right d->hscroll = widthUsed - lineRect.width() + 1; } // the y offset is there to keep the baseline constant in case we have script changes in the text. QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->ascent - fm.ascent()); // draw text, selections and cursors#ifndef QT_NO_STYLE_STYLESHEET if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) { cssStyle->focusPalette(this, &panel, &pal); }#endif p.setPen(pal.text().color()); QVector<QTextLayout::FormatRange> selections;#ifdef QT_KEYPAD_NAVIGATION if (!QApplication::keypadNavigationEnabled() || hasEditFocus())#endif if (d->selstart < d->selend || (d->cursorVisible && d->maskData && !d->readOnly)) { QTextLayout::FormatRange o; if (d->selstart < d->selend) { o.start = d->selstart; o.length = d->selend - d->selstart; o.format.setBackground(pal.brush(QPalette::Highlight)); o.format.setForeground(pal.brush(QPalette::HighlightedText)); } else { // mask selection o.start = d->cursor; o.length = 1; o.format.setBackground(pal.brush(QPalette::Text)); o.format.setForeground(pal.brush(QPalette::Window)); } selections.append(o); } /*+*/ if (/* условия для выделения блока текста жирным */) {/*+*/ QTextLayout::FormatRange o;/*+*/ o.start = 3; // начало блока (первый символ)/*+*/ o.length = 4; // длина блока в символах/*+*/ o.format.setFontWeight(QFont::Bold);/*+*/ selections.append(o);/*+*/ } // Asian users see an IM selection text as cursor on candidate // selection phase of input method, so the ordinary cursor should be // invisible if we have a preedit string. d->textLayout.draw(&p, topLeft, selections, r); if (d->cursorVisible && !d->readOnly && !d->hideCursor) d->textLayout.drawCursor(&p, topLeft, cursor, style()->pixelMetric(QStyle::PM_TextCursorWidth));}
C++ (Qt)static void setLineEditTextFormat(QLineEdit* lineEdit, const QList<QTextLayout::FormatRange>& formats){ if(!lineEdit) return; QList<QInputMethodEvent::Attribute> attributes; foreach(const QTextLayout::FormatRange& fr, formats) { // [b]обязательно[/b] нужно отнять от требуемой стартовой позиции текущую позицию курсора. // можно обойтись без этого, если в начало и конец списка вставить специально подготовленные // атрибуты, но меня и такой вариант устраивает QInputMethodEvent::AttributeType type = QInputMethodEvent::TextFormat; int start = fr.start - lineEdit->cursorPosition(); int length = fr.length; QVariant value = fr.format; attributes.append(QInputMethodEvent::Attribute(type, start, length, value)); } QInputMethodEvent event(QString(), attributes); QCoreApplication::sendEvent(lineEdit, &event);} static void clearLineEditTextFormat(QLineEdit* lineEdit){ setLineEditTextFormat(lineEdit, QList<QTextLayout::FormatRange>());} // наглядный пример:QLineEdit* lineEdit = new QLineEdit;lineEdit->setText(tr("Task Tracker - Entry")); QList<QTextLayout::FormatRange> formats; QTextCharFormat f; f.setFontWeight(QFont::Bold);QTextLayout::FormatRange fr_task;fr_task.start = 0;fr_task.length = 4;fr_task.format = f; f.setFontItalic(true);f.setBackground(Qt::darkYellow);f.setForeground(Qt::white);QTextLayout::FormatRange fr_tracker;fr_tracker.start = 5;fr_tracker.length = 7;fr_tracker.format = f; f = QTextCharFormat();f.setForeground(Qt::gray);QTextLayout::FormatRange fr_entry;fr_entry.start = 15;fr_entry.length = 5;fr_entry.format = f; formats.append(fr_task);formats.append(fr_tracker);formats.append(fr_entry); customizeLineEditText(lineEdit, formats);
C++ (Qt)void MyLineEdit::inputMethodEvent(QInputMethodEvent *e){ bool wasReadOnly = isReadOnly(); if(wasReadOnly) setReadOnly(false); QLineEdit::inputMethodEvent(QInputMethodEvent *e); setReadOnly(wasReadOnly);}