You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QPlainTextEdit如何禁用Shift+左键选中文本仅保留自定义下划线格式

解决PySide2 QPlainTextEdit自定义行下划线与Shift点击冲突问题

核心问题点

  • 事件过滤器处理完鼠标点击逻辑后未拦截事件,默认事件继续传播触发了QPlainTextEdit自带的文本选中效果
  • 原change_summary_block_format方法仅重置了全文档格式,未给目标区间的行应用下划线样式
  • Shift点击的行存储逻辑不合理,多次点击会导致区间计算异常

修改后可直接运行的代码

#!/usr/bin/python3.6
from PySide2.QtCore import Qt, QEvent
from PySide2.QtWidgets import QApplication
from PySide2.QtGui import (QTextCharFormat, QBrush, QColor, QTextCursor)
from PySide2.QtWidgets import (QPlainTextEdit, QMainWindow, QVBoxLayout, QWidget)
import sys


class Window(QMainWindow):
    def __init__(self, app):
        super().__init__()
        # 存储点击的起始行光标
        self.start_cursor = None

    def create_widget(self):
        self.plain_textedit = QPlainTextEdit()
        self.plain_textedit.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.plain_textedit.setStyleSheet(
            """QPlainTextEdit {font-size: 14pt;
                               font-family: Courier;}""")
        self.plain_textedit.setMouseTracking(True)
        # 存储默认文本格式,用于重置样式
        self.default_char_format = self.plain_textedit.currentCharFormat()
        self.plain_textedit.setCursorWidth(5)
        self.plain_textedit.viewport().installEventFilter(self)
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.plain_textedit)
        self.window = QWidget()
        self.window.setLayout(main_layout)
        self.setCentralWidget(self.window)

    def eventFilter(self, obj, event):
        if obj is self.plain_textedit.viewport() and event.type() == QEvent.MouseButtonPress:
            if event.button() == Qt.LeftButton:
                # 获取点击位置对应的行光标
                text_cursor = self.plain_textedit.cursorForPosition(event.pos())
                modifiers = QApplication.keyboardModifiers()
                # 普通左键点击:记录起始行,仅给当前行加下划线
                if modifiers != Qt.ShiftModifier:
                    self.start_cursor = text_cursor
                    # 先重置全文档格式
                    self.reset_all_format()
                    # 给当前行加下划线
                    self.add_line_underline(text_cursor)
                # Shift+左键点击:计算区间,给范围内所有行加下划线
                else:
                    if self.start_cursor is None:
                        # 首次点击就按Shift的话直接把当前行设为起始行
                        self.start_cursor = text_cursor
                    self.reset_all_format()
                    start_line = self.start_cursor.blockNumber()
                    end_line = text_cursor.blockNumber()
                    # 统一区间顺序
                    if start_line > end_line:
                        start_line, end_line = end_line, start_line
                    # 遍历区间所有行加下划线
                    for line_num in range(start_line, end_line + 1):
                        block = self.plain_textedit.document().findBlockByLineNumber(line_num)
                        line_cursor = QTextCursor(block)
                        self.add_line_underline(line_cursor)
                # 拦截事件,不让默认处理逻辑触发文本选中
                return True
        return super().eventFilter(obj, event)

    def reset_all_format(self):
        """重置全文档为默认格式"""
        cursor = self.plain_textedit.textCursor()
        cursor.select(QTextCursor.Document)
        cursor.setCharFormat(self.default_char_format)
        cursor.clearSelection()
        self.plain_textedit.setTextCursor(cursor)

    def add_line_underline(self, cursor):
        """给指定光标所在行添加蓝色下划线"""
        cursor.select(QTextCursor.LineUnderCursor)
        format = QTextCharFormat()
        format.setForeground(QBrush(QColor("blue")))
        format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
        cursor.mergeCharFormat(format)


def main():
    app = QApplication([])
    window = Window(app)
    window.create_widget()
    window.show()
    app.exec_()


if __name__ == "__main__":
    sys.exit(main())

关键修改说明

  • 事件过滤器处理完鼠标点击逻辑后返回True,拦截事件传播,彻底屏蔽默认的文本选中行为
  • 优化了行区间计算逻辑,支持正选反选(Shift点击行在起始行上方也能正常计算区间)
  • 拆分了重置格式、添加下划线的独立方法,逻辑更清晰
  • 移除了冗余的import导入,减少不必要的资源占用

内容的提问来源于stack exchange,提问作者user765443

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 06:45:03