久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(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
返回資訊列表
中文字幕 人妻不满 在线视频| 一起草精品人妻| 亚洲天堂一区| 成人乱人伦一区二区| 国人欧美精品一区二区| 又大又大又大又粗爽高潮观看| 黑人中出21连凳花野真衣| 黄片com.| 波多野结衣被操50分钟免费视频| 丰满人妻-区二区三区免费看 | 日韩欧美亚洲自拍偷拍| 日本黄色精品| 国产传媒av天美传媒在线| 大香蕉92| 中文字幕女同在线| 欧美高潮在线| 精品无人区麻豆乱码久久久| 亚洲性爱高潮影院| 五月天成人综合| 国产中文大片资源中文字幕 | 久操热| 久久久久久一日韩字幕无码| 九九热AV| 天天视频黄| 极品肉射| 欧美色网| 91精品人| yaouchengrenav| 色97干| 亚洲日韩东京热一区| 中文有码9| 91碰碰| 亚洲区限制级| 中文字幕精品亚洲熟女| 欧美性夜| 啪啪视频免费在线观看| 人妻色偷色噜| 富女玩鸭子一级毛片| 日韩在线国产字幕| 欧美 亚洲 综合 制服 另类| 久久少妇视频| 国产女人9999| 俞拍自拍| chaopen97久久| 日韩青久久| 国产精品动态一区二区三区四四| 国产激情在线| 欧美日韩在线视频网站| 欧美呦呦性爱| 国产女生在线| 五月婷婷性爱| 玖玖人人爱| 国产九九久久久精品| 亚洲一区二区三区麻豆传媒| 亚洲综合图片在线| 精品传媒在线一区| 香蕉国产精品麻豆亚洲欧美日韩| 无码乱人伦中文视频| 自拍偷拍2025在线观看| 久热这里| 亚洲性猛交| 91激情综合| 国产丁香精品露脸视频| 大香蕉伊人75| 台湾成人无码AV| 亚洲色图殴美色图激情乱伦| 欧美性战999| Julia Annxxxxx| 色欧洲| 一级@啪啪视频| 黄片com.| 久久久9品一区二区三区| 国产日韩人人| 中文字幕一二三| 内射老妇BBWX0C0CK| 久操网视频| 国产乱伦性爱AV| 国产最新AV| 人妻内射一区二区在线视频| 人妻娇喘 激情视频| 欧洲亚洲国产综合在线| 热九九精品| 久草视频制服诱惑| 又黄又硬又粗又长国产视频| 亚洲欧洲无码bt精品合集| 色噜噜精品一区二区三| 在线女人91| 亚洲综合伊人| 伊人黄色片| 久久极品伊人| 暴力av在线| 伊人激情五月天一区二区| 3571色综合一区二区二区| 欧洲大香蕉| 日本中文字幕不卡视频| 欧美在线视频99| 黄色一区三区| 久久 国产 无码| 欧美性天天影视| 天美传媒av一区二区| 2017天天插| 老熟女搡BBBB搡BBBB视频| 97就爱干| 久9精品| 1024午夜激情男人的天堂| 羞答答AV中文字| 白丝被操91| 懂色AV一区二区三区| 无码九九九九| 天天插天天操| 99久久免费看精品国产一区| 国产福利小视频高清在线观看| 91N五十路| 人妻激情视频| 另类天堂| 欧美精品庄| 97人人模人人爽人人| 成人片视频| 中文字幕久久婷婷丁香五月天| 99亚洲天堂| AV天黑人| 三级三久久线久久99久目本WW| 久久久久国产| 女人爽到高潮潮喷18禁网站| 999精品久久久久久久| 久久妇| 欧洲综合无码| 欧美丝袜激情| 啊啊啊啊嗯嗯嗯用力好爽| av麻豆啪啪| 久久久精品电影| 一及黄久一点| 伊人激情五月天一区二区| 蜜桃一区二区三区| 中国国国产一级特黄毛片| 麻豆一区在线| 日韩一级欧美一级在线观看| 日日躁夜夜躁狠狠躁超爽| 91黑丝在线播放| 中文字幕三四五区| 欧美性色综合网| 国产三级资源在线观看| 久久九九久精品国产尤物|国产精品爽黄69天堂A片潘金莲,国产亚洲精品第一综合 | 久久久9 9 9精品| 91在线国产后入风骚翘臀美女素人| 欧美黄色手机在线观看| 少妇三P| 久久久久亚洲av综合波多野制衣| 偷拍99| 激情开心五月天| 欧美色图综合| 天天操天天日天天干| 午夜黄色免费在线观看| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区 | 成人av动漫在线观看| 天堂综合网| 91九九九逼| 国产区91柔拿会所技师| 天天综合青苹果| 日韩精品人妻系列无码天堂| 亚洲欧美国产成人综合不卡| 亚洲高清视频在线免费观看| 91蜜桃传媒精品久久久一区二区| 大香蕉AV丝袜| 国模吧 一区二区三区| 亚洲一二三四区| 综合色拍| 在线人妻熟女一区二区三区四区五区| 看一级特黄a大一片| 久久这里只| 一区二区三区成人| 久久久久久夜夜夜夜夜| 国产午夜无码片在线观看影视| 国产精品96久久久久久| 另类专区加勒比| 偷拍网站久久男女男| 精品高清一区二区三区三州| 夜夜躁狠狠躁日日躁av| 大屁股熟女一区二区三区| 91女人的网站| 亚洲国产精品久久久久久久久久| xxx0国产在线播放| 黄片免费看的| 久久中文字幕不卡人妻| 久久久久久久9| 国产免费一区| 天美传媒AV国产在线| 一区二区 韩日AV| 欧美精品xxxwww| 欧美精品宗合| 9Ⅰ老熟女| 国产免费内射视频| 成人性生活高清视频在线播放| 国产久久久久影院老熟女| 白丝AV网站| 日韩在线视频1234| av天天在线观看| 亚洲五月婷婷| 日本黄 R色 成 人网站| 激情九月婷婷| 九热视频| 大奶啊啊好爽 | 大香蕉琪琪日本女优不卡| 东北女人av| 999久久久精品国产| 色久桃花影院在线观看| 少妇一区二区三区精选| 国产又色又粗又黄又爽| 日韩中文字幕人妻视频| 成人性爱视频在线看| 91精品无码久久久久久久 | 超碰人人乐97| 国产人妻久久精品一区二区三区| 欧美后入式| 天天干1区2区在线| 色噜噜人妻av中文字幕| 97免费在线| 91综合网站| 日韩亚洲欧美中文字幕| 97爱爱| 91精品人| 欧洲成人性爱视频| 免费人成?大片在线播放| 亚洲日韩美女中文字幕乱| 天天做日日做天天欢。| 啊视频在线| 久久亚洲婷婷| 日本九九久久99播| 精品乱码在线观看| 亚州色综合| 色吧5亚洲| 网友自拍第一页| 凹凸视频在线一区二区| 国内偷自视频区视频综合| 老司机天天操| a在线观看| 日韩av女优在线免费一区| 夜夜嗨av午夜成人| 男人天堂网手机版婷婷| 欧美偷拍| 欧美黄色大片在线观看 | 综合免费无码中文| 首页亚洲国产高跟丝袜诱惑视频| 国产高清1234区| 九热大香蕉| 色偷偷超碰亚洲| 亚洲第一视频 欧美风情 日韩| 亚洲牲交| 亚洲欧美中文日韩视频中国语| 国产欧美伊人| 曰本特级特黄特色黄色A级网站高清在线免费看 | 成人免费视瓶| 99热综合| 中文字幕久久亚州无码| 嗯嗯不要视频| 日本色色色视频| 蜜桃久久综合视频| 国产精品天干天干综合网麻豆 | 亚洲欧美色图小说| 91狠狠色丁香婷婷综合久久| 91成人国产综合久久精品蜜月| 蜜臀一二三区| 亚洲精品一区二区精品| 玖玖视频在线资源一区二区三区| se,,,亚洲欧美| av日韩在线观看电影| 91综合在线| 天堂资源站| 九九综合九九综合| 国产一区二区三区中文字幕| 亚洲精品蜜桃久久久| 国产成人精品必看| 超硑97精品| 美女网站91| 一块操欧美| 天天综合网~91入口| 亚洲性爱成人| 欧美九九爱| 天天夜夜rb| 亚洲欧美日韩精品久| 中文字幕av久久爽Av| 男女啊啊啊啊啊| 久久精品色欧美aⅴ一区二区| www.91欧美| 九色 人妻 大香蕉| 国产精品乱码久久久| 人妻乱仑一区二区三区| 国产精品对白自产拍| 久综合国内精品自在自线| 神马精品视频| 国产精品999zyz| 国产福利在线视频网站| 亚洲AV资源| 中文人妻av高清一区| 天天综合网~91| n1038 一二三区| 久久嫩草| 久久手机好看网站| 国产真乱mangent| 91高潮| 亚洲自拍一区夜夜操| 欧美在线|亚洲| 久久精品免费| 老熟女乱伦一区| 日本人体九九九九九九| 91中文字幕制服丝袜免费视频| 久久精品店| 色婷婷成人综合| 亚洲熟女人妻中文字幕一区二区| 九九热免费国产视频婷婷伊人| 欧美 亚洲精品首页| 婷婷丁香五月天综合东京热| 超碰97在线中文| 国产三级日产三级韩国三级| 婷婷久久久精品| 福利色色| 男人的天堂va在线| 欧美一区二区三区黄色影视| 国产中文福利| 91美女视频电影| 搡老熟女老女人老熟妇免费视频| 9精品久久久久| 激情综合五月| 欧美精品精品一区二区| 亚洲drav色图| 九九香蕉网| 熟妇乱伦一区二区| 国产精品在线一区二区| 水野优香在线观看| 国产女大学生AV| 一区二区不卡| 九月丁香婷婷| 91搞逼视频| 精品久操| 欧美日韩黄色片一区二区三区四区人与兽做爱| 国产激情av女片自拍| 中文 人妻 制服| 日韩99神马视频片| 91粉嫩萝控精品福利网站_精品影音先锋国| 色欲久久99国产精品久久久久久| 色香在线| 猛交交| 大香焦A片| 久草综合网| 91色黑人少妇| 久99热| 麻豆AV96熟妇人妻| 中国AV美女| 97国产高清视频在线观看| 欧美日本一区二区a人| 婷婷五月天久久精品视频一区二区三区| 久久风骚城市人| 欧美中文字幕男人天堂久久精品| 亚州色站 日韩电影| 久草久日| 啊啊啊啊二区好大| 2001天天操| 国产大学生高潮在线播放| 操逼日批| 翔田千里无码一区| 天天网综合| 亚洲久草AV色图| 久久一二三四不卡| 美日韩一卡二卡三卡免费人妻精品| 国产精品亚洲一区二区三区四区| 亚洲欧洲综合成人av一区| 久久精品人妻一区| 色色毛片| 日产操逼| 日韩免费中文字幕视频| 日本操逼视频免费| 天天综合网日韩| 亚洲欧美国产精品久久久久久久| 日本色日夜干| 美欧色综合| 国产麻豆91欧美一区二区久久婷婷国产精品| 久久亚洲人妻| m欧洲一级午老| 日韩超碰精品综合| SS久久| 日韩久久超碰色| 亚洲色人妻综合| 色综合一区二区三巨| 另类图片五月天| 亚洲AV无码国产成人| 久久久久九九九| 一级黄色牲爱A级片| 国产女人和拘做爰视频| 国产自产一区视频在线| 欧美人妻精品一区二区| 97人人射| 久久鲁夜| 亚洲天堂另类| 2017av无码免费无线播| 超碰国产精品无码| 岛国大片在线观看网站入口| 国产精品无套内谢| 亚洲激情在线| 女人天堂AV五区在线| 91精品人妻一区二区三区蜜桃臀| 久久婷婷亚洲欧| 麻豆天美在线喷水AV| 欧美96交| 亚洲 欧美 日韩 国产一区二区| 日本孕妇一区二区视频操逼免费看 | 美国精品国产精品| 精品性爱无码在线播放| 天天爱天天韩国日本牛牛牛牛| 嗯嗯啊在线视频| 色欲久久久久综合网| 狠狠色伊人亚洲综合网站色| 欧美丝袜美女电影一二三四区| 日韩啪啪网| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 婷婷丁香人妻 | 亚洲中文字幕熟女| 中文字幕交换人妻| 屌逼麻豆| 女生自91网站| 国产综合久| 久久精品熟女亚洲AV麻豆软件| 免费av高清无码| 偷看洗澡一二三区美女| 人妻91少妇| 国产极品粉嫩馒头一线天av| 亚洲日韩美女中文字幕乱| 97婷婷色| 一本大道综合伊人精品热热| 婷婷国产精品一区二区| 欧 美 自 拍 偷 拍| 亚洲av乱伦色图网站| 青青草亚洲一区 | 午夜AV人气不卡| 99熟女| 亚洲码和欧洲精品激情系列| 国产2.3.4区| 欧美gv在线观看| 亚洲av强奸乱伦| 亚洲射综合网| 青草精品视频-日本久久久久网站| 免费一级精品啪啪视频| 亚洲情色电影网| 亚欧美色图| 99精品欧美一区二区三区桃色| 天天干,天天日| 97丝袜亚洲在线播放| av激情亚洲五月天| AV 少妇 人妻 偷拍| 亚洲精品97中文字幕| 91福利网在线观看| 爱射综合| 中文字幕人乱码中文字的预防方法| 91五十路| 性爱Av免费| 999狠狠综合| 超碰久草| 亚洲午夜福利视频| 国产精品3| 国产成人自拍视频视频| 黄色不卡视频| 日本免费一级AAA大片器| 国产在线不卡导航| 亚洲九九九| 色五91| 天天碰久久入| 亚洲九区| 97超碰大| 国产一区二区三区中文字幕| 国产精品乱码久久| 超碰av人人人| 视频一区二区免费在线| 久久九九一区二区三区成人| 国产精品久久久久无码Av网曝门 | 久日91在线| 人人艹亚洲| 97超碰资源网| 欧美专区日本专区| 亚洲美腿丝袜香蕉影视欧美成人| 夜色AV无码手机在线影院| 超碰免费欧美7| 91三级理论片播放器| h色99999| 一块操欧美性爱| 国产丁香精品露脸视频| 另类在线| 欧美激情激情xxxx欧美专区| 97操97色| 中文字幕aⅴ在线视频| 国产辣妈在线视频福利| 久久亚洲骚逼综合| 国产精品福利视频播放| 欧洲精品区| 97人妻碰碰中文无码久热丝袜| 欧亚 另类 久| 久久人妻97久久久久久久| 久久欲| 综合九九| 97久久久久久久精| 亚洲 自拍偷拍 欧美| 麻豆a'v电影| 色婷婷在线视频| 无码高清少妇久久| 一本色道久久综合狠狠操| 五月天综合网| 久久黄色性爱视频| 亚洲成成熟女人综合一区二区| 丁香五月激情综合| 日韩精品国产一区二区| 亚洲区小说| 在线天堂999| 美女黄频a美女大全免费皮| 91色插| 熟妇精品juliaannAV| 日韩av在线播放不卡| 91丝袜美女视频| 中文字幕女同在线| 黄页18禁| 欧美 亚洲 偷拍自拍| 凹凸 69堂 在线播放| 亚洲国产欧美中文永久| 长久操视频| 狠狠色一区二区中文字幕| 97精品综合久久| 在线看免费无码AV天堂的| 久久久久久69国产一区二区| 99re这里只有精品中心播放| 欧美人妻精品一区二区| 久久精品国产Aⅴ| 干美女人妻| 亚欧中文字幕在线视频| 丁香五月天堂网| 93人人操人人| 日韩极品无码B| 91黄站| 免费成人在线熟妇网| 久热伊人| 精品v日韩欧美国产| 日韩性爱啪啪视频| 密臀在线免费观看| 人妻天天操天天爽视频免费| 亚洲天堂无码| 天天综合网日韩7799| 色在线视频导航| 日本不卡一二区| 久久99久久99精品天美传媒棢·纸:. | 人人妻人人玩人人澡人人爽| 麻豆色约约| 中文字幕人乱码中文字的预防方法 | 欧美 日韩 另类 亚洲| 国产 日韩 欧美 人妻 熟女 中文 69人妻精品一区二区绯色 | 91N欧美| 狼人久草| www.狠狠操| 性色av婷婷久久一区二区点复制| 中文字幕美女91| 91综合天天| 天天热精品| 国产亚卅97| 欧美成人精品A片免费一区99| 超碰国产精品久| AAAAAAAAA黄片| 丰满人妻一区二区三区四区| 亚洲欧美黄| 精品久| 亚洲精品国产精品成人| 青娱乐福利99| 日韩操逼HD| 亚洲成熟国产精品美女| 国产高清成人传媒影视| 婷婷五月天在线观看| 91无人区卡一卡二卡三乱码入口最新版:能让用户有更多选择的选择-经典说说-爱 | 97 超碰 人人做 人人爱| 亚洲国产综合久久久性感熟妇| 欧美美女自慰一区二区三区| 亚洲宅男天堂| 91av熟女人妻| 国产一级特黄大片处女| 女人 A一级| 国产热RE99久久6国产精品首| 一级免费啪啪片| 人妻AV 中文字幕的| 九九热男人天堂| 在线综合 亚洲 欧美中文字幕 | 午夜综合在线| 97亚洲国产| 夜夜爽夜夜摸夜夜操免费视频| 青青草在线视频播放器| 色99999| 99re免费视频精品全部| 久久久久久AⅤ无码免费肉站| 99欧美| 欧美天堂日韩三级国产传媒| 欧亚日韩综合精品国产| 亚洲人久久久久日| 翔田千里AⅤHD无码| 国产版a级片直播在线| 久久手机视直播| 亚洲性少妇| 葡萄牙性视频一二区| 制度丝袜99| 在线观看一卡二卡| 锕锕好爽 死我在线观看| 九热中文字幕| 全球成人中文在线| 欧美操逼视频二区| 男人精品区| 91人妻做a观看视频| 玖玖视频在线资源一区二区三区| 大香蕉之青青草原| 日本成人在线不卡一区二区三区| 国产真实野战在线视频| 人妻美腿丝袜制服诱惑综合天堂-| 少妇特黄一区二区三区| 内射夫妻三片| 超碰久久中文| 中国和日本人色哪个不下载能放| 中文色综合| 啊a一区在线| 碰人碰碰人人开房人肉| 国产精品久久久久久久久久梁医生| 成视频在线观看免费看| 亚洲色图欧美色图制服诱惑| 日产操逼| 天天影视网综合少妇| 丁香7月婷婷| 狠狠操夜夜| 久久曰曰| 26uuu国产亚洲综合| 久久久久久久少妇| 亚洲人妻久久| 曰韩精品九九无码| 99re这里只有| 91影视亚洲| 日韩无码视频黄色| 欧美色九九九| 老熟妇乱轮| 啊好大好舒服| 精品一区二区三区免费古装毛片香港三级日本三级人妇 | 美女天天干| 操逼操网| 久久噜噜噜精品国产亚洲综合| 欧美性爱第一区| 久久99精品国产| 亚洲伊人a线观看视频| 成人五月天色网| 午夜a成v人电影| 欧美中字二区| av网页一区二区三区| 热久久国产精品视频大陆精品| 无码不卡亚洲成?人片| 美女啊啊啊啊啊啊啊| 久久男人天堂| 天天舔九色婷婷| 午夜视频久久久久一区| 中国小夫妻勾搭露脸淫荡对白| 一本精品日本在线视频精品| 日日日骚女人精品| 亚洲精品中文字幕一区在线视频 | 免费家庭乱伦视频| 清清一区二区三区四区不卡视频| 91精品人妻一区二区三区蜜桃| 黄骗免费网站| 青青草伊人久久| 午夜视频久久久久一区| 99re在线精品78| 一级久久久久久久久久久| 208天天久久九九九| 九九99精品视频在线观看| 天天92av| 九九夜精品九九在线| 国产亚洲精品av一区| 欧洲站一级二级三级h| 97人人干| 老熟女乱伦一区| 91青青在线视频| 亚洲 91 在线| 国产操伦| 肥臀熟女一区二区三区视频| 日韩欧美亚洲国产日韩| 秋霞久久亚洲精品成人| 九九九只有精品| 亚洲天堂性爱| 黄色免费网页无码| 亚洲久久久久| 天堂涩涩| 炮色五月| 亚洲制服欧美另类内射| 国产精品乱码久久久久| 国产精品久久久久久久久久久久久久久久 | 成人国产二区三区在线,男女精品。| 五月天色图| 亞洲久久直播| 丁香婷婷五月| 日韩欧美三级| 亚洲成人妻日韩在线| 五月色网| 精品少妇人妻av久久免费| 高清视频一区| 91久久久久久久| 96AV精品| 久久 国产精品 一区| 欧美精品69性爱| 久久粉色| 欧美色图小说综合| 91麻豆天美传媒HD| 久久色人体| 日韩性爱视频免费在线| 色欲av一区二区三区蜜芽| 78精品| 国产精品一二三| 黄色高清久久无码依人| 亚洲文学偷乱拍啪啪啪啪| 精品99999久久久久久| av资源在线播放天堂| 999亚洲国产视频| 国产亚洲福利第一页丝袜| 天天射天天色成人| 福利天天都操| 91处女在线视频| 欧亚日韩三区| 樱花草社区www中国| 天美av在线观看| 天天爽夜夜操| 99综合| av天堂手机版追回| 青青伊人这里只有精品| 欧美性爱伊人| 欧美日韩香蕉| 999久久久| 天天在线91| 试看60秒| 久久久99999久网站| 图色综合网| 啊a一区在线| 夜夜嗨一区| 亚洲激情网一二三四区| 操逼日韩无码 | 日韩人人精品| 亚洲综合 欧美| 91AV天美在线视频| 色一射色一射| 91狠狠综合久久久久久| 东京热免费视频| 97色婷婷| 久久久久精| 岛国小电影| 国产精品午夜成人福利| 亚洲色图国产另类| 九一性生活免费视频| 999熟女精品| 日韩天天综合| 天天综合~91| 欧美中文字幕日韩在线| 大香蕉www.超碰| 亚洲97久久精品亚洲| 欧美黄片欧美黄片xxx| 欧亚免费视频| 殴美牲| 欧美亚洲影视| a网站免费观看| 少妇内射www在线观看视频| 国产精品久久久777| 综合网久久| 少妇色综合| 国产农村妇女毛片精品久久| 色汉综合| 97在线视频观看网站| 在线人人人人人人精品超| 91狠狠综合久久久| 人人爱夜夜爱| 久久视频,这里只有精品| 天天欧美| 女欧美一区二三区| 中国女人内射6XXXXX| 中文字幕日本久久| 久久久9品一区二区三区| 九九九影院| 狠狠躁伊人中文字幕| 一区AV| 国产精品视频白浆免费| 国产在线76页| 狠狠色一区二区中文字幕| 天天操天天干美女网址导航| 天天日天天操天天射河南省| 国产 亚洲 丝袜 制服| 色婷婷丁香五月| 精品一区二区麻豆| 97天天| 国产精品黄色三级av| 婷婷色综合| 欧美91网站| 热99re69精品8在线播放| 2020中文在线一区二区三区| 色色热| 久久久久9999精品九九九| 操人妻视频| 在线人人人人人人精品超| 国产视频一区二区在线| 97中文字幕一区| 嫩草美女久久| 欧美|91色综合| 欧美在线|亚洲| 国产中文字幕在线点播| 曰韩精品九九无码| 超碰97导航| 老司机深夜18禁污污网站| 超碰在线99| 99re在线视频国产| 99视频这有这里有精品| 大香蕉碰| 超碰69| 操逼无码操逼| 99re6久热只有精品6在线直播| 久久精品女同亚洲女同13| 亚洲无码太久| 刺激性视频黄页| 亚洲日韩美女丝袜美腿人妻视频| 大香蕉强奸乱伦| 91久久伊人婷婷青青草| 中文字幕丰满人妻日本| 丁香六月激情综合| av日韩中文字幕| 日本免费专区| 欧美日动态视频| 蜜乳AV免费观看| 欧美人妻精品| 啊啊啊啊啊好多水| 色五月婷婷麻豆在| 91精品人妻一区二区三区蜜桃| 爱我干综合| 亚洲校园激情| 欧美黄色片AAAAA| 天天性射网| 国产精品三级视频网站| 欧美综合色综合| 国产成人www免费人成看片| 欧美激情久久久久| 日本国产高清色www视频在线| 骚女高跟AV在线| 91人妻素女| 国产女主播视频在线观看| 囯产操逼片| 日1区2区3区2020| 丁香五月婷婷啪啪| 先锋女优在线观看视频| 亚洲天堂区| 亚洲情色综合| 国产一区麻豆免费观看| 嫩草美女久久| 男人成人黄色视频在线观看免费下载| 中文字幕成人理论在线| 97在线播放| www.狠狠干.coom| 成年人网站在线免费观看| 91中文精品日韩欧美在线 | 久久‘黄片视频| 日韩BBN| 亚洲色图大香| 国产精品第一区第一页| 老司机午夜福利视频一区二区| 1769一区二区| 欧美综合第一页| 久久人人爽爽爽人久久久| 乱伦a片视频| 日韩BBN| 人人妻人人操人人乐| 91黑丝美女| 日韩免费三级黄片电影| 成人片视频| 久久婷婷视频| 免费国产电影一区二区| 呦女网站| 丰满人妻-区二区三区免费| 少妇久久久| 亚洲诱惑| 婷婷色网| 亚洲图片婷婷五月天| 高精欧美色| 国产精品视频播放| 狼人久草| 成人一级性爱| 60秒不遮不挡| 欧美91网站| 婷婷四五区| 中日韩熟女| 久久只有精品| 色99久草| 色诱avtt| 伊人网av| 在线v中文字幕一区二区三区| 欧美色综合| 国产三级中文字幕粉嫩| 97大色网| 亚洲少妇色| 成人性爱高清视频免费看| 日韩欧美性爱电影在线观看| 破处bbq| 国产传媒美日韩av| 亚洲精品99| 玖玖玖玖精品国产剧情| 91一区二区三区蜜桃| 欧美色图20P| 精品中文一区二区| 97色色国产视频| 蜜臀久久久久久999| 天天看,天天做| 在线观看高清AV| 秋霞Av理论一级在线| 91综合天天| 中文字幕精品亚洲熟女| 欧美情色贴图| 老熟女熟妇| 91婷婷伊人狠人| 色五月大香蕉| 色婷婷五月综合激情中文字幕| 一级片在线观看高清无码| 精品人妻一二三| 人妻少妇精品视频一区二区三区| 二级毛片| 久久机热| 色亚州人久干视频在线观看免费版| 日韩中文字幕熟妇人妻| 欧美淫穴| 中文字幕五区| 中字乱伦AV| 日韩性爱高清免费视频| 全免费a敌肛交毛片免费| 久久久精| 天天插天天插| 国产精品岛国片在线观看| 高潮的A片激情扒开一区| 欧美色www亚洲国产阿娇要播| 国产精品9999| 午夜男人的天堂| 综合色欧美| 亚洲Av诱惑| 欧美 亚洲 在线| 日本精品一区二区不卡| 快播电影网日韩新片| 青青草导航在线视频| 日本加勒比无码专区一二三| 曰韩香蕉97| 91精品久久久久久77777| 青青草玖玖爱| 久久久天美| 国产91美女视频| 91成人无码| 精品999999| 玖玖爱在线视频免费观看| 插入逼91| 亚洲h片在线免费观看| 欧美精品99久久久**| 333kkkk·亚洲com久久| 国产激情av女片自拍| 伊人色综合网电影 | 人人超碰在线观看黄| 日本东京热大香蕉a片| jiujiujiujingpin| 97人人色| 在线综合网| 家庭乱伦国产| 不卡啪啪视频| 久久极品一区二区| 特级大荫道BBwBBwBBW| 伊人久久大香线综合无码| SUV一区二区在线看| 欧美综合色| 国产性爱强奸乱伦大全| 午夜超爽| 乱老女人一区二区视频| 花野真衣| 好吊爽好吊爽在线视频,中文字幕精品一区二区日本,国产良妇出轨视频在线观看, | 亚洲av无码国产精品字幕| 亚洲欧洲成人在线电影| 日本十八禁免费看污网站| 色婷婷九月天天综合| 天天做天天爽| 91l欧美在线| 91丝袜人妻| 亚洲欧美国产中文视频| 特级丰满少妇一级AAAA爱毛片| 五月丁香六月| 久久99精品九九久久久婷婷| 日韩欧美女求操每天更新| PMv在线观看| 国产精品久久伊人| 红桃视频高潮| 91国产丝袜白虎| 欧美日韩性爱电影在线| 国产粉嫩蜜臀av一区二区三区 | 成人无码电影在线观看网| 日韩黄色成人性爱| 国产天天看| 久久精品国产亚洲粉嫩| 青娱乐欧美激情一区二区| 久久综合五月天| 在线情色电影 91大| 欧美色宗合| 久久艹逼视频| 亚洲熟久久| 国产精品人妻无码久久久老鸭窝| 黄片无码在线制服| 亚洲国成人情色好看电影| 婷婷国产精品一区二区| 国产专区第一页| 欧美亚洲丝袜美女电影| 91色插| 一级久久性爱视频| 久久一二三四五六七八九区区| 97亚洲色图| 囯产乱伦一区二区三女| 欧美在线大香蕉| 成年人黄色视频免费| 五月婷婷色色| 精品大全99999| 强奸乱伦Av网| 嫩草伊人久久精品| 亚洲97| 91爽啪| 日骚逼视频| www.狠狠| 99re视频在线播放青草| 日本一级性爱| 一二视频神马久久传媒| 日逼视频日本| 操一区| 翔田千里无码中出中文字幕| 午夜呻吟欧美| 久久只有精品| 蜜色网色哟哟| 好色综合| av婷婷色网| 天天看精品动漫视频一区| 97舔舔| 深夜福利黄片| 800zy一区二区| 精品国产Av无码久久久亚洲| 欧洲综合视频| 精品无码欧美三级| 嗯嗯啊啊用力视频免费| 五月丁香黄色网| 亚洲人在线成线成人| 亚洲一区日韩精品中文字幕| 乱日视频| 正在播放国产精品一区| 99久热精品99re6热| 色色香蕉| 91狠狠狠| 成人资源中文字幕在线观看天天| 欧美成人精品欧美一级乱黄一区二…| 色婷婷久久| 欧美超碰在线| 91麻豆天美国产| 欧美日韩亚洲一区二区在线观看| 免费超碰97久久| 日韩中文字幕视频在线观看| 夜夜春夜夜操| 大胆91| 欧美熟妇成人一区二区| baiduhicn.com。| 91精品啪在线观看国产城中村| 成人怡红院| 精品国产72| 中文字幕aⅴ在线视频| 伊人网在线点播| 丰满人妻一区二区三区四| 超碰97人妻免费在线| 乱子伦一区二区三区国产精品| 日韩不卡av一二三| 91一区二匹| 少妇内射www在线观看视频| 26uuu国产免费观看| 2017天天拍大香蕉| 日本不卡二三区| 91精品丝袜在线观看| 日韩大香蕉| 成熟熟女国产精品一区二区| 午夜男人一级A片7777| 免费操逼91| 亚洲欧美综合网站| 亚洲91少妇| 黄色在线网站| 麻豆视频一区二区| 人妻熟女一区二区三区在线| 国产吞精a级片激情电影| 久久久96| 国产热av| 蜜桃久久久久久久| 粉嫩绯色AV一区二区在线| 精品久| 久久是精品| 天天影视激情欧美| 人人操人人狠狠操| 在线无码操| 国产精品久久久吖| 噜噜噜噜天天狠狠| 人人超碰在线观看黄| 五月天婷婷综合| 亚欧视频在线| 人人操人人摸人人骑| A级国产欧美激情在线| 一中国女人毛片水真多| 67914在线兔费成人视频| 中文字幕在线观看AV| 亚洲啪啪性视频| 6080YYY午夜理论片在线观看| 啊啊啊爽爽| 视频在线97| 亚洲激情天堂网| 欧美激情总合网| 婷婷丁香五月激情啪啪| 亚洲第一免费视频| 免费a v| 60秒不遮不挡| 欧洲站一级二级三级h| 熟女一区二区三区| 不卡人妻少妇精品毛片一区23区视频| 国产伦精品一区二区三区在线观| 免费一级a毛片久久久久久鸭绿欲| 国产一区在线播放| 亚洲少妇视频| 精品无码一区二区三区| 噜噜噜亚洲精品| 97色诱| 九九九九九九亚洲| 亚洲 综合 欧美| 色婷婷综合网| 国产67194| 精品国产肉丝袜在线拍国语| 少妇人妻在线| www激情| 国产理论视频在线播放| 欧州一区二区三区四区| 凌辱美少妇久久aV| 欲综合网| 亚洲精品九九九九九九| 黑人粗大V S日韩女优视频| 超碰综合色| 啊啊啊不要啊啊受不了了视频在线 | 91人妻Pr| 超碰人人超在线观看| 51一区二区三区| 青娱乐国产精品| 亚洲高清国产理伦片| 在线欧美69V免费观看视频| 中文字幕乱码人妻二区三区| 国产乱伦性爱区| 日韩性爱毛片操骚逼| 久久五十路熟女人妻| 亚洲欧洲综合av在线| 天天看天天在线精品| 久草网站免费在线观看| 九九久久一区二区伦理| 黑人无码一区二区| 亚洲无码久久久久久久| 国产一区二区三区影片| 色九九综合| 偷窥自拍亚洲色图| 超碰天天久久79| 国产精品久久久久久久久久久久久久久久 |