例如。
我们创建一个样式类并将其设置为
verticalScrollBar
的QTextEdit
。
每当我们搜索文本时,我们都会重新绘制滚动条。
找到的值的比例为TextHeight / documentHeight。
.h
#ifndef TEXTEDIT_H
#define TEXTEDIT_H
#include <QTextEdit>
class TextEdit : public QTextEdit
{
Q_OBJECT
public:
TextEdit();
QList<qreal> m_findPoints;
QList<QTextEdit::ExtraSelection> m_exl;
void appendExtraSelection(QTextCursor& tc);
void searchText();
void searchRecursion(QString text, quint64 pos, QTextDocument::FindFlags& flags);
};
#endif // TEXTEDIT_H
.cpp
#include "TextEdit.h"
#include "qscrollbar.h"
TextEdit::TextEdit()
{
QString dummyText = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.""";
setPlainText(dummyText.repeated(30));
}
void TextEdit::searchText()
{
m_exl.clear();
QString text = "ad";
if (text.isEmpty())
return;
QTextDocument::FindFlags flags;
searchRecursion(text, 0, flags);
setExtraSelections(m_exl);
m_findPoints.clear();
for (QTextEdit::ExtraSelection& ex: m_exl)
{ // the rect of cursor
QRect r = cursorRect(ex.cursor);
// the bottom of cursor
qint64 bottom = static_cast<qreal>(r.bottom());
qreal height = static_cast<qreal>(viewport()->height());
// the ratio of bottom in current height
qreal findPoint = bottom / (document()->size().height());
// the relative position in scrollbar.
findPoint = height*findPoint;
// append the relative positio
m_findPoints.append(findPoint);
}
//force to call drawConplexControl of SearchableStyle
verticalScrollBar()->repaint();
}
void TextEdit::searchRecursion(QString text, quint64 pos, QTextDocument::FindFlags& flags)
{
QTextCursor tc = document()->find(text, pos, flags);
if (!tc.isNull())
{
appendExtraSelection(tc);
searchRecursion(text, tc.selectionEnd(), flags);
}
}
void TextEdit::appendExtraSelection(QTextCursor& tc)
{
QTextEdit::ExtraSelection ex;
QTextCharFormat format;
// Customize the format as needed
format.setForeground(QBrush(Qt::blue));
format.setBackground(QBrush(Qt::yellow));
ex.cursor = tc;
ex.format = format;
// Append the selection to the list
m_exl.append(ex);
}
.h
#ifndef SEARCHABLESTYLE_H
#define SEARCHABLESTYLE_H
#include <QProxyStyle>
class TextEdit;
class SearchableStyle : public QProxyStyle
{
Q_OBJECT
public:
SearchableStyle(TextEdit* textEdit);
TextEdit* m_textEdit;
void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const;
};
#endif // SEARCHABLESTYLE_H
样式.cpp
#include "SearchableStyle.h"
#include "..//MarkScrollBarTextEdit/TextEdit.h"
#include "qpainter.h"
SearchableStyle::SearchableStyle(TextEdit* textEdit)
{
m_textEdit = textEdit;
m_textEdit->m_findPoints = {};
}
void SearchableStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
{
if (control == QProxyStyle::CC_ScrollBar)
{
painter->setRenderHint(QPainter::Antialiasing);
//default painting
QProxyStyle::drawComplexControl(control, option, painter, widget);
QRect upperButtonRect = subControlRect(control, option, QProxyStyle::SC_ScrollBarAddLine, widget);
qreal barWidth = upperButtonRect.width() - 3;
// the minimal position of mark
qreal upperHeight = upperButtonRect.height();
QRect underButtonRect = subControlRect(control, option, QProxyStyle::SC_ScrollBarSubLine, widget);
// the maximam position of mark
qreal underHeight = underButtonRect.height();
qreal widgetHeight = widget->height();
qreal maxHeight = widgetHeight - underHeight;
// the color of mark : blue
painter->setPen(QPen(QColor(0, 0, 255)));
painter->setBrush(QBrush(QColor(0, 0, 255)));
//
foreach (qreal f, m_textEdit->m_findPoints){
if (f < upperHeight)
{
f = upperHeight;
}
else if (f > maxHeight)
{
f = maxHeight;
}
painter->drawRoundedRect(QRectF(2, f, barWidth, 1), 2, 2);
qDebug() << f;
}
// guard over painting
return;
}
QProxyStyle::drawComplexControl(control, option, painter, widget);
}
主.cpp
#include "MainWindow.h"
#include "TextEdit.h"
#include "qscrollbar.h"
#include "../PublicationTest3/SearchableStyle.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
TextEdit *t = new TextEdit();
SearchableStyle *s = new SearchableStyle(t);
t->verticalScrollBar()->setStyle(s);
w.setCentralWidget(t);
w.show();
t->searchText();
return a.exec();
}