【Qt之QTextDocument】使用
- 描述
- 常用方法及示例
- 使用QTextList
- 使用QTextBlock
- 使用QTextTable
- 表格顯示富文本
- 結論
描述
QTextDocument
類保存格式化的文本。
QTextDocument
是結構化富文本文檔的容器,支持樣式文本和各種文檔元素,如列表、表格、框架和圖像。它們可以用于創建QTextEdit
,也可以單獨使用。
每個文檔元素由一個相關的格式對象描述。每個格式對象都被QTextDocuments
視為唯一的對象,并且可以通過objectForFormat()
傳遞以獲取應用于它的文檔元素。
可以使用QTextCursor
以編程方式編輯QTextDocument
,并通過遍歷文檔結構來檢查其內容。整個文檔結構都存儲在根框架下的文檔元素層次結構中,可以使用rootFrame()
函數找到。或者,如果只想迭代文檔的文本內容,可以使用begin()
、end()
和findBlock()
檢索文本塊,以便檢查和迭代。
文檔的布局由documentLayout()
確定;如果要使用自己的布局邏輯,則可以創建自己的QAbstractTextDocumentLayout
子類,并使用setDocumentLayout()
設置它。可以通過調用metaInformation()
函數獲取文檔的標題和其他元信息。對于通過QTextEdit
類向用戶公開的文檔,文檔標題也可以通過QTextEdit::documentTitle()
函數獲得。
toPlainText()
和toHtml()
便利函數允許以純文本
和HTML格式
檢索文檔的內容。可以使用find()
函數搜索文檔的文本。
可以使用setUndoRedoEnabled()
函數控制對文檔執行的操作的撤消/重做。通過undo()
和redo()
插槽可以控制撤消/重做系統;文檔還提供了contentsChanged()
、undoAvailable()
和redoAvailable()
信號,通知連接的編輯器部件有關撤消/重做系統的狀態。
以下是QTextDocument
的撤消/重做操作:
- 插入或刪除字符。在同一文本塊內插入或刪除的序列被視為單個撤消/重做操作。
- 插入或刪除文本塊。在單個操作中的插入或刪除序列(例如通過選擇然后刪除文本)被視為單個撤消/重做操作。
- 文本字符格式更改。
- 文本塊格式更改。
- 文本塊組格式更改。
常用方法及示例
void addResource(int type, const QUrl &name, const QVariant &resource)
: 添加資源。將資源資源添加到資源緩存中,使用類型和名稱作為標識符。type應該是QTextDocument::ResourceType中的值。QVariant resource(int type, const QUrl &name) const
: 獲取資源。從具有給定名稱的資源返回指定類型的數據。
富文本引擎調用這個函數來請求沒有直接存儲在QTextDocument中,但仍然與之關聯的數據。例如,圖像通過QTextImageFormat對象的name屬性間接引用。
資源在文檔內部緩存。如果在緩存中找不到資源,則調用loadResource來嘗試加載該資源。然后loadResource應該使用addResource將資源添加到緩存中。
QTextDocument* doc = ui->textEdit->document();QImage image(":/images/xxx.png");doc->addResource(QTextDocument::ImageResource, QUrl("qrc:/images/xxx.png"), QVariant(image));// 在文檔中插入圖像QTextCursor cursor(doc);cursor.insertImage(doc->resource(QTextDocument::ImageResource, QUrl("qrc:/images/xxx.png")).value<QImage>());
使用addResource()
方法的好處主要包括:
- 方便管理:該方法允許您將資源(如樣式表、圖像等)添加到文檔中,并將其存儲在內存中,以便在需要時進行訪問。這樣可以使資源的管理更加集中和方便。
- 提高效率:通過將資源添加到文檔中,您可以在整個文檔中重復使用這些資源,而無需每次都從磁盤或網絡中加載。這可以減少加載時間,提高應用程序的響應速度。
- 易于維護:使用
addResource()
方法將資源添加到文檔中,可以使應用程序的資源管理更加清晰和有序。這使得資源的更新和替換變得更加簡單,因為您只需在文檔中修改相應的資源即可。 - 支持重用:通過將資源添加到文檔中,您可以輕松地在不同的應用程序或文檔中使用相同的資源。這有助于減少重復代碼,提高代碼的可重用性。
- 支持動態內容:
addResource()
方法允許您根據需要動態添加和更新資源。這使得在運行時根據用戶交互或其他事件動態更改文檔內容變得更加容易。
QTextBlock begin() const
: 返回文檔的第一個文本塊。QTextBlock end() const
: 該函數返回一個塊,用于在迭代文檔時測試文檔的結尾。返回的塊是無效的,并且表示文檔中最后一個塊之后的塊。您可以使用lastBlock()來檢索文檔的最后一個有效塊。
for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())qDebug().noquote() << it.text();
QTextBlock firstBlock() const
: 返回文檔的第一個文本塊內容。QTextBlock lastBlock() const
: 返回文檔的最后一個文本塊內容。
doc->firstBlock().text();
doc->lastBlock().text();
bool QTextDocument::isEmpty() const
: 如果文檔為空,返回true;否則返回false。bool QTextDocument::isRedoAvailable() const
: 如果可重做,則返回true;否則返回false。bool QTextDocument::isUndoAvailable() const
: 如果可撤消,則返回true;否則返回false。QTextBlock QTextDocument::lastBlock() const
: 返回文檔的最后一個(有效的)文本塊。int QTextDocument::lineCount() const
: 返回此文檔的行數(如果布局支持此項)。否則,這與塊數相同。
doc->isEmpty();
- 枚舉:enum QTextDocument::FindFlag
- 獲取枚舉值:flags QTextDocument::FindFlags
這個enum
描述QTextDocument
的find
函數可用的選項。這些選項可以從以下列表中進行OR-ed
組合:
常量 | 值 | 描述 | 解釋 |
---|---|---|---|
QTextDocument::FindBackward | 0x00001 | Search backwards instead of forwards. | 向后搜索而不是向前搜索。 |
QTextDocument::FindCaseSensitively | 0x00002 | By default find works case insensitive. Specifying this option changes the behaviour to a case sensitive find operation. | 默認情況下,find不區分大小寫。指定此選項會將行為更改為區分大小寫的查找操作。 |
QTextDocument::FindWholeWords | 0x00004 | Makes find match only complete words. | 使查找只匹配完整的單詞。 |
QTextCursor find(const QString &subString, const QTextCursor &cursor, FindFlags options = FindFlags()) const
查找給定字符串subString
在cursor
所代表的文本中的位置,返回一個文本光標,該光標指向找到的文本。如果未找到匹配的字符串,則返回一個空的光標。可以設置查找選項options
,例如大小寫敏感、全字匹配等。QTextCursor find(const QString &subString, int position = 0, FindFlags options = FindFlags()) const
查找給定字符串subString
在當前文本中的指定位置position
處開始查找,返回一個文本光標,該光標指向找到的文本。如果未找到匹配的字符串,則返回一個空的光標。可以設置查找選項options
,例如大小寫敏感、全字匹配等。QTextCursor find(const QRegExp &expr, int from = 0, FindFlags options = FindFlags()) const
使用正則表達式expr
在當前文本中的指定位置from
處開始查找,返回一個文本光標,該光標指向找到的文本。如果未找到匹配的字符串,則返回一個空的光標。可以設置查找選項options
,例如大小寫敏感、全字匹配等。QTextCursor find(const QRegExp &expr, const QTextCursor &cursor, FindFlags options = FindFlags()) const
使用正則表達式expr
在cursor
所代表的文本中的位置查找,返回一個文本光標,該光標指向找到的文本。如果未找到匹配的字符串,則返回一個空的光標。可以設置查找選項options
,例如大小寫敏感、全字匹配等。QTextCursor find(const QRegularExpression &expr, int from = 0, FindFlags options = FindFlags()) const
使用正則表達式expr
在當前文本中的指定位置from
處開始查找,返回一個文本光標,該光標指向找到的文本。如果未找到匹配的字符串,則返回一個空的光標。可以設置查找選項options
,例如大小寫敏感、全字匹配等。QTextCursor find(const QRegularExpression &expr, const QTextCursor &cursor, FindFlags options = FindFlags()) const
使用正則表達式expr
在cursor
所代表的文本中的位置查找,返回一個文本光標,該光標指向找到的文本。如果未找到匹配的字符串,則返回一個空的光標。可以設置查找選項options
,例如大小寫敏感、全字匹配等。
QTextDocument* pDoc = ui->textEdit->document();pDoc->setPlainText("helloworld");QTextCursor cursor = ui->textEdit->textCursor();cursor.insertText("\n");cursor.insertText("earth");cursor.insertText("\n");cursor.insertText("sun");// 輸出查找到的位置,從后往前查找qDebug() << pDoc->find(QRegularExpression("ear"), cursor.position(), QTextDocument::FindBackward).position();// 以下查找到會自動選擇匹配到的ui->textEdit->find("ear", QTextDocument::FindBackward);
- 枚舉:enum QTextDocument::MetaInformation
這個枚舉描述了可以添加到文檔中的不同類型的元信息。
常量 | 值 | 描述 | 解釋 |
---|---|---|---|
QTextDocument::DocumentTitle | 0 | The title of the document. | 文件的標題。 |
QTextDocument::DocumentUrl | 1 | The url of the document. The loadResource() function uses this url as the base when loading relative resources. | 文檔的url。loadResource()函數在加載相關資源時使用此url作為基。 |
- QString metaInformation(MetaInformation info) const
void setMetaInformation(MetaInformation info, const QString &string)
: 將由info指定的類型的文檔元信息設置為給定的字符串。
pDoc->setMetaInformation(QTextDocument::DocumentTitle, "helloworld");qDebug() << pDoc->metaInformation(QTextDocument::DocumentTitle);
23. 獲取文本塊數目、行數、是否編輯、是否為空等操作
// 文本塊數目qDebug() << pDoc->blockCount();// 行數qDebug() << pDoc->lineCount();// 是否是空qDebug() << pDoc->isEmpty();// 是否編輯qDebug() << pDoc->isModified();// 是否執行RedoqDebug() << pDoc->isRedoAvailable();// 是否執行UndoqDebug() << pDoc->isUndoAvailable();// Undo和Redo是否使能qDebug() << pDoc->isUndoRedoEnabled();
24. void setHtml(const QString &html)
pDoc->setHtml("<p style='color:#ff0000;'>helloworld</p>");
25. void setPlainText(const QString &text)
使用此方法,會將textEdit.setTextColor()方法設置的文本顏色失效。
pDoc->setPlainText("helloworld");
使用QTextList
QTextDocument* pDoc = ui->textEdit->document();pDoc->setPlainText("helloworld\n");QTextCursor cursor(pDoc);QTextListFormat listFormat;listFormat.setStyle(QTextListFormat::ListDecimal); // 使用有序列表QTextList * pList = cursor.insertList(listFormat);cursor.insertText("Item 1\n");cursor.insertText("Item 2\n");cursor.insertText("Item 3");QTextList* list = cursor.currentList();qDebug() << list->count();if (list) {QTextBlock currentItem = list->item(0);// 處理列表中的第一個項QString text = currentItem.text();qDebug() << text;}
使用QTextBlock
QTextDocument* pDoc = ui->textEdit->document();QTextCursor cursor(pDoc);cursor.insertText("\n");cursor.insertText("Hello, World!");QTextBlock currentBlock = pDoc->firstBlock();while (currentBlock.isValid()) {QString text = currentBlock.text();// 處理當前段落的文本內容qDebug() << text;currentBlock = currentBlock.next();}
使用QTextTable
QTextDocument* pDoc = ui->textEdit->document();// pDoc->setPlainText("helloworld\n");QTextCursor cursor(pDoc);QTextTableFormat tableFormat;tableFormat.setBorder(1);tableFormat.setCellPadding(5);tableFormat.setAlignment(Qt::AlignCenter);cursor.insertTable(3, 2, tableFormat);QTextTable* table = cursor.currentTable();if (table) {for (int row = 0; row < table->rows(); ++row) {for (int col = 0; col < table->columns(); ++col) {QTextTableCell cell = table->cellAt(row, col);QTextCursor cellCursor = cell.firstCursorPosition();cellCursor.insertText(QString("Row %1, Col %2").arg(row).arg(col));}}}
表格顯示富文本
QTableWidget
是Qt框架提供的一個用于顯示表格數據的控件。然而,QTableWidget
本身并不直接支持富文本(rich text)的顯示。如果需要在QTableWidget
中顯示富文本,一種方法是使用QTableWidgetItem
的setData
方法,將富文本作為自定義數據存儲在表格中,然后在單元格的渲染過程中使用自定義的QStyledItemDelegate
來顯示這些數據。
#include <QApplication>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QTextDocument>
#include <QTextCharFormat>
#include <QTextCursor>
#include <QStyledItemDelegate>class RichTextDelegate : public QStyledItemDelegate {
public:explicit RichTextDelegate(QTableWidget* pTW){m_pTW = pTW;}
public:void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {QTableWidgetItem *item = m_pTW->item(index.row(), index.column());if (item) {QTextDocument doc;doc.setHtml(item->data(Qt::UserRole).toString());doc.drawContents(painter);}}private:QTableWidget* m_pTW;
};int main(int argc, char *argv[]) {QApplication app(argc, argv);QTableWidget table;table.setColumnCount(1);table.setRowCount(3);table.setItemDelegateForColumn(0, new RichTextDelegate(&table));// 添加富文本數據到表格中QTableWidgetItem *item1 = new QTableWidgetItem;item1->setData(Qt::UserRole, "<h1>標題1</h1><p>段落1</p>");table.setItem(0, 0, item1);QTableWidgetItem *item2 = new QTableWidgetItem;item2->setData(Qt::UserRole, "<h1>標題2</h1><p>段落2</p>");table.setItem(1, 0, item2);table.show();return app.exec();
}
- 創建了一個自定義的
RichTextDelegate
類,繼承自QTableWidgetItemDelegate
。 - 在
paint
方法中,檢查每個表格項的數據,如果存在自定義的富文本數據(存儲在Qt::UserRole
),則使用QTextDocument
來渲染這些數據。 - 將這個自定義委托設置為表格的第一列的代理。
結論
只要未來可期,今天就值得欣喜
。