使用自定义格式并且不要在 qplaintextedit 中选择完整的文本
Posted
技术标签:
【中文标题】使用自定义格式并且不要在 qplaintextedit 中选择完整的文本【英文标题】:use custom format and do not select complete text in qplaintextedit 【发布时间】:2021-12-27 06:29:21 【问题描述】:我写了一个小程序,我想使用下划线格式而不是 QplainTextEdit 提供的选定文本
-
效果很好,当我点击鼠标左键时
但是当我使用 shift+left click 时,qplaintextedit 选择完整的文本和下划线格式消失了。
我正在尝试仅使用下划线格式而不选择文本。
shift+左键的预期行为
#!/usr/bin/python3.6
from PySide2.QtCore import Qt, QEvent
from PySide2.QtWidgets import QApplication
from PySide2.QtGui import (QTextCharFormat, QIcon, QKeySequence,
QBrush, QColor, QTextDocument, QFont,
QTextCursor, QTextBlockFormat, QFontDatabase)
from PySide2.QtWidgets import (QPlainTextEdit, QSizePolicy, QApplication, QLabel, QGridLayout, QMessageBox, QToolBar, QTextEdit, QCheckBox, QAction,
QTableWidget, QTableWidgetItem, QHeaderView, QMenu,
QWidget)
from PySide2.QtCore import Qt, QSize, QRegExp, QFile, QTextStream, QRect
from PySide2.QtWidgets import (QMainWindow, QVBoxLayout,
QPlainTextEdit, QGridLayout, QGroupBox,
QListWidget, QHBoxLayout, QLabel, QLineEdit,
QMenuBar, QPushButton, QMessageBox, QDialog,
QTextEdit, QVBoxLayout, QWidget, QFormLayout,
QCheckBox, QDialogButtonBox,
QTableWidget, QTableWidgetItem, QHeaderView)
import sys
class Window(QMainWindow):
def __init__(self, app):
super().__init__()
self.shift_left_click_cursor = []
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.plain_textedit_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:
#Reseting format for single click when user use shift+click select data
if event.button() == Qt.LeftButton:
text_cursor = self.plain_textedit.cursorForPosition(event.pos())
text_cursor.select(QTextCursor.LineUnderCursor)
format = QTextCharFormat()
format.setForeground(QBrush(QColor("blue")))
format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
text_cursor.mergeCharFormat(format)
modifiers = QApplication.keyboardModifiers()
if modifiers == Qt.ShiftModifier:
self.shift_left_click_cursor.append(text_cursor)
self.change_summary_block_format()
def change_summary_block_format(self):
start_line = self.shift_left_click_cursor[0].blockNumber()
end_line = self.shift_left_click_cursor[-1].blockNumber()
index = 0
plain_textcursor = self.plain_textedit.textCursor()
plain_textcursor.select(QTextCursor.Document)
plain_textcursor.setCharFormat(self.plain_textedit_format)
plain_textcursor.clearSelection()
for line in range(start_line, end_line + 1):
text_data = self.plain_textedit.document().findBlockByLineNumber(line)
print(text_data.text())
text_cursor = QTextCursor(text_data)
# self.plaintext_cursor_multiselection(text_data)
print(text_data)
def main():
app = QApplication([])
window = Window(app)
window.create_widget()
window.show()
app.exec_()
if __name__ == "__main__":
sys.exit(main())
【问题讨论】:
【参考方案1】:如果您将事件发送到 QPlainTextEdit,那么您可以获得选择的位置和锚点并将它们移动以覆盖整行。
class Window(QMainWindow):
def __init__(self, app):
super().__init__()
self.shift_left_click_cursor = []
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.plain_textedit_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:
#Reseting format for single click when user use shift+click select data
if event.button() == Qt.LeftButton and event.modifiers() & Qt.ShiftModifier:
self.plain_textedit.mousePressEvent(event)
text_cursor = self.plain_textedit.textCursor()
positions = (text_cursor.anchor(), text_cursor.position())
text_cursor.setPosition(min(positions))
text_cursor.movePosition(QTextCursor.StartOfLine)
text_cursor.setPosition(max(positions), QTextCursor.KeepAnchor)
text_cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
format = QTextCharFormat()
format.setForeground(QBrush(QColor("blue")))
format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
text_cursor.mergeCharFormat(format)
text_cursor.clearSelection()
text_cursor.setPosition(positions[1])
self.plain_textedit.setTextCursor(text_cursor)
return True
return super().eventFilter(obj, event)
请注意,您可以改为继承 QPlainTextEdit 并重新实现 mousePressEvent
。
class PlainTextEdit(QPlainTextEdit):
def mousePressEvent(self, event):
super().mousePressEvent(event)
if event.button() == Qt.LeftButton and event.modifiers() & Qt.ShiftModifier:
text_cursor = self.textCursor()
positions = (text_cursor.anchor(), text_cursor.position())
text_cursor.setPosition(min(positions))
text_cursor.movePosition(QTextCursor.StartOfLine)
text_cursor.setPosition(max(positions), QTextCursor.KeepAnchor)
text_cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
format = QTextCharFormat()
format.setForeground(QBrush(QColor("blue")))
format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
text_cursor.mergeCharFormat(format)
text_cursor.clearSelection()
text_cursor.setPosition(positions[1])
self.setTextCursor(text_cursor)
【讨论】:
以上是关于使用自定义格式并且不要在 qplaintextedit 中选择完整的文本的主要内容,如果未能解决你的问题,请参考以下文章
如何在本地用phpstudy调试多个网站 并且通过自定义域名访问
如何自定义 git rebase --interactive 提交消息的格式?