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、运行结果图