Issue
I have written small program and would like to use underline format rather than selected text which is provided by QplainTextEdit
- it work well, when i click mouse left click
- But when i Use shift+left click, qplaintextedit select complete text and underline format gone.
- I am trying to use only underline format and do not select text.
Expected behavior for shift+left click
#!/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())
Solution
If you send the event to the QPlainTextEdit then you can get the position and anchor of the selection and move them to cover the whole line.
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)
Note that you could instead subclass QPlainTextEdit and reimplement 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)
Answered By - alec
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.