GUI學習之十三——QPlainTextEdit學習總結


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'
MoveOperation枚舉值
MoveAnchor = ...  # type: 'QTextCursor.MoveMode'
KeepAnchor = ...  # type: 'QTextCursor.MoveMode'
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_())
行號滾動案例

 

         


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM