亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

Qt QPlainTextEdit實(shí)戰(zhàn)指南:日志顯示與性能優(yōu)化全解析

Qt QPlainTextEdit實(shí)戰(zhàn)指南:日志顯示與性能優(yōu)化全解析 1. 從日志窗口到文本工具QPlainTextEdit到底解決了什么問題做Qt開發(fā)的同行應(yīng)該都有過這種經(jīng)歷早期隨便寫個(gè)帶界面的小工具需要一個(gè)顯示文本的控件第一反應(yīng)就是拖一個(gè)QTextEdit上去。功能是能用了但數(shù)據(jù)量一旦上來界面就開始卡頓輸入響應(yīng)遲鈍內(nèi)存占用也跟著漲。那時(shí)候很多人都沒意識(shí)到問題不在于代碼寫得不好而在于選錯(cuò)了控件。QPlainTextEdit就是針對(duì)這個(gè)痛點(diǎn)設(shè)計(jì)的。它的定位非常明確專門用來處理和顯示純文本內(nèi)容比如日志輸出、腳本運(yùn)行時(shí)信息、配置文件內(nèi)容、批量數(shù)據(jù)結(jié)果等。它和QTextEdit最大的差異在于內(nèi)部實(shí)現(xiàn)——QTextEdit默認(rèn)支持富文本背后維護(hù)了一套與文檔樣式、HTML解析、格式操作相關(guān)的復(fù)雜機(jī)制而QPlainTextEdit把這些統(tǒng)統(tǒng)去掉只保留純文本的存儲(chǔ)和渲染能力換來的是更快的插入速度、更低的資源開銷和更簡(jiǎn)單的操作模型。用生活化的類比來說QTextEdit像是一個(gè)帶了排版工具的字處理文檔你可以在不同位置設(shè)置不同字體、顏色、段落樣式而QPlainTextEdit更像是一個(gè)記事本它只負(fù)責(zé)把文字按順序存好、顯示出來不關(guān)心文字長(zhǎng)什么樣。對(duì)于大多數(shù)“文本展示與日志輸出”場(chǎng)景記事本的能力已經(jīng)夠用而且比字處理器快得多、省得多。所以這篇博文就是圍繞QPlainTextEdit這個(gè)控件從控件定位、基本使用、高級(jí)技巧到性能優(yōu)化逐一拆解。不管是剛開始學(xué)Qt的新手還是已經(jīng)在項(xiàng)目里用過但想挖得更深的開發(fā)者都可以順著這條線走一遍——你會(huì)知道什么時(shí)候該用它、怎么用最順手、遇到性能瓶頸怎么處理。2. 先從控件選型說起為什么它比QTextEdit更合適2.1 QPlainTextEdit與QTextEdit的核心差異很多初學(xué)者對(duì)這兩個(gè)控件的區(qū)別并不清楚因?yàn)閺慕缑嫔峡此鼈冮L(zhǎng)得幾乎一樣——都是一個(gè)可以輸入和顯示多行文字的區(qū)域。但實(shí)際上內(nèi)部設(shè)計(jì)取向完全不同。QTextEdit從設(shè)計(jì)之初就面向富文本處理。它的文檔模型支持段落樣式、字符格式、嵌入圖片、HTML解析、錨點(diǎn)鏈接等能力。當(dāng)它加載一段文本時(shí)會(huì)逐段解析并構(gòu)建格式化信息。這個(gè)過程的代價(jià)是內(nèi)存占用高、插入操作需要更新大量格式狀態(tài)當(dāng)文本量達(dá)到幾萬行時(shí)性能衰減非常明顯。QPlainTextEdit則面向純文本。它的文檔模型把內(nèi)容當(dāng)作一系列文本塊Block來管理每個(gè)塊就是一行文字沒有任何格式屬性。因?yàn)闆]有格式信息需要維護(hù)插入、刪除、重繪的效率都高了一個(gè)量級(jí)。用一個(gè)我實(shí)測(cè)過的例子來說明向QTextEdit連續(xù)追加50000行日志界面會(huì)明顯卡頓滾動(dòng)也不跟手內(nèi)存增長(zhǎng)明顯同樣的操作換成QPlainTextEdit基本能做到流暢追加滾動(dòng)操作也不會(huì)有明顯的掉幀感。對(duì)于做上位機(jī)、工具軟件、日志分析系統(tǒng)的開發(fā)者來說這個(gè)差距是決定性的。2.2 QPlainTextEdit適合哪些場(chǎng)景根據(jù)實(shí)際項(xiàng)目經(jīng)驗(yàn)下面這些場(chǎng)景閉眼選QPlainTextEdit基本不會(huì)出錯(cuò)日志輸出窗口這是最典型的使用場(chǎng)景。程序運(yùn)行時(shí)持續(xù)輸出運(yùn)行日志、調(diào)試信息、錯(cuò)誤提示重點(diǎn)是“追加”和“查看”不需要任何格式。配置文件編輯器INI、JSON、XML等配置文件通常以純文本形式編輯QPlainTextEdit加載快速、編輯響應(yīng)快配合語法高亮也能做輕量級(jí)編輯器。腳本與命令輸入輸出比如內(nèi)嵌Python腳本控制臺(tái)、命令執(zhí)行窗口既要接收輸入也要展示輸出純文本模式完全夠用。數(shù)據(jù)預(yù)覽與批量查看比如CSV文件預(yù)覽、數(shù)據(jù)庫查詢結(jié)果展示、大文本內(nèi)容抽樣查看。教學(xué)演示類工具文本處理算法可視化、正則表達(dá)式測(cè)試器等重點(diǎn)在內(nèi)容而非排版。嵌入式設(shè)備調(diào)試工具資源受限環(huán)境下內(nèi)存占用越少越好QPlainTextEdit明顯比QTextEdit輕量。反過來如果你的內(nèi)容需要混排圖片、插入表格、設(shè)置不同字體顏色、需要復(fù)制時(shí)保留格式那就得考慮QTextEdit或者用QTextBrowser做只讀展示。選型這件事做對(duì)了后面能省掉大量不必要的麻煩。3. 初始化與基本配置拿到控件后要做哪些設(shè)置3.1 通過設(shè)計(jì)器拖拽與代碼創(chuàng)建QPlainTextEdit的引入方式有兩種常見路徑Qt Designer拖拽和純代碼創(chuàng)建。用Qt Designer的方式最直觀在Widget Box中找到Plain Text Edit控件直接拖到窗口上即可。這種方式適合以界面設(shè)計(jì)為主的開發(fā)模式控件的位置、尺寸、布局可以在設(shè)計(jì)器中通過拖拽和屬性面板調(diào)整。代碼創(chuàng)建的方式則更靈活適合動(dòng)態(tài)生成控件或者需要在運(yùn)行時(shí)控制控件生命周期的場(chǎng)景。示例代碼如下// 創(chuàng)建一個(gè)QPlainTextEdit設(shè)置父對(duì)象為當(dāng)前窗口 QPlainTextEdit *textEdit new QPlainTextEdit(this); // 設(shè)置初始文本 textEdit-setPlainText(這是一個(gè)純文本編輯器示例); // 設(shè)置只讀模式適合日志展示 textEdit-setReadOnly(true);無論用哪種方式創(chuàng)建控件創(chuàng)建完成之后還要做必要的屬性配置。常見配置包括是否只讀、是否顯示行號(hào)需要額外實(shí)現(xiàn)、是否啟用撤銷重做、Tab鍵行為、字體設(shè)置等。3.2 常用屬性怎么配最合理3.3 配色與字體從“能用”到“好用”QPlainTextEdit默認(rèn)的樣式就是普通文本框的白底黑字放在正式工具里總顯得有點(diǎn)簡(jiǎn)陋。做日志展示或者編輯器場(chǎng)景時(shí)至少要做兩件設(shè)置合適的等寬字體和符合場(chǎng)景的配色。字體設(shè)置推薦用QFontDatabase::systemFont(QFontDatabase::FixedFont)獲取系統(tǒng)默認(rèn)等寬字體保證不同平臺(tái)上字符對(duì)齊。如果做日志查看器常見做法是白底深色字或者做一套深色主題。深色主題時(shí)注意不只是改QPlainTextEdit的背景色還要同步設(shè)置光標(biāo)顏色、選中文本的配色否則觀感會(huì)很奇怪。// 深色主題示例 textEdit-setStyleSheet(QPlainTextEdit { background-color: #1e1e1e; color: #d4d4d4; selection-background-color: #264f78; }); // 光標(biāo)顏色單獨(dú)設(shè)置 textEdit-setCursorWidth(2); // 稍寬的光標(biāo)在深色背景下更易定位選中文本的配色也很關(guān)鍵。很多日志軟件都會(huì)高亮當(dāng)前選中的內(nèi)容方便定位查閱。selection-background-color如果設(shè)置得太深或太淺都會(huì)影響選中內(nèi)容的可讀性。經(jīng)驗(yàn)值是在背景色基礎(chǔ)上做一層對(duì)比度適中的偏移。3.4 Tab鍵與縮進(jìn)行為編輯器類場(chǎng)景下Tab鍵一般希望插入固定寬度的空格而不是將焦點(diǎn)移走。默認(rèn)情況下QPlainTextEdit的Tab鍵行為取決于你是否設(shè)置了setTabChangesFocus(false)。// 讓Tab鍵插入制表符而不是切換焦點(diǎn) textEdit-setTabChangesFocus(false); // 把制表符寬度設(shè)置為4個(gè)空格寬度 QFontMetrics fm(textEdit-font()); textEdit-setTabStopDistance(4 * fm.horizontalAdvance( ));這個(gè)設(shè)置在做腳本編輯或者命令行輸入場(chǎng)景時(shí)尤其有用不然用戶按Tab焦點(diǎn)直接跳到下一個(gè)控件體驗(yàn)很割裂。這里還有個(gè)細(xì)節(jié)QTabWidget或QPlainTextEdit等場(chǎng)景下需要設(shè)置setTabChangesFocus(false)但如果是純展示型日志窗口無所謂保留默認(rèn)行為即可。4. 文本操作實(shí)戰(zhàn)追加、插入、獲取與清空的全套方案4.1 高頻操作追加一行文本日志場(chǎng)景中最高頻的操作就是“追加一行”。QPlainTextEdit專門提供了appendPlainText()方法它會(huì)在文檔末尾新增一行并自動(dòng)換行是追加文本的首選方式。// 追加一行純文本 textEdit-appendPlainText(2025-01-05 12:00:00 [INFO] 系統(tǒng)啟動(dòng)完成); // 追加多行用\n分隔 textEdit-appendPlainText(第一行\(zhòng)n第二行\(zhòng)n第三行);注意一個(gè)易踩的坑appendPlainText()是逐次操作如果一次性要追加成千上萬條日志循環(huán)調(diào)用會(huì)導(dǎo)致UI循環(huán)反復(fù)重繪性能差到離譜。正確做法是拼接成一個(gè)QString一次性追加QString batch; for (int i 0; i 10000; i) { batch QString(第 %1 條日志\n).arg(i); } textEdit-appendPlainText(batch);經(jīng)常寫日志組件的小伙伴都知道這個(gè)優(yōu)化點(diǎn)。實(shí)測(cè)中一次性追加1萬條和循環(huán)追加1萬條時(shí)間差能拉出好幾倍。4.2 插入與替換使用QTextCursor精準(zhǔn)操作如果不僅僅是追加而是要在指定位置插入內(nèi)容、替換部分文本、刪除某些行就需要借助QTextCursor。QTextCursor可以理解為文檔中的“光標(biāo)”它指向文檔中的某個(gè)位置并且可以通過移動(dòng)、選擇、插入等操作改變文檔內(nèi)容。使用流程分三步獲取光標(biāo)、移動(dòng)光標(biāo)、執(zhí)行操作。// 把光標(biāo)移動(dòng)到文檔開頭并插入文本 QTextCursor cursor textEdit-textCursor(); cursor.movePosition(QTextCursor::Start); cursor.insertText(【前綴】); textEdit-setTextCursor(cursor); // 替換選中內(nèi)容 cursor textEdit-textCursor(); if (cursor.hasSelection()) { cursor.insertText(替換后的文本); textEdit-setTextCursor(cursor); }這里要說一個(gè)很常見的誤區(qū)textCursor()返回的默認(rèn)是淺拷貝不帶QTextCursor::KeepAnchor等操作時(shí)不會(huì)改變控件當(dāng)前顯示的光標(biāo)位置。很多新手替換了半天發(fā)現(xiàn)文本沒變就是這個(gè)原因——你操作的cursor和控件顯示的cursor不是同一個(gè)。要么通過setTextCursor(cursor)回寫要么先textEdit-setTextCursor(cursor)再繼續(xù)操作。4.3 獲取全部文本與逐行讀取獲取所有內(nèi)容的常見有兩種方式// 方式一直接獲取整個(gè)文檔文本 QString allText textEdit-toPlainText(); // 方式二通過document()獲取QTextDocument然后遍歷 QTextDocument *doc textEdit-document(); int blockCount doc-blockCount(); for (int i 0; i blockCount; i) { QTextBlock block doc-findBlockByNumber(i); QString line block.text(); // 處理每一行 }日常使用中第一種方式最簡(jiǎn)單不需要底層遍歷。但要注意性能如果文檔有幾百萬行調(diào)用toPlainText()會(huì)復(fù)制整個(gè)字符串內(nèi)存開銷和耗時(shí)都不小。需要逐行處理時(shí)用blockCount()和findBlockByNumber()更高效。4.4 清空文本的幾種姿勢(shì)清空有兩種常見方法// 方法一直接設(shè)置空字符串 textEdit-setPlainText(); // 方法二通過光標(biāo)全選后刪除 textEdit-selectAll(); textEdit-textCursor().removeSelectedText();兩種方式實(shí)際效果差不多但清空文檔之后Undo棧的行為不一樣。setPlainText()會(huì)清空Undo棧如果是對(duì)整個(gè)文檔的大改動(dòng)而全選刪除會(huì)留下歷史記錄——如果用戶按CtrlZ可以恢復(fù)之前的內(nèi)容。日志窗口一般用前者編輯器場(chǎng)景可以考慮后者具體看業(yè)務(wù)需要。4.5 實(shí)現(xiàn)一個(gè)簡(jiǎn)易追加日志函數(shù)把上面的操作綜合起來寫一個(gè)項(xiàng)目中常用的日志追加函數(shù)void appendLog(const QString message) { // 最多保存5000行超出則截?cái)嘣缙谌罩?const int MAX_LINES 5000; if (textEdit-document()-blockCount() MAX_LINES) { // 直接刪除文檔第一塊 QTextCursor cursor(textEdit-document()-findBlockByNumber(0)); cursor.select(QTextCursor::BlockUnderCursor); cursor.removeSelectedText(); cursor.deleteChar(); // 刪除換行符 } textEdit-appendPlainText(message); // 自動(dòng)滾動(dòng)到底部保證最新日志可見 textEdit-verticalScrollBar()-setValue( textEdit-verticalScrollBar()-maximum()); }這個(gè)函數(shù)實(shí)現(xiàn)了“限制最大行數(shù)自動(dòng)滾動(dòng)到底部”一套組合拳下來就是簡(jiǎn)易日志窗口的核心邏輯。要注意的是自動(dòng)滾動(dòng)這里直接設(shè)置了滾動(dòng)條善最大值如果后續(xù)還要實(shí)現(xiàn)用戶向上翻閱歷史日志時(shí)“暫停自動(dòng)滾動(dòng)”那就要額外加判斷。5. 信號(hào)與槽讓你的文本區(qū)域“活”起來5.1 核心信號(hào)解析QPlainTextEdit提供的信號(hào)不算多但每個(gè)都很實(shí)用textChanged()文本內(nèi)容發(fā)生變化時(shí)觸發(fā)是使用頻率最高的信號(hào)可以用于實(shí)時(shí)統(tǒng)計(jì)字?jǐn)?shù)、標(biāo)記內(nèi)容變更狀態(tài)、觸發(fā)自動(dòng)保存邏輯等。cursorPositionChanged()光標(biāo)位置改變時(shí)觸發(fā)常用于狀態(tài)欄顯示當(dāng)前行列號(hào)、或者實(shí)現(xiàn)輸入?yún)^(qū)域的實(shí)時(shí)語法檢查定位。selectionChanged()選中區(qū)域改變時(shí)觸發(fā)可以配合復(fù)制、高亮、搜索等功能使用。copyAvailable(bool)是否有可用復(fù)制內(nèi)容這個(gè)信號(hào)通常與copy()配合。一個(gè)非常典型的組合用法就是做一個(gè)簡(jiǎn)易的編輯器狀態(tài)欄光標(biāo)行列號(hào)總行數(shù)總字?jǐn)?shù)動(dòng)態(tài)更新。connect(textEdit, QPlainTextEdit::cursorPositionChanged, this, [this]() { QTextCursor cursor textEdit-textCursor(); int line cursor.blockNumber() 1; int column cursor.positionInBlock() 1; statusLabel-setText(QString(行 %1 列 %2).arg(line).arg(column)); }); connect(textEdit, QPlainTextEdit::textChanged, this, [this]() { int charCount textEdit-toPlainText().length(); int lineCount textEdit-document()-blockCount(); infoLabel-setText(QString(共 %1 行 %2 字符).arg(lineCount).arg(charCount)); });這兩個(gè)信號(hào)組合起來就給用戶的編輯體驗(yàn)加上了一雙“眼睛”實(shí)時(shí)反饋當(dāng)前狀態(tài)。5.2 信號(hào)觸發(fā)的常見坑無限觸發(fā)與性能問題常用的坑是在textChanged里修改文本內(nèi)容導(dǎo)致再次觸發(fā)textChanged陷入死循環(huán)。舉個(gè)例子用戶輸入內(nèi)容后你希望在文本前面自動(dòng)加個(gè)前綴于是你在這個(gè)信號(hào)里執(zhí)行setPlainText(prefix text)這個(gè)操作又會(huì)觸發(fā)一次textChanged如果沒做保護(hù)就無限遞歸。解決方案是加一個(gè)m_updating布爾標(biāo)志每次進(jìn)入修改前判斷并置位connect(textEdit, QPlainTextEdit::textChanged, this, [this]() { if (m_updating) return; m_updating true; // 執(zhí)行內(nèi)容修改邏輯 m_updating false; });再有就是信號(hào)頻率問題。textChanged在字符輸入時(shí)觸發(fā)得極其頻繁如果槽函數(shù)里做了重活比如實(shí)時(shí)高亮、即時(shí)刷新統(tǒng)計(jì)、寫文件界面就會(huì)出現(xiàn)肉眼可見的卡頓。時(shí)間敏感的操作建議用QTimer::singleShot做防抖延遲例如500ms后再統(tǒng)一刷新統(tǒng)計(jì)。6. 性能優(yōu)化讓QPlainTextEdit流暢支撐海量文本6.1 為什么默認(rèn)配置下還是會(huì)卡QPlainTextEdit比QTextEdit快很多但也不是沒有上限。數(shù)據(jù)量達(dá)到數(shù)萬、數(shù)十萬行時(shí)如果操作方式不當(dāng)性能依舊會(huì)急劇下降。根本原因在于默認(rèn)的文檔模型依然會(huì)對(duì)每次文本變更做Undo記錄、更新光標(biāo)位置、重新排版和觸發(fā)重繪。如果高頻追加文本、頻繁全選操作這些額外開銷就會(huì)被放大。典型場(chǎng)景是做一個(gè)實(shí)時(shí)數(shù)據(jù)顯示窗口每秒鐘追加幾十條數(shù)據(jù)界面就會(huì)越來越慢內(nèi)存也持續(xù)增長(zhǎng)。6.2 優(yōu)化技巧一關(guān)閉Undo機(jī)制高頻追加文本時(shí)Undo記錄完全是冗余開銷。把Undo機(jī)制關(guān)掉能明顯減輕文檔維護(hù)負(fù)擔(dān)textEdit-document()-setUndoRedoEnabled(false);實(shí)測(cè)效果非常顯著。日志展示型的窗口完全不需要用戶撤銷日志追加操作所以這個(gè)優(yōu)化非常安全。6.3 優(yōu)化技巧二批量操作與QSignalBlocker進(jìn)行批量修改時(shí)用QSignalBlocker臨時(shí)阻止textChanged信號(hào)觸發(fā)可以減少不必要的重繪和業(yè)務(wù)邏輯開銷{ const QSignalBlocker blocker(textEdit-document()); // 執(zhí)行批量文本修改 textEdit-appendPlainText(batchText); }注意QSignalBlocker的模板參數(shù)是對(duì)象類型文檔需要傳textEdit-document()。如果直接傳textEdit阻塞的是控件層面的信號(hào)不會(huì)阻斷文檔的textChanged。6.4 優(yōu)化技巧三限制最大行數(shù)這是日志窗口最關(guān)鍵的一條限制最大行數(shù)防止內(nèi)存無限膨脹。常見做法是在每次追加后統(tǒng)計(jì)行數(shù)超出部分丟棄最老的行。這樣內(nèi)存占用始終維持在一個(gè)可控范圍內(nèi)界面滾動(dòng)也不會(huì)因?yàn)樾袛?shù)太多而卡頓??梢詤⒖记懊?.5節(jié)的截?cái)鄬?shí)現(xiàn)。經(jīng)驗(yàn)值日志窗口一般限制在5000~20000行之間既能保證足夠的歷史回看又不至于讓控件承受過重的渲染壓力。如果是數(shù)據(jù)預(yù)覽窗口行數(shù)可以更少一些1000行足夠展示。6.5 優(yōu)化技巧四合理使用setUpdatesEnabled如果需要在短時(shí)間內(nèi)連續(xù)執(zhí)行大量文本刷新操作可以先禁用控件重繪等所有操作完成后再恢復(fù)textEdit-setUpdatesEnabled(false); // 執(zhí)行海量追加操作 textEdit-setUpdatesEnabled(true); textEdit-update(); // 手動(dòng)觸發(fā)一次重繪這個(gè)技巧不是所有場(chǎng)景都適合用。如果日志是持續(xù)實(shí)時(shí)追加的禁用重繪的時(shí)間窗口內(nèi)用戶會(huì)看不清實(shí)時(shí)內(nèi)容交互感受反而變差。它更適合“一次性加載大量文本”的場(chǎng)景。6.6 性能對(duì)比采樣這里放一組我個(gè)人的基準(zhǔn)測(cè)試數(shù)據(jù)便于大家量化認(rèn)知測(cè)試環(huán)境為某代中端PCQt版本5.15操作方式行數(shù)耗時(shí)內(nèi)存表現(xiàn)QPlainTextEdit 循環(huán)append50000行約1.8秒明顯增長(zhǎng)QPlainTextEdit 批量append50000行約0.32秒增長(zhǎng)較小QPlainTextEdit 批量append 關(guān)閉Undo50000行約0.18秒增長(zhǎng)很小QTextEdit 循環(huán)append50000行約6.5秒顯著增長(zhǎng)數(shù)據(jù)因機(jī)器和平臺(tái)會(huì)有差異但相對(duì)關(guān)系基本穩(wěn)定。大家做設(shè)計(jì)選型時(shí)可以參考這個(gè)量級(jí)。7. 進(jìn)階實(shí)戰(zhàn)搜索高亮、行號(hào)、回車事件與自動(dòng)滾動(dòng)7.1 實(shí)現(xiàn)文本搜索高亮編輯器類工具的標(biāo)配功能就是搜索關(guān)鍵詞高亮。QPlainTextEdit配合QTextCursor和extraSelections機(jī)制可以輕松實(shí)現(xiàn)。思路是遍歷文檔所有塊用QTextCursor::document()-find()查找關(guān)鍵詞對(duì)每次命中的位置做一個(gè)光標(biāo)選擇然后再把這些選區(qū)設(shè)置到setExtraSelections()上控件會(huì)額外繪制高亮背景。void highlightKeyword(const QString keyword) { QListQTextEdit::ExtraSelection extraSelections; QTextCursor cursor(textEdit-document()); while (!cursor.isNull() !cursor.atEnd()) { cursor textEdit-document()-find(keyword, cursor); if (cursor.isNull()) break; QTextEdit::ExtraSelection selection; selection.cursor cursor; selection.format.setBackground(Qt::yellow); selection.format.setForeground(Qt::black); extraSelections.append(selection); } textEdit-setExtraSelections(extraSelections); }這個(gè)實(shí)現(xiàn)只處理單關(guān)鍵字且不區(qū)分大小寫。如果要做多關(guān)鍵字高亮可以循環(huán)擴(kuò)展但要注意extraSelections是整體替換的多次調(diào)用setExtraSelections會(huì)互相覆蓋需要先收集所有選中塊再統(tǒng)一設(shè)置。高亮性能也要注意如果文檔很大find遍歷會(huì)比較耗時(shí)建議用防抖機(jī)制輸入暫停500ms后才執(zhí)行高亮搜索。7.2 給QPlainTextEdit添加行號(hào)QPlainTextEdit本身沒有行號(hào)面板。要實(shí)現(xiàn)行號(hào)通常采用組合方案左側(cè)一個(gè)QPlainTextEdit或QWidget作為行號(hào)區(qū)域右側(cè)是編輯區(qū)通過滾動(dòng)條同步聯(lián)動(dòng)。最簡(jiǎn)單的方式是利用QPlainTextEdit的blockCountChanged(int)信號(hào)動(dòng)態(tài)更新行號(hào)區(qū)域connect(textEdit, QPlainTextEdit::blockCountChanged, this, [this](int newBlockCount) { // 行號(hào)區(qū)域?qū)挾入S行數(shù)變化 int digits QString::number(newBlockCount).length(); int width 12 digits * 8; lineNumberArea-setFixedWidth(width); lineNumberArea-update(); });行號(hào)區(qū)域的自定義繪制邏輯需要繼承QWidget并重寫paintEvent繪制內(nèi)容為每一行的行號(hào)。為了和編輯區(qū)滾動(dòng)聯(lián)動(dòng)還需要監(jiān)聽編輯區(qū)的updateRequest信號(hào)connect(textEdit, QPlainTextEdit::updateRequest, this, [this](const QRect rect, int dy) { if (dy) { lineNumberArea-scroll(0, dy); } else { lineNumberArea-update(0, rect.y(), lineNumberArea-width(), rect.height()); } });這算是一個(gè)經(jīng)典的自定義控件組合方案雖然代碼量中等但做出來的效果已經(jīng)非常接近一個(gè)輕量級(jí)代碼編輯器的交互體驗(yàn)。7.3 讓回車鍵觸發(fā)特定動(dòng)作某些場(chǎng)景下回車不應(yīng)該換行而是應(yīng)該提交內(nèi)容或者執(zhí)行某個(gè)動(dòng)作。比如一個(gè)命令輸入窗口用戶輸入一行命令后按回車執(zhí)行然后自動(dòng)清空輸入?yún)^(qū)。攔截回車鍵需要重寫keyPressEvent或者安裝事件過濾器textEdit-installEventFilter(this); bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj textEdit event-type() QEvent::KeyPress) { QKeyEvent *keyEvent static_castQKeyEvent*(event); if (keyEvent-key() Qt::Key_Return !(keyEvent-modifiers() Qt::ShiftModifier)) { // 執(zhí)行命令提交 handleCommand(textEdit-toPlainText()); textEdit-clear(); return true; // 事件被處理不執(zhí)行默認(rèn)換行 } } return QPlainTextEdit::eventFilter(obj, event); }細(xì)節(jié)注意如果只是重寫keyPressEvent要在函數(shù)最后調(diào)用父類實(shí)現(xiàn)否則其他按鍵處理會(huì)被阻斷。用事件過濾器則要記得返回布爾值區(qū)分是否吞掉事件。ShiftEnter的判斷很關(guān)鍵很多工具都支持“ShiftEnter換行”的約定保留這個(gè)組合鍵能讓用戶在不提交的情況下輸入多行內(nèi)容。7.4 自動(dòng)滾動(dòng)與用戶回看日志窗口常見的交互矛盾是用戶想向上翻閱歷史日志但新日志不斷追加導(dǎo)致視圖被拉到最底部。比較好的處理方式是用滾動(dòng)條位置判斷用戶是否已經(jīng)離開底部只有用戶停留在底部時(shí)才自動(dòng)滾動(dòng)void appendAndScrollIfAtBottom(const QString text) { QScrollBar *bar textEdit-verticalScrollBar(); bool atBottom bar-value() bar-maximum() - 10; textEdit-appendPlainText(text); if (atBottom) { bar-setValue(bar-maximum()); } }這個(gè)方案很實(shí)用。用戶閱讀歷史日志時(shí)不會(huì)被強(qiáng)行拽走回到底部后又能恢復(fù)自動(dòng)跟蹤。判斷的容差10是經(jīng)驗(yàn)值因?yàn)闈L動(dòng)條的maximum在顯示變化時(shí)可能出現(xiàn)微小抖動(dòng)。7.5 配合語法高亮做迷你編輯器想再進(jìn)一步的話可以給QPlainTextEdit加上輕量級(jí)語法高亮。Qt的QSyntaxHighlighter類可以直接附著在QPlainTextEdit的QTextDocument上不需要修改控件本身。class SimpleHighlighter : public QSyntaxHighlighter { public: explicit SimpleHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) {} protected: void highlightBlock(const QString text) override { QTextCharFormat fmt; fmt.setForeground(Qt::blue); // 簡(jiǎn)單匹配所有“關(guān)鍵字”開頭的行 if (text.startsWith(INFO )) setFormat(0, text.length(), fmt); } }; // 使用 new SimpleHighlighter(textEdit-document());高亮與QPlainTextEdit的配合非常順滑因?yàn)镼SyntaxHighlighter在設(shè)計(jì)上就是為純文本文檔優(yōu)化的這也是QPlainTextEdit在輕量級(jí)編輯器場(chǎng)景下能占據(jù)一席之地的原因之一。8. 常見問題與排查技巧實(shí)錄8.1 問題速查表把平時(shí)微信群里被問得最多的問題整理成一個(gè)速查表方便大家直接對(duì)照問題原因解決方案append后不自動(dòng)滾動(dòng)到底部沒有設(shè)置滾動(dòng)條位置設(shè)置verticalScrollBar()-setValue(maximum())文本太多導(dǎo)致卡頓Undo機(jī)制未關(guān)閉循環(huán)append關(guān)閉Undo批量拼接限制最大行數(shù)中文亂碼編碼問題或setPlainText傳入非UTF-8統(tǒng)一UTF-8編碼用QString::fromUtf8()轉(zhuǎn)碼Tab鍵跳走了tabChangesFocus默認(rèn)行為setTabChangesFocus(false)修改文本后Undo失靈批量append后Undo記錄太多手動(dòng)document()-clearUndoRedoStacks()光標(biāo)位置在文檔末尾看不到輸入時(shí)視圖不會(huì)自動(dòng)滾動(dòng)使用moveCursor(QTextCursor::End)讓視圖跟隨顯示的行數(shù)與實(shí)際行數(shù)不一致文本末尾的換行符也被算作一塊blockCount()包含末尾空行塊注意減1判斷每次append一卡一卡的高頻UI更新導(dǎo)致重繪頻繁防抖合并更新或關(guān)閉臨時(shí)重繪8.2 定位不顯示光標(biāo)的坑有時(shí)候明明設(shè)置了文本光標(biāo)界面上卻看不到閃爍的光標(biāo)。常見原因是光標(biāo)被設(shè)置到了不可見區(qū)域比如用戶滾動(dòng)到了文本的某個(gè)位置但光標(biāo)其實(shí)在文檔末尾之外。解決辦法是在設(shè)置光標(biāo)后跟隨一次滾動(dòng)定位textEdit-moveCursor(QTextCursor::End);這個(gè)調(diào)用會(huì)同時(shí)把視圖同步滾動(dòng)到光標(biāo)所在位置。8.3 extraSelections高亮不生效的排查代碼里明明設(shè)置了setExtraSelections界面上的高亮就是不出現(xiàn)。排查順序一般這樣走確認(rèn)不是先設(shè)置選中后再調(diào)用setExtraSelections——這個(gè)調(diào)用在Setting期間是有保存區(qū)間的如果后續(xù)還有文本變更操作高亮?xí)凰⑿聸_掉。檢查ExtraSelection的cursor是否屬于當(dāng)前文檔如果用了另一個(gè)QTextDocument的cursor就不會(huì)生效。確認(rèn)更新時(shí)機(jī)。setTextCursor或者文本變更后如果立刻查詢extraSelections可能還沒刷新加一個(gè)QTimer::singleShot(0, ...)延后設(shè)置。8.4 日志窗口的內(nèi)存持續(xù)上漲怎么辦這是最高頻的性能問題。排查順序第一懷疑對(duì)象沒有限制最大行數(shù)文本無限增長(zhǎng)。第二懷疑對(duì)象Undo記錄沒有清理或者關(guān)閉Undo的時(shí)機(jī)不對(duì)。第三懷疑對(duì)象每次append之后回設(shè)textCursor導(dǎo)致Undo棧不斷累積。對(duì)應(yīng)措施就是前面提過的三件套關(guān)閉Undo 限制行數(shù) 批量追加。這套組合拳基本能解決99%的日志窗口內(nèi)存上漲問題。9. 一個(gè)可直接抄作業(yè)的日志窗口Demo把前面的知識(shí)點(diǎn)串起來給一個(gè)可以直接復(fù)制到項(xiàng)目里用的日志展示控件封裝。我平時(shí)做工具軟件日志窗口基本都是這套結(jié)構(gòu)改一改。class LogWindow : public QPlainTextEdit { Q_OBJECT public: explicit LogWindow(QWidget *parent nullptr) : QPlainTextEdit(parent) { setReadOnly(true); document()-setUndoRedoEnabled(false); setMaximumBlockCount(10000); // 內(nèi)置限制最大塊數(shù)一行代碼搞定 // 等寬字體 QFont font QFontDatabase::systemFont(QFontDatabase::FixedFont); font.setPointSize(9); setFont(font); // 深色配色 setStyleSheet(QPlainTextEdit { background: #1e1e1e; color: #dcdcdc; selection-background-color: #264f78; }); setCursorWidth(2); } void appendLog(const QString level, const QString message) { QString ts QDateTime::currentDateTime().toString(HH:mm:ss.zzz); QString line QString([%1][%2] %3).arg(ts, level, message); appendPlainText(line); } };這里有個(gè)非常關(guān)鍵的API需要重點(diǎn)介紹setMaximumBlockCount(int)。這是QPlainTextEdit自帶的行數(shù)限制方法設(shè)置之后文檔會(huì)自動(dòng)丟棄最老的行塊。相當(dāng)于內(nèi)置了“滾動(dòng)日志緩沖區(qū)”不用手動(dòng)做截?cái)噙壿嬃撕糜玫煤堋?shí)測(cè)結(jié)果設(shè)置setMaximumBlockCount(10000)后文檔塊數(shù)永遠(yuǎn)維持在一萬行左右內(nèi)存保持穩(wěn)定追加性能也穩(wěn)定。這個(gè)接口很多人沒用過實(shí)際上是最優(yōu)雅的日志窗口內(nèi)存管理方案。10. 個(gè)人實(shí)操體會(huì)與補(bǔ)充建議10.1 選型上不要迷信功能越多越好我把“用對(duì)控件”看得比“用好控件”更重要。QPlainTextEdit和QTextEdit的選型本質(zhì)是功能和性能的權(quán)衡。做工程的人最忌諱拿著一把大砍刀去削水果——功能過剩的控件會(huì)讓項(xiàng)目背負(fù)不必要的性能包袱。日志、配置、腳本輸出清一色用QPlainTextEdit就對(duì)了。不要為了將來某天萬一要插入圖片而提前選QTextEdit真到那一步再換也不遲。10.2 性能優(yōu)化要有一個(gè)“及格線”思維優(yōu)化有一句話值得反復(fù)強(qiáng)調(diào)優(yōu)化是為了滿足場(chǎng)景需求不是為了追求極致。日志窗口限制1萬行是合理的限制10萬行也是合理的但限制100萬行就有點(diǎn)過度了——當(dāng)用戶要查找一條歷史日志時(shí)1萬行已經(jīng)很難快速搜到不如把日志寫文件用外部工具分析。性能優(yōu)化一定要結(jié)合業(yè)務(wù)場(chǎng)景來定指標(biāo)否則就是無底洞。10.3 單調(diào)的函數(shù)也能玩出花樣補(bǔ)充一個(gè)高頻效的小技巧把日志等級(jí)和顏色對(duì)應(yīng)起來用extraSelections做ERROR級(jí)別的紅色高亮。這樣在日志界面中不用看文字內(nèi)容掃一眼顏色就能定位危機(jī)。類似的做法還有把當(dāng)前行高亮顯示比如實(shí)現(xiàn)一個(gè)編輯器場(chǎng)景下的“當(dāng)前行背景色”connect(textEdit, QPlainTextEdit::cursorPositionChanged, this, [this]() { QListQTextEdit::ExtraSelection selections textEdit-extraSelections(); // 清掉舊的當(dāng)前行高亮只保留其他高亮 QListQTextEdit::ExtraSelection others; for (const auto sel : selections) { if (sel.format.property(CurrentLineProperty) ! true) others.append(sel); } QTextEdit::ExtraSelection currentLine; currentLine.format.setBackground(QColor(0x2a, 0x2a, 0x2a)); currentLine.format.setProperty(CurrentLineProperty, true); currentLine.cursor textEdit-textCursor(); currentLine.cursor.clearSelection(); others.append(currentLine); textEdit-setExtraSelections(others); });這個(gè)方案通過給format加自定義屬性來區(qū)分哪些是當(dāng)前行的高亮避免每次光標(biāo)位置變化時(shí)被誤刪。實(shí)際體驗(yàn)很接近主流代碼編輯器的觀感。10.4 日志組件務(wù)必考慮“外置可替換”最后一條建議是架構(gòu)層面的不要把日志輸出耦合死在某個(gè)具體的QPlainTextEdit上。我比較推薦在業(yè)務(wù)代碼里把日志接口抽象出去// 業(yè)務(wù)模塊只依賴這個(gè)接口 class ILogSink { public: virtual ~ILogSink() default; virtual void write(const QString level, const QString message) 0; };這樣寫的好處是開發(fā)階段可以把日志輸出到QPlainTextEdit看界面效果正式發(fā)布時(shí)可以直接替換成寫文件版本或者同時(shí)輸出到界面和文件。日志窗口本身只是IO的一個(gè)終點(diǎn)不應(yīng)該反向侵入業(yè)務(wù)邏輯。項(xiàng)目里加日志時(shí)一旦發(fā)現(xiàn)到處都是textEdit-appendPlainText就該反思一下是不是耦合過重了。這套組件我在幾個(gè)工具類項(xiàng)目里都用過穩(wěn)定性和實(shí)用性都經(jīng)過了實(shí)際場(chǎng)景的檢驗(yàn)。如果你只是需要一個(gè)能看日志的控件按這篇的思路走一遍就夠了如果你還想進(jìn)一步實(shí)現(xiàn)搜索、過濾、自動(dòng)歸檔QPlainTextEdit同樣能撐得住擴(kuò)展方式無非就是遍歷文檔操作光標(biāo)理解了這兩個(gè)核心很多高級(jí)玩法都能自己寫出來。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
91 手机在线播放 绯色| 亚洲综合九九| 亚洲综合激情五月久久| 国产精品久久久无码AV网站| 性爱视频免费网址| 天天92av| 天天欲望网| 色综合20p| 色五月av| 五月丁香激情综合网| 久久成年片色大黄全免费网站| 中文字幕精品专区搜索结果91| 日韩丝袜人妻AV| av午夜影院在线播放| 国产女大学生AV| 美女9118禁| 日日干夜夜欢| 78精品| 日韩 女同 综合| 国产99999久久精品| 无码久| 嗯嗯嗯,草死我| 爱爱动态120秒| 素人播放一区| 影音综合网| 亚洲蜜臀懂色| 中文字幕人妻色偷偷久久皮| 久久这里精品国产99丫e6| 久久精品小视频| 欧美丰满熟妇XXXX性ppX人交| wwwxxx日本爽| 亚洲中文一区二区三区| 波多野结衣一级视频| 亚洲开心网| 日韩97超碰| 亚洲日韩精品一区二区| 国产辣妈在线视频福利| 成人av性爱电影在线观看| 日韩成人私密一级精品av| 91宗合网| 永久免费观看的毛片的网站| 看黄片视频免费| 日韩一级特黄av毛片| 日本一区视频在线观看| 久久久久亚洲Aⅴ无码| 东北丰满熟女国产一区| 久操高青| 欧洲亚洲综合| 久久这里只| 91综合在线| 国产无码精品久久久久久| 精品国模无码| 91强热人妻| 国产97色在线| 久久视网78| 亚洲精品国产熟女久久久| 欧美日综合| 欲香欲色综合天天伊人| 国产精品扒开腿做爽爽爽视频| 男人的天堂2018| 日本一区二区亚洲综合| 一级黄色性爱A级片| 日韩AC| 亚洲国产日韩欧美熟妇在线| 操人妻少妇中文| 久久超碰亚洲人| 综合91网| 亚洲日韩精品一区二区| 久操九九九九| 青娱乐 青青青操 日逼| 欧美v亚洲v综合v国产v妖精| 精品一区二区人妖| 蜜臀久久久国产| 中文字幕第二页| 一级人妻性爱视频| 91精品大奶人妻| 欧美激情视频一区二区三区不卡| 97中文字幕一区| 男人天堂东京热| 内射小黄片| 国产一区二区视频在线播放| 成人在线永久| 91天天看| 天天爽天天| 中文字幕免费观看| 91高潮| 国产毛片久久久久久久| 精品丰满人妻一区二区三区免费观| 99热aaa| 欧美日韩久久精品爱爱| 天天操天天舔| 超碰久久草| 丰满人妻一区二区三区| 亚洲Av无码成人精品国产| 99国产精品人妻人伦| 久久久草草精品| 日韩极品无码B| http://qxhbdz.com| 精品少妇高潮久久| 午夜福利免费精品视频| AV男人天堂网| Blackedraw视频一区二区| 欧洲中文字幕| 日韩熟女乱伦中出| 亚洲少妇自拍中文字幕懂色| 国产精品一级特黄aaa大片在线观看 | 香蕉婷婷| 一本久久久精品| 日本性爱网址| 四虎免费视频| 久精品无码av一区二免费国产在线观看 | 校园春色综合| 超碰九7免费| 久久久精品成人国产| 手机久操欧美综合色码| 成人精品在线| 精品人妻av区天天看片| 天天流夜夜操| 高潮精品| 欧美一区二区三区大综合| 免费国产视频| 欧美日韩理论一区| 日韩精品在线观看观看| 国产白丝在线| 日韩欧美一级特黄大片| 女色综合| 亚洲图片另类| 4141514逼喷水三级片| 中国少妇啪啪视频| http://qxhbdz.com| 亚洲色图A| a在线观看| 少妇熟女一区二区三区| 精品视频123区小说区| 欧美色人| 99热导航| 亚洲啪啪性视频| 夜夜嗨一区二区三区直播内容| 国内自拍 日韩激情 99| 成人性交免费视屏| 天天日天天射天天干| 欧美v亚洲v综合v国产v妖精| 操学生天天| 日韩一性一交一A片俄罗斯| 乱色老一区二区三区的观看方式| 婷婷丁香熟妇综合网| 青草成人免费视频一COm| 99这里有精品| 国产精品无码av嫩草| 伊人久久亚洲色欲综合网站| 九九色色| 国产操偷| 天天综合中文字幕 91| 中文字幕 一区二区 亚洲无码| 啪啪啪精品| 影音资源男人日韩| 熟妇最新先锋一二三区| 亚洲无码AV九九九| 99人妻| 亚洲av热热色| 九九久久99| 欧美性爱18观看| 久久风骚城市| 97色色色综合网站| 麻豆黄色五月天| 中文日本免费高清| 国产伦精品| 色男人色天堂东京热| 99热这里只有精品8| 久久亚洲中文字幕视频| 搡老女人老91二区| 91精品人妻五十路| 神马久久久久久久久久| A V少妇特黄三级| 无码人妻精品一区二区中文| 少妇厨房愉情理伦片bd在线观看| 欧美伊人电影| 91老熟女91老女人| 人妻第一页| 最新精品久久蜜桃 | 国产白丝av| 久久一本大香蕉 | 91爱做| 98色网| 亚洲色图亚洲无码强奸乱伦 | 中文字幕、久久精品国产2020、久久综合久久自在自线精品自、亚洲 | 黄色小视频日本txt| 欧美亚洲中文| 男人的天堂免费| 久久华人网| 密臀AV在线| 欧美日韩情色一区二区| 久久久蜜桃一区二区三区| 日韩三级天堂在线观看| 亚洲熟女性高潮久久久| 亚洲国产精品无码AV久久久| 97久久超碰| 少妇蹲下露出大唇5| 亚洲天堂另类| 丰满人妻一区二区三区四区| 亚洲一区二区三区婷婷| 亚洲av综合色区无码一| 国产精品毛片?v一区二区三区 | 温婉少妇玩3p| 亚洲成人免费中文字幕| 国产麻豆福利av在线播放| 一级做a爰片久久毛片图片| 91香蕉国产尤物视频| 好属操| 日本男人天堂| 国产一区二区二区按摩精品啪视频| 欧色网址| 亚洲欧洲激情卡通另类文学四射小说网站| 日韩免费中文字幕视频| 黄色AV免费| 国产精品一区二区亚洲人成毛片| 中文字幕一二区二三区人妻专区| 亚洲暴力强奸AV| aⅴ日韩成人电影av在线免费看av大全| 老熟女乱子伦中文字幕一区二区| 国产这里只有精品| 狼天天狼天天大香蕉| 91狠狠综合久久久久久| 97爱欧美| 九热超碰| 成人性交午夜免费片| 日躁天天爽爽| 综合国产影视三级| 一级啊性爱在线视频| 制服乱伦| 一区麻豆 高清中文字幕| 亚洲一二三精品久久网| 午夜后入| 91九色丨风韵犹存| 亚洲成人在线高清| 激情六月天| 男女打扑克高清网站| 嗯嗯啊啊视频一区二区三区| 激情婷婷黑人91| 久久超碰网| 日本高清视频xxxx| 亚洲夜夜欢无码一区二区| 日韩三级一区| 性交一区二区在线播放| 中文字幕在线免费观看| 2019天天干天天操| 国产农村妇女精品1区二区| 无码人妻丰满熟妇区毛片| 久久九九97| 色视频蜜乳| 色色五月天激情| 亚洲色图加勒比| 色九九久九九| 18禁美女裸体无遮挡啪啪| 激情五月综合网| 久久精品人妻一区| 国产精品极品美女视频| 人妻久久久| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 亚洲av强奸乱伦| 欧美日韩情色一区二区| 青青草一区二区三区四| 天天躁日日躁xxxxx| 97干在线视频| 日本熟妇精品九九| 国产无马在线| 99自拍B亚洲 | 女人喷水视频在线观看| 欧美性暴力猛交XXXX| 亚洲同性aV综合| 黄色视频60分钟| 素人美腿视频网站| 国产97视频| 国产福利av精彩对白| 一区,二区,三区网站| 成人草草视频| 亚洲av强奸乱伦| 屁股久久久久久久久| 日本国产欧美一区三区二区| 天天综合91在线| 精品无av| 亚洲色综合| 青操影院| 欧美一级A片在线看视频性色| 久久夜夜夜| heyZO天然素人无码AⅤ专区| 中文字幕AV片| 巨爆乳肉感一区二区三区竹菊影视| 欧洲与亚洲欧美精品中文字幕| a'v在线资源| 久热色情精品| 超碰97色| 色好看av| 久久国产免费激情视频| 久久成人午夜狠狠| 亚洲精品啪视频| 日韩三级性| 欧美专区日本专区| 国产欧美日产一区二区三区 - 国产欧美日 | 九九探花视频在线观看| 91狠狠综合久久| 最新欧美色网| 明星性猛交ⅹxxx乱大交| 国产天天骚| 内射老妇BBWX0C0CK| 久久久久久91香蕉国产| 黄页视频网站野外| 色欲天香天天综合网-成年人三级片网站-欧美乱妇狂野-日韩国产专区-久久久久久 | 五月丁香婷婷啪啪| 欧美色就是色| 天美一区在线| 香蕉在线一区二区三区| 欧美欧美啪啪视频| 国产av热热色| 久久婷婷热| 久久午夜色播影院免费高清| 亚洲涩涩| 天天干天天插| 日本成人A片网站| 精品久久艹| 发朗少妇买婬全视频中文| 丰满人妻区一区二区三| 人人超碰在线观看黄| www.91理论| 97se亚洲综合自| 97玖玖人妻| 人人做人人妻人人夜视频| 欧美色吧综合| 熟妇熟女一区二三区| 亚瑟国产精品久久无码| 哈哈操电影| 成人综合视频久久| 精品超碰国产| 国产第12页| 91天美免费| 久久嫩草国产成人一区| 噜噜吧,噜噜色,噜噜| 亚洲不卡三级手机播放| 超碰伊人在线| 亚洲AV无码| 亚州操逼图| 欧美中文综合| 日本 情色 1区2区3区| 69精品在线| 插日本熟女视频| 老司机午夜精品视频| 亚洲天天精品| 曰韩香蕉97| 久久不卡一区二区| 99精品久久| 色欲无码人妻日韩欧美精品| 又大又大又大又粗爽高潮观看| 劲爆欧美人妖三区91| 国产精品经典一卡久久久 | 情色AV电影| 风流老熟女一区二区三区l| 亚洲色婷婷久久91| 先锋女优在线观看视频| 黑白配性爱AV成| 亚洲自拍一区夜夜操| 亚洲91少妇| 中文久久爆乳| 日韩A优精品在线观看| 国内毛片欧美香蕉精品| 色欧洲| 加勒比无码毛片| 天天干天天中出av| 九一综合网| 97免费视频网| 75大香蕉| 欧美综合制服在线| 欧美亚洲AN| 国产亚洲欧洲在线观看| 久久大陆| 九9热伊人| 97精品视频网站| 动漫片子网站3黄| 久久,精品一二三| 五月丁香色综合| 中文字幕黄色片| 亚洲操人| 色99视频| 亚洲色鬼| 老熟女熟妇| 97久久精品国产| 啊啊啊不要啊啊受不了了视频在线 | 欧美顶级黄色大片免费| 国产亚洲精品av一区| 久久久久久电影| 一级黄色视频网| 操逼逼中文字幕| 亚洲成人日韩小说| a在线视频免费观看| 欧美顶级黄片AAAAA在线免费看| 熟女色综合久久| 国产色精品午夜大片| 郑州宾馆老熟女露脸啪啪| 日韩操逼HD| 最近2019中文字幕国语免费版 | 超碰超碰超碰超碰的大鸡吧操黑丝袜| 91狠狠综合久久| 久久久久久九九九| 黄片视频观看| 色嗨嗨在线| 亚洲一区二区性爱电影| 懂色AV一区二区三区| 欧美三级一级| 欧美一区二区三区黄色影视| 九九九九免费| 国产日产精品久久快鸭的功能介绍| 日韩成人性爱AV| 翔田千里av一区二区三区| 日韩亚洲美女一区久久| 操死我了嗯嗯嗯| 熟妇女伦乱视频视频| 97资源久久| 国产一区二区三三视频| 五月婷婷AV| 在线天堂999| 久久精品高清无码一区| 久久青青草在线视频| 家庭乱伦国产精品| 日韩性爱再线视频| 97内射偷拍| 国产精品一区二区麻豆| 在线日韩日本亚洲国产| 日本午夜精品理论片A级APP发布| 99热精品国产| 亚洲se91| 国产区性爱在线视频秋霞豆| 丰满翘臀美女影院视频| 少妇天堂| 偷窥自拍A片| 日本精品国产视频| 人爽不卡视频| 日本123区操B视频| 九九热这里只有在线精品视 伊人草 成人菠萝蜜视频在线观看 | 六月激情婷婷| julia中文字幕在线观看| 97日亚洲欧美| 精品一区二区人妖| 国产十八禁视频| 久久9久| 综合自拍| 91色色综合| 91被操| 操狠狠| 亚洲三级。日韩三级| 玖玖资源综合在线视频| 国产精品视频| 亚洲第一页第二页激情| 天天综合网~69| 黑人性欧美| 粉嫩在线一区二区懂色| 台湾佬中文娱乐网久久久久久久久久com | 99精品九九九九九九| 中文字幕交换人妻| 日韩精品大香蕉伊人在线| 亚洲成人精品在线一区| 伊人色综合超碰| 久久久中文| 91狠狠综合久久久久久| 91情色在线| 最新日产中文在线麻豆| 蜜桃狠狠色伊人亚洲综合| 人人看人人爰人人操| 啊啊啊不要啊啊受不了了视频在线| 免费精品无码一级毛片牛牛影视| 91女网站| 强奸乱伦AV一天堂网| 久久一二区四| 欧美传媒| 91精品久久久久久久久久| 一线黄色免费性爱片| 91欧美性| 黄片在线免费在线观看| 超碰在线91| 射 色综合| 绯色一区二区三区不卡少妇 | 日韩少妇无码| 97色插| 一级做a爰片性色毛片久久| 免费农村成人少妇人妻Aa一区二区视频| 综合夜夜| 97干天天| 色色色99| 精品无码秘 人妻一区二区| 色哟哟国产精品免费网址| 国产精品探花色| 欧洲精品网| 欧美极度丰满熟妇hd| 日本布卡一区二三区| 日日夜夜干| 强奸乱伦AV一天堂网| 国产偷人妻精品一区二区在线| 蜜乳AV网址| 青草精品视频日本久久久久网站在线| av大香蕉网站| 乱老女人一区二区视频| 亚洲黄片免费在线播放| 少妇久久久免费| 日韩有码免费视频| 久久久久久亚洲中文| 久久久91福利姬| 一区二区三区欧美激情| 欧美久久草熟女| 久久丝袜| 这里只有精品视频在线观看麻豆 | 久久久久亚洲| 久久国产999| 超碰三级秋霞| 操逼网站视频漫画国产| 亚洲日韩人妻中文字幕一区| 成人精品水蜜桃久久久久久久| 五月婷婷六月丁香| 国产精品黄色三级av| 欧美日韩欧美| 天天摸天天舔天天操| 欧美久久九九| 天天干人妇| 欧美激情视频在线一区| 天天干18禁| 亚洲日韩东京热一区| 91人妻超碰| 久久AV无码网址| 国产精品午夜AV完会免费| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 成人资源中文字幕在线观看天天| 日韩人妻中文视频| 韩美日操逼| 久久久青青草| 俺也射| 欧美中字二区| 一区麻豆 高清中文字幕| 婷色五月天| 久久免费精品视频免一| 日韩精品在线观看观看| 韩国三级一线观看久| 97超碰美女| 久操免费电影| 97资源站国产精品| 国产黑白丝在线| 超碰97在线中文| 97超碰亚洲| 男人的天堂VA| 四虎av在线| 精品女同一区| 精品人妻一区二区三区蜜桃视频| 偷拍2020| 热热色国产一二区AV| 天天舔天天日天天射| 国产AV天美| 亚洲中文字幕有码视频一区二区三区| 婷婷香蕉欧美在线一区二区三区| AV 少妇 人妻 偷拍| 超碰在线99| 色五月婷婷久久| 国产97色在线| 人妻AV 中文字幕的| 一起草av| 精品久久青青草| 欧美熟妇视频| 殴美日韩m| 五月天综合网| 亭亭在线资源| 中文字幕国产| 日夜伊人网| 91天天| 亚洲电影中字一区二区| 91在线视频免费播放| 美女午夜福利免费视频| 久操精品网| 亚洲精品 大香蕉| 亚洲骚女一区二区三区| 99啪啪| 亚欧美综合网。| 骚日日av| 91搡老女人老妇女老熟女歌词翻译| 日韩啊V| 日韩人妻制服丝袜av| 亚洲午夜福利在线影院| 91日韩在线| 99久久无色码| 941超碰| 亚洲97精品| 中国农村熟妇毛片视频| 亚洲欧美日韩精品久久久一区二区| 欧美婷婷五月天| 蜜色网色哟哟| 视频二区熟女人妻| 亚洲综合在线第一页| 国产黄色视频久久| 午夜男人一级A片7777| 旡码电影特区| 综合一区二区影视| 日韩精品人妻| 亚洲成A∨人影院在线欢看| 校园春色 男人天堂 | 香蕉黄色一级视频| 久久露脸国产老熟女| 国产有码一区| 精品少妇高潮久久| 久久青青草原免费视频| 爽爽淫人网| 91N综合在线| 老妇女91| 亚洲熟女av日韩熟女| 宗合情欲网| 久久久青青草| 亚洲五码一区二区三区| 蜜桃臀 后入 一区 二区 三区 在线| 视频二区熟女人妻| 国产家庭乱伦表演| 午夜天堂精品久久久久91| 亚洲涩涩| 91成人高清在线观看| 激情五月婷婷| 国产精品午夜精品| 曰韩操B| 欧美一区二区在线资源| 九九九九精品精| 黄色av片三级三级三级免费看| 国产精品 午夜福利| 亚洲美女精品九九视频| 精品成人av一区二区三区在线| 日韩精品人妻中文字幕久久久| 久热最新在线杭州| 九九久久综合| 天天操狠狠日夜夜干超大胆开放com大香蕉视频在线观看 | 人妻在线大香蕉| 久久国产成人精品国产成人亚洲| 色五月婷婷久久| 中文字幕av一区二区三区人妻少妇| 国产隔壁老王影院在线| 亚洲最大的黄色电影网站。| 97视频在线播放| 国产毛片精品一区二区色欲黄A片| 91九色丰满高潮| 日韩成人性爱AV| 国产精品在线一区二区| 色色香蕉| 亚洲亚洲亚洲天堂天堂| 中文字幕狠狠玩| 伊人在线大香蕉视频久久| 午夜精品五区| 国产中文字幕在线观看| 久久艹逼视频| 国产精品一区二区三区四区五区| 免费精品99| 精品九九九九九九| 青青草日逼视频| 国产成人亚洲精品无码最新在线| 欧美性色综合网| 91东京热男人的天堂| 欧美情色贴图| 亚洲国产精品成人无码久久久 | 亚洲另类欧美精品| 熟女高潮合集-永久久久-成人AV| 日本Xx性爱| 亚洲第一男人天堂| 精品少妇一区二区三区免费观看| 精品人妻一二三| 欧美大香蕉97| 日韩成人精品视频自拍| 天天操妹子| 富二代亚洲精品99| 欧美αv.com| 96精品久久久| 9/A片 | 超碰视97中文| 日韩精品区二区三区不卡| 蜜臀一区二区三区在线| 国产一区二区三区,在线观看观看| 欧亚乱色熟女一区二区| 97超碰超| 久久日本熟女精品一区| 国产高潮AA片免费看| 日韩肏逼视频| 丝袜色综合| 六九九九| 欧美日韩操逼动图| 91精品久久久久| 在线观看A啊啊啊| 亚洲女毛多水多21P| 亚洲动态色图| 日日妻色网| 国产玖玖| 国产精品激情久久久久久久| 成人久久久| 久久人妇| 天天淫人人妻日日色| yellow网站免费观看日韩高清无码| 超碰久久.com| 另类图片亚洲加勒比另类图片亚洲加勒比另类图片亚洲加勒比 | 午夜天堂精品久久久久91| 另类小说综合网| 唯美清纯 妖精视频| www.男人天堂| 亚洲。日韩。欧美| 99久久久久| 影视综合无码少妇| 久久老女人| 四虎精品永久在线观看| 欧美情色贴图| 亚洲色图 欧美热图 清纯唯美 另类自拍 | 日韩免费性爱视频在线观看| 日韩免费高清大片在线| 亚州男人天堂| 久久久久久人| 日本中文字幕一区| 麻豆婷婷成人一二三| 婷婷五月丁香五月| 精品一二三区久久AAA片| 五月天久久综合网| 2021国产成人精品久久| 67914在线兔费成人视频| 东北女人| 欧美天堂日韩三级国产传媒| 99色热| 四虎影院成年人片| 91成人久久| 伊人黄色片| 国产强奸乱伦欧美| 久久国产乱子伦精品免费女,网站| 乱操9999| 人妻人久久精品中文字幕| 91影视亚洲| 人人搡人人肉久久精品| 国产亚洲欧洲在线观看| 中文字幕片| juliaann精品熟女一区| 日韩美脚一区二区网站| 熟女丰满人妻一区| 玖玖综合.com| 台湾佬激情综合| 麻豆天美久久91| 69精品在线| 一二三啪啪专区| 久久精品免费| 中文字幕制服欧美久久一区| 久久25| 91网亚洲| 欧美伦乱爱| 亚洲drav色图| 亚洲好色人妻| 久久九九97| 亚洲色图欧洲| 中文字幕av亚洲精品| 84YTCOM性无码| 操国产逼| 亚洲免费在线探花| 99久久精品无码一区二区| 97任你吞精| 99热综合| 日本少妇va7777| 久久久久久9999| 午夜无码熟妇丰满人妻| 婷婷探花久久精品一区| 亚洲熟女人妻中文字幕一区二区| 久久久久久久人妻丝袜| 欧美爱三级日韩久久| 超碰成人公开| 国产精品视频精品一二| AV 少妇 人妻 偷拍| 国产精品 亚洲情色| 夜夜福利| 精品国产a∨一区天美传媒| 91国模| 大香蕉黄色一级片免费看| 成人 日本A片无码8888| 色色激情五月天| 第四色色综合91| WWW美腿丝袜香蕉中文| 啊啊啊啊无码| AV污污污污| 女优视频第10页| 欧美亚洲AN| 欧美激情 亚洲色图| 99婷婷一区二区| 日韩欧美俄罗斯A片| 天天影视网综合少妇| 黄呦呦在线| 日日夜夜骑| 欧美Aⅴ| 九九激情网| 一直超碰| 国产女人视频三四五区| 浪人综合网| 日韩美女久久一区二区三区| 91老熟女91老女人| 小说区 图片区色 综合区| 亚洲无码久久久久久久| 超碰97网址| 精品无码少妇| 八人操人人摸人人看| 后X久久| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 青青草导航在线视频| 日本操逼无码| 1024人妻| 久久网亚洲| 亚洲性爱电影| 久久久艹艹艹| www.91视频网| 成人免费福利在线观看| 国产美女精品| 中文乱码字幕观看| 午夜天堂啪啪| 久久久91福利姬| 天天激情干| 在线天堂999| 97视频在线播放| 99久久久久| 国产精品久久久久久久久久二区三区| 亚洲精品白浆高清久久久久久| 一二三区在线| 天干天干天干天天做| 女人 A一级| 蜜桃视频一区二区三区| 69av一区二区三区| 91九久| 99re这里只有精品9| 97自拍视频在线| 人妻激情视频| 国产AV久久久蜜爱影集| 91网站在线播放| 强奸乱伦麻豆| 欧美日韩美女精品久草一区二区三区 | 欧美性爱1080p| 男人网站婷婷| 强奸乱伦亚洲第一页| 啊啊啊在线观看免费视频| 日本操逼无码| 人人操天天爽| 日韩无码视频黄色| 色婷婷综合久久中文字幕雪峰| 探花精品 一区二区| 久久综合18p| 国产精品成久久久久午夜午夜| 日本一区二区电影网站| 中文字幕av亚洲精品| 欧美色图片91| 黄色大片免费在线| 久久日本熟女精品一区| 黄色AAAAAAAAAAA大片| Julia Annxxxxx| 91在线无码精品秘 软件| 小电影欧美91| 女同在线视频一区| 精品国产av一区二区三区四区入口| 人妻天天爽夜夜爽精品2| 久久久久久久久久va| 少妇色综合| 婷婷精品视频| 欧美91精品国产自产| 大香蕉伊人在线成人AV在线观看 | 青青草久草AV| 欧美亚洲激情一二三| 久操网无码在线| 国产成人精品一区| 色色五月婷| 日本一区二区中文字幕久久| 一区二区 日韩 欧美 国产 传媒| 精品人妻一区二区视频| 破处bbq| 日本91白丝| 国产一区二区在线播放量| 蜜桃精品一区二区三区久在线| 99视频在线| 日本爽爽爽爽爽爽免费视频| 试看60秒| 精品国产乱码久久久久久久久1| 国产精品久久天天干| 哑洲在线| 欧美亚男人的天堂| 精品性爱一二三区| 黄骗免费网站| 91欧美丝袜| 九九热男人天堂| 亚洲成人福利电影免费| 精品福利| 操老熟女AV| 欧美大香蕉卡久久| 激情综合网五月婷婷五月天| 亚洲另类天堂| 韩国嫰模上门援交视频| 91亚州日韩高清| 亚洲乱码国产乱码精网站| 天天肏天天干| 日韩无码服务区| 黄总AV色图| 日韩午夜啪啪视频| 午夜福利激情在线视频| 91天天综合日韩欧美| 亚洲大色鬼| 曰本精品久久久| 超碰99在线观看| 日本免费中文字幕在线| 久久男人天堂| 免费男人的天堂| 亚洲吊色| 精品免费一区二区三区在线亚洲人成| 亚洲精品日韩国产欧美| 成全在线观看免费观看| 一区在线精品中文字幕| 97久久久网站| 99热国产| 天天干天天中出av| 96精品久久久久中文字幕| 免费看毛片操穴| 国产成人精品日本亚洲语言| 无码黑人精品一区二区三区三| 国产免费黄色一级大片| 国内一级精品| 欧美综合自拍亚洲综合图| 成人五月天色网| 97蜜桃综合| 人妻嗯啊啊在线播放| 插欧洲美女欧美精品| 美女极品一区二区三区| 操人人| 欧美成人性爱视频在线播放| 一起草在线视频| 亚洲欧美清纯| 五月天婷婷社区| 亚洲玖玖爱| 精品熟妇视频一区二区| 少妇蹲下买菜露大唇0| 色臀aV| 青青草无码视频| 丝袜色综合| 欧美极品少妇| 熟妇一区,二区,三区。| 九草九九九| 97视频在线免费| 亚洲风情综合网| 极品人妻少妇综合| 怡春院久久| 亚洲男人天堂2017| 欧洲精品一级二级精品综合视频综合| 风韵犹存大大大大香蕉 | 国产精品久久久久无码A√| 无遮挡一级毛片视频免费的| 人人贴人人摸| 日韩亚洲中文字幕在线| aaaa少妇高潮大片| 国内毛片免费h片在线| 99综合视频| 欧美色偷拍| 综合网久久| 偷拍色图| 亚洲 欧美综合| 大学生美女口爆| 日韩精品一区二区高清| 很黄很色的视频在线观看| 国产亚洲精品美女久久久m| 欧美性爱系列| 综合色图区| 粘花网06av视频| 中文字幕第23区| 日夜尻逼网| 婷婷激情四射| 国产肏逼网站| 人摸人人操人| 日本三级中国三级99人妇网站| 亚洲中文制服诱惑| 久久大精品乱码视频人妻熟女| nuu12国产麻豆精品| 熟女精品日韩一区二区三区| 日韩欧美大片免费高清啪啪| 国产高清MV操逼视频| 激情综合婷婷| 亚洲丝袜色图| 九九超碰综合网| 99无码狠狠久久| 思思热在线cao| 欧美日韩国产在线| 青青草大香蕉在线视频| 骚货操死你| 91被操| 一区在线观看中文字幕| 99热在线只有精品| 乱操乱伦AV| 色婷婷小说| 91/欧美| 久久久久99999| 无码丰满熟妇一区二区浪潮AV| 亚卅熟女乱色| 五月天色电影| 91色婷婷综合久久中文字幕二区| 亚瑟国产精品久久无码| 久久综合99| 乱欲性色| 国产一级高清免费观看| 国产精品久久久久综合| 人人澡综合涩| 日韩无限资源| 国产精品免费视频人成| 欧美se亚洲| 亚洲欧美97| 国产精品一二三在线看| 欧美日韩理论一区| 91中文字幕制服丝袜免费视频| 日韩欧美aⅴ综合网站发布| 日韩三级久久久| 青青青草原| 啪啪AV导航| 国产福利夜| 激情小说亚洲色图| 大香蕉九九| 国产中午字一暮区| 欧美亚洲第一页| 免费农村成人少妇人妻Aa一区二区视频| 天美传媒精品久久视频| 欧美老妇曰批的视频| 亚洲91网。| 九九九精品| 亚洲少妇色| 亚洲高清欧美总合| 日本污ww视频网站| 后入式视频国产自| 日本三级A片网站com| 国产一区二区三区不卡手机在线| 天天综合青苹果| 99久久久久| 色97欧美| 激情四射五月天| 久久精品无码熟妇一区二区三区视频导航| 亚洲精品一区二区精品| av操操不卡| 1000部熟女视频在线观看| 色穴精品| 亚洲图片欧美| 殴美牲| 欧美色网| 人妻精品4K4K4K4K4| 色网站导航大全| 欧美欲色| 国产精品永久免费10000| 91欧美美女日韩国产婷婷| 亚瑟国产精品久久无码| 日韩啪啪啪视频| 日韩图区 偷拍| 久久久国产精品亚洲精品| 亚洲色 国产 欧美 日韩| 青青青草伊人精品| 免费人成?大片在线播放| 女人天堂网| 日韩性爱播放| 久久在肏| 国产四虎在线| 岛国福利在线精品播放| 久操九九九九九九九九九九九九九九九九九九九九九九九九九九九九 | 日本亚洲熟女视频| 欧美se综合| 啊啊啊 在线观看| 欧美区亚洲区偷拍区| 精品人妻一区春色| 人妻熟女av国产网站| 久久黄人人爽视频| 99久久无色码| 欧美一级黄片视频在线| 亚洲骚男同com| 久久99网站| a片自拍直播视频| 91 丝袜在线观看| 岛国精品视频在线观看| 蜜臀久久99精品久久久久久-DVD| 亚洲精品色| 亚洲 日韩 丝袜 熟女 变态| 人妻少妇无码| 啊啊啊啊啊啊啊国| 26uuu国产日韩综合在线观看| 超碰4A| 91色图片| 偷看洗澡一二三区美女| 亚洲色图欧美一区二区不卡| 九九国产| 屌色在线97视频| 九月激情婷婷| 97综合激情| 绑缚麻绳人妻寝取完整版| 日本在线视频导航| 日韩国产精品人妻无码久久久| 欧美影音在线| 日本高清电影欧美色图| 一区二区三区黄色片a| 男人综合网| 日韩电影天堂视频一区二区| 中文字幕在线观看丝袜| 操逼大黄片| 天天射日日干| 欧美高潮| 夜夜操av亚洲一区二区| 国产无套粉嫩白浆在| 综合伊人网12色| 91国产丝袜白虎| 欧美伦乱爱| 在线观看十八禁| 国产超碰人人操| 蜜乳Av成人片网站| 久久久久少妇| 亚洲中文字幕av | 久久久久久久久久9| 懂色av中文字幕一区二区三区天美| 丝袜内射| 五月天综合| 天天干夜夜操网| 亚洲天堂一区二区久久| 97天堂| 91青青在线| 亚洲精品黑丝| 330dv亚洲成年视频网| 99热色这里只有精品| 99操逼| 性色av网站| 日本一级婬片试看三分钟| 操国产逼| 亚洲欧美人妻| 久热这里只有精品9| 蜜桃臀一区二区三区久久| 玖玖爱一区在线| 综合网~91综合网| 97亚洲国产影视| 小少妇| 91一起操| 伊人色综合网电影| 亚洲中文日韩精品| 大香蕉强奸乱伦| 隔壁邻居波多野结衣中文字幕| 国产极品粉嫩馒头一线天av| 国产真实子伦对白| 精品午夜福利导航| 春色校园综合网| yazhououmeizongya| 午夜福利在线合集| 国产乱人妻精品入口| 99re69| 久久超碰、| 亚州精品丝袜-不卡成人免费| 人妻日日夜夜精品| 久久久不能久久久久| 亚州成人a∨| 日少妇亚洲版| 你草精品在线视频| 久久一二三四不卡| 亚洲欧美一区二区不卡视频播放 | 男人天堂2017| 一级毛片电影免费看| 人人搞人人插人人操| 黑人精品XXX一区一二区| 性爱网站一区二区| 黑人白女精品一区| 国产自产一区视频在线| 国语对白在线播放视频| 十八禁啪啦拍视频无遮挡| 色婷婷狠狠| 欧美亚洲激情小说| 国产精品久久久777| 伊人久久蜜月|