Bootstrap

QTextEdit中插入特殊符号

Qt允许通过用QTextCharFormat注册一个自定义对象类型来将自定义文本对象插入到文档中。还必须为该类型实现一个QTextObjectInterface,并在文档的QAbstractTextDocumentLayout中注册。当渲染QTextDocument时遇到该对象类型时,接口的intrinsicSize()和drawObject()函数会被调用。

主要步骤如下:

1、选择一个对象类型。objectType是一个整数,其值大于或等于QTextFormat::UserObject。
2、创建一个QTextCharFormat对象,并使用setObjectType()函数将对象类型设置为所选类型。
3、实现QTextObjectInterface类。
4、用你的QTextObjectInterface子类的实例调用QAbstractTextDocumentLayout::registerHandler()来注册你的对象类型。
5、在文档中插入QChar::ObjectReplacementCharacter与前述所选对象类型的QTextCharFormat。如前所述,每当遇到替换字符时,QTextObjectInterface intrinsicSize()和drawObject()的函数将以QTextFormat为参数被调用。

自定义的textObject类需同时继承QObject以及QTextObjectInterface

示例代码如下:

1、CTextEdit

//CTextEdit.h
#ifndef CTEXTEDIT_H
#define CTEXTEDIT_H

#include<QTextEdit>

class CTextEdit : public QTextEdit
{
    Q_OBJECT
public:
    CTextEdit(QWidget* parent = nullptr);
};

#endif // CTEXTEDIT_H
//
//CTextEdit.cpp
#include "CTextEdit.h"
#include<QTextCharFormat>
#include"ChineseCharacterObject.h"

CTextEdit::CTextEdit(QWidget *parent)
    :QTextEdit(parent)
{
    setText("hello QTextEdit!a-");

    ChineseCharacterObject* cObj = new ChineseCharacterObject;
    cObj->setParent(this);
    document()->documentLayout()->registerHandler(ChineseCharacterObject::ChineseCharFormat,cObj);

    QTextCharFormat textcharFormat;
    textcharFormat.setObjectType(ChineseCharacterObject::ChineseCharFormat);
    textcharFormat.setProperty(ChineseCharacterObject::CharacterData,QVariant("aaa"));

    QTextCursor cursor = this->textCursor();
    cursor.movePosition(QTextCursor::End);
    cursor.insertText(QString(QChar::ObjectReplacementCharacter),textcharFormat);
    setTextCursor(cursor);
}
//

2、自定义textObject

#ifndef CHINESECHARACTEROBJECT1_H
#define CHINESECHARACTEROBJECT1_H

#include<QTextObjectInterface>
#include<QFont>

class QFontMetricsF;

class ChineseCharacterObject : public QObject,public QTextObjectInterface
{
    Q_OBJECT
    Q_INTERFACES(QTextObjectInterface)
public:
    enum
    {
        ChineseCharFormat = QTextCharFormat::UserObject + 1
    };
    enum ObjectProperties
    {
        CharacterData = 1
    };
    explicit ChineseCharacterObject();
    QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) override;
    void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc
                            , int posInDocument, const QTextFormat &format) override;
signals:

public slots:
private:
    QFontMetricsF* m_pFontMF;
    QFont m_Font;
};

#endif // CHINESECHARACTEROBJECT1_H

#include "ChineseCharacterObject.h"
#include<QPainter>

ChineseCharacterObject::ChineseCharacterObject()
{
    m_Font.setFamily("SimSun");
    m_Font.setPointSize(9);
    m_pFontMF = new QFontMetricsF(m_Font);
}

QSizeF ChineseCharacterObject::intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format)
{
    Q_UNUSED(doc)
    Q_UNUSED(posInDocument)
    QString txt = /*qvariant_cast<QString>*/(format.property(CharacterData).toString());
    return QSizeF(m_pFontMF->width(txt),m_pFontMF->height());
}

void ChineseCharacterObject::drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc
                                        , int posInDocument, const QTextFormat &format)
{
    Q_UNUSED(doc)
    Q_UNUSED(posInDocument)
    QString txt = /*qvariant_cast<QString>*/(format.property(CharacterData).toString());

    painter->fillRect(rect,QBrush(QColor("#ff00ff")));
    painter->drawText(rect,txt);
}

3、调用示例

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}
class CTextEdit;
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    CTextEdit* m_pTextEdit;
};

#endif // MAINWINDOW_H
///
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include<QTextCharFormat>
#include<QTextCursor>
#include<QVBoxLayout>
#include<QtSvg/QSvgRenderer>
#include<QDebug>
#include"ChineseCharacterObject.h"
#include"CTextEdit.h"

MainWindow::MainWindow(QWidget *parent)
    :QMainWindow(parent)
    ,ui(new Ui::MainWindow)
    ,m_pTextEdit(nullptr)
{
    ui->setupUi(this);
    m_pTextEdit = new CTextEdit(this);
    ui->verticalLayout->addWidget(m_pTextEdit);
    m_pTextEdit->hide();


}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    if(m_pTextEdit->isHidden())
    {
        m_pTextEdit->show();
        ui->pushButton->setText("hideTextEdit");
    }
    else
    {
        m_pTextEdit->hide();
        ui->pushButton->setText("showTextEdit");
    }
}

4、运行结果图

;