Qt 文本编辑,在滚动条中带有书签

问题描述 投票:0回答:1

我想在文本中搜索单词时为我的文本编辑器创建书签,滚动条应该像在 qt 编辑器中一样将条着色为绿色。

我需要帮助!您是否有想法在搜索单词时访问滚动条并为其着色?

qt qt5 finder qpainter qtextedit
1个回答
0
投票

例如。

我们创建一个样式类并将其设置为

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();

}

© www.soinside.com 2019 - 2024. All rights reserved.