QPlainTextEdit可以說是一個簡化版的QTextEdit類控件,和QTextEdit的功能差不多,使用了QTextEdit和QTextDocument作為背后實現的技術支撐。
由於QPlainTextEdit在文檔中使用QPlainTextDocumentLayout的簡化布局,它的性能要優於QTextEdit。(同樣反過來可以說效果要略於QTextEdit)我們可以看一個這樣的現象
左邊的是QTextEdit,右邊的是QPlainTextEdit,注意看文本框上沿,QTextEdit的是不是沒有完全顯示出來?對了!這就是由於QPlainTextEdit是用逐行逐段滾動的方法替代了像素精准度高的滾動方法,所以效率要更高一些(每次滾動都需要重新的繪制)在處理大批量的文本內容有比較強大的優勢。
QPlainTextEdit類的父類是QABstractScrollArea類,和QTextEdit不屬於從屬結構的。
一功能作用
QPlainTextEdit的功能作用和QTextEdit基本一致,我們大概過一遍
1.構造函數
qte = QPlainTextEdit(window) qte = QPlainTextEdit('字符',window)
2.提示占位文本
QPlainTextEdit.setPlaceholderText('占位文本') QPlainTextEdit.placeholderText()
3.只讀模式(只對用戶只讀,但可以通過代碼修改)
QPlainTextEdit.setReadOnly()
QPlainTextEdit.isReadOnly()
4.格式
QPlainTextEdit.setCurrentCharFormat(QTextCharFormat) #格式設定 QPlainTextEdit.mergeCurrentCharFormat(QTextCharFormat) #格式合並 QPlainTextEdit.currentCharFormat() #格式獲取——>QTextCharFormat
5.軟換行模式
QPlainTextEdit的軟換行模式比QTextEdit的枚舉值要少得多,只限定了是否限用軟換行(默認情況時啟用軟換行的,即字符超出控件寬度后直接換行)
QPlainTextEdit.setLineWrapMode(QPlainTextEdit.NoWrap) QPlainTextEdit.lineWrapMode() #枚舉值 QPlainTextEdit.NoWrap #不換行——0 QPlainTextEdit.WidgetWidth #按寬度換行——1
6.覆蓋模式
QPlainTextEdit.setOverwriteMode(True)
QPlainTextEdit.overwriteMode()
但這里有個現象不知道是不是源代碼里的bug,可以試一試:
啟用覆蓋模式,在文本框中輸入1234567,把光標移動到3處,可以發現3是被光標覆蓋的,這時候輸入中文,可以發現3並沒有被覆蓋,和插入的效果一樣
並且還可以試一試輸入中文后在用中文覆蓋,也是沒有覆蓋效果的,但是可以用非中文的字符覆蓋中文(中文的標點不可以)。
7.Tab鍵控制
QPlainTextEdit.setTabChangesFocus()
QPlainTextEdit.setTabStopWidth()
QPlainTextEdit.tabChangesFocus()
QPlainTextEdit.tabStopWidth()
可以強制用Tab鍵切換焦點,或者定義Tab鍵的縮進距離。
8.文本操作
a.普通文本的操作
QPlainTextEdit.setPlainText() #設置普通文本 QPlainTextEdit.insertPlainText() #插入普通文本 QPlainTextEdit.appendPlainText() #追加普通文本
插入是在光標位置插入,而追加不考慮光標位置,直接在最后端插入文本(另起一個段落)
b.富文本
QPlainTextEdit.appendHtml() #追加Html標簽
這里添加的Html標簽只能是最簡單的標簽,不支持表格、列表圖片等。
c.文本的獲取
QPlainTextEdit.toPlainText() #獲取文本
這里獲取的文本是從文本框里看到的文本,如果是Html標簽並不會顯示源代碼
pte.appendHtml("<a herf='http://www.cngba.com'>博客園</a>") print(pte.toPlainText())
打印出來的結果就是“博客園”。
9.塊操作
QPlainTextEdit.blockCount() #獲取當前塊的個數 QPlainTextEdit.setMaximumBlockCount() #設置最多的塊個數 QPlainTextEdit.maximumBlockCount() #獲取塊的數量限定值
塊就是在文本框中的段落的個數。默認值為0,即為不做限制。當給出限定值后,超出了限定值會把最上面的段落頂沒了(是真的沒了而不是不顯示)
10.常用操作
QPlainTextEdit.selectAll() QPlainTextEdit.copy() QPlainTextEdit.paste() QPlainTextEdit.cut() QPlainTextEdit.clear() QPlainTextEdit.redo() QPlainTextEdit.undo() QPlainTextEdit.find() #搜索枚舉值 QTextDocument.FindBackward #向前搜索 QTextDocument.FindCaseSensitively #區分大小寫 QTextDocument.FindWholeWords #匹配完整單詞
這些用法按名字就能了解,還有一個縮放的功能要單獨提一下
QPlainTextEdit.zoomIn(int) #縮放
int如果大於0,就是放大,而小於0就是縮小。
11.滾動
在處理比較大的文本的時候,有可能光標離開當前顯示的頁面,我們可以用滾動的方法,讓光標顯示在文本塊的中間(一般都是配合一個按鈕,這里就放出來槽函數就行了)
def fun(): pte.centerCursor() pte.setFocus()
當點擊了按鈕,光標所在的行會盡可能的滾動到頁面中間。這里說盡可能,是因為如果光標原先在第一行貨最后一行,第一行放在中間前面是會留白的,肯定不現實,但是如果加上這句代碼就可以使最后一行顯示在文本框中間
pte = QPlainTextEdit(window)
pte.setCenterOnScroll(True)
注意是在聲明控件的時候就要定義了,而不是在槽函數里(雖然沒什么影響,但一般不這么用,否則需要在每個槽函數里都定義)。加了這句代碼,就可以使文檔后面留白
.
然后就可以把光標所在行(最后一行)滾動到空間中間位置。
還有另外一種方法
def fun(): pte.ensureCursorVisible() pte.setFocus()
這種方式是滾動距離最小的方法保證了光標可見。但是加上
pte.setCenterOnScroll(True)
也可以保證滾動到中間。
12.光標操作
QPlainTextEdit的光標操作和QTextEdit的光標操作差不多,把里面的API列一下就可以了。
QPlainTextEdit.textCursor() #獲取光標對象 QPlainTextEdit.cursorForPosition() #獲取距離指定位置最近的光標對象 QPlainTextEdit.setCursorWidth() #設定光標寬度 QPlainTextEdit.cursorWidth() #獲取光標寬度——>int QPlainTextEdit.cursorRect(QTextCursor) #獲取指定掛光標對象矩形 QTextCursor.moveCursor(QTextCursor.MoveOperation,QTextCursor.MoveMode)

NoMove = ... # type: 'QTextCursor.MoveOperation' Start = ... # type: 'QTextCursor.MoveOperation' Up = ... # type: 'QTextCursor.MoveOperation' StartOfLine = ... # type: 'QTextCursor.MoveOperation' StartOfBlock = ... # type: 'QTextCursor.MoveOperation' StartOfWord = ... # type: 'QTextCursor.MoveOperation' PreviousBlock = ... # type: 'QTextCursor.MoveOperation' PreviousCharacter = ... # type: 'QTextCursor.MoveOperation' PreviousWord = ... # type: 'QTextCursor.MoveOperation' Left = ... # type: 'QTextCursor.MoveOperation' WordLeft = ... # type: 'QTextCursor.MoveOperation' End = ... # type: 'QTextCursor.MoveOperation' Down = ... # type: 'QTextCursor.MoveOperation' EndOfLine = ... # type: 'QTextCursor.MoveOperation' EndOfWord = ... # type: 'QTextCursor.MoveOperation' EndOfBlock = ... # type: 'QTextCursor.MoveOperation' NextBlock = ... # type: 'QTextCursor.MoveOperation' NextCharacter = ... # type: 'QTextCursor.MoveOperation' NextWord = ... # type: 'QTextCursor.MoveOperation' Right = ... # type: 'QTextCursor.MoveOperation' WordRight = ... # type: 'QTextCursor.MoveOperation' NextCell = ... # type: 'QTextCursor.MoveOperation' PreviousCell = ... # type: 'QTextCursor.MoveOperation' NextRow = ... # type: 'QTextCursor.MoveOperation' PreviousRow = ... # type: 'QTextCursor.MoveOperation'

MoveAnchor = ... # type: 'QTextCursor.MoveMode' KeepAnchor = ... # type: 'QTextCursor.MoveMode'
二.信號
1.文本改變
QPlainTextEdit.textChanged()
2.選中文本改變
QPlainTextEdit.selectionChanged()
在這個函數中並沒有參數傳遞,如果想獲取選中的文本就需要結合文本光標來實現
def fun(): print('選中文本發生改變:',pte.textCursor().selectedText())
3.光標位置發生改變
QPlainTextEdit.cursorPositionChanged()
4.塊的個數變化
QPlainTextEdit.blockCountChanged(int)
隨函數傳遞塊的個數(int)。
5.內容更新請求
QPlainTextEdit.updateRequest(QRect.rect,int dy)
只要內容發生變化就調用(包括光標的閃爍)。這個主要是用在類似於文本框被滾動時,由於每次滾動導致的界面上內容發生變化都相當於重繪一遍,而dy就是滾動的步長。具體的用法在下一節結合案例來說明
6.編輯狀態發生改變時
QPlainTextEdit.modificationChanged()
這個主要是用在例如對文檔進行編輯時,函數傳遞參數(bool)為True,這個時候是可以有撤銷動作的,當文件被保存后,把這個狀態重置一下,就不能有撤回了(就和word一樣)
doc = pte.document() doc.setModified(False) #重置被編輯狀態
6.復制、撤銷、重做可用時
QPlainTextEdit.copyAvailable(bool)
QPlainTextEdit.undoAvailable(bool)
QPlainTextEdit.redoAvailable(bool)
復制可用——有選中的情況下;撤銷可用——被編輯狀態為True;重做——有撤銷作業
三.內容更新請求
QPlainTextEdit里有個信號是updateRequest(),我們結合一個案例來使用一下
好多文本編輯器都有個行號,Pycharm就有,我們在上下滾動屏幕顯示的時候行號是跟着切換的。
思路就是用一個label里放置所有的行號(紅色的label),父級控件是和文本框高度一致的label(限制label),限制label和文本框同屬window控件。由於限制label的尺寸固定,就限制了行號label顯示出的內容,當文本框發生滾動時,由於事件函數傳遞有滾動的y的像素值,把行號的label在y軸上移動相應的像素值就可以了。

from PyQt5.Qt import * import sys app=QApplication(sys.argv) window = QWidget() window.resize(800,500) pte = QPlainTextEdit(window) pte.resize(300,300) pte.move(300,100) num_cut = QLabel(window) #限制標簽的大小 num_cut.resize(30,300) num_cut.move(270,100) num_cut.setStyleSheet('background-color:green') num = QLabel(num_cut) num.move(0,7) #偏移一點保證label里的行號和文本框里的段落能對齊 line_nums = '\n'.join([str(i) for i in range(1,101)]) #生成行號 num.setText(line_nums) num.adjustSize() def fun(rec,dy): num.move(num.x(),num.y()+dy) #信號內傳遞有滾動的y像素值 pte.updateRequest.connect(fun) window.show() sys.exit(app.exec_())