There are three QGraphicsView in one line. If these QGraphicsView is vertically located (orientation is 0), to select texts with mouse is no problem. But if these QGrahpicsView is horizontally located, goes bad.Even if horizontally located, I must select texts vertically.
It seems that the mouse point at the time of mouse press event is decided by QTextEdit coordinate at first. At the time of mouse move event, the mouse point is decided by the position of mouse press event as the anchor. So is the time of mouse release event.
Is there way to select texts with mouse naturally? Or does Qt allow us to select texts with mouse vertically only?
from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsProxyWidget, QTextEdit
from PySide6.QtGui import QTextDocument, QPageSize, QPainter, QBrush, QTextCharFormat, QTextOption
from PySide6.QtCore import Qt, Signal, QRect, QRectF, QEvent, QSize, QSizeF, QPointF
class MainGraphicsView(QGraphicsView):
def __init__(self, parent=None):
super(MainGraphicsView, self).__init__(parent)
self._mainscene = MainGraphicsScene(1)
self._mainscene._mainview = self
self.setScene(self._mainscene)
class MainGraphicsScene(QGraphicsScene):
def __init__(self, orientation = 1, parent=None):
super(MainGraphicsScene, self).__init__(parent)
if orientation == 0:
self.rootView = TextGraphicsView()
self.rootView.main_scene = self
self.root_proxywidget = self.addWidget(self.rootView)
self.rootView.setSceneRect(0, 0, self.document()._pageWidth, self.document()._pageHeight)
self.secondaryView = SecondaryTextGraphicsView(2, self.rootView.scene())
self.secondaryView.setSceneRect(0, self.document()._pageHeight, self.document()._pageWidth, self.document()._pageHeight)
self.secondary_proxywidget = self.addWidget(self.secondaryView)
self.secondary_proxywidget.setPos(0, self.document()._pageHeight)
self.thirdView = SecondaryTextGraphicsView(3, self.rootView.scene())
self.thirdView.setSceneRect(0, self.document()._pageHeight*2, self.document()._pageWidth, self.document()._pageHeight)
self.third_proxywidget = self.addWidget(self.thirdView)
self.third_proxywidget.setPos(0, self.document()._pageHeight*2)
if orientation == 1:
self.rootView = TextGraphicsView()
self.rootView.main_scene = self
self.root_proxywidget = self.addWidget(self.rootView)
self.rootView.setSceneRect(0, 0, self.document()._pageWidth, self.document()._pageHeight)
self.secondaryView = SecondaryTextGraphicsView(2, self.rootView.scene())
self.secondaryView.setSceneRect(0, self.document()._pageHeight, self.document()._pageWidth, self.document()._pageHeight)
self.secondary_proxywidget = self.addWidget(self.secondaryView)
self.secondary_proxywidget.setPos(self.document()._pageWidth, 0)
self.thirdView = SecondaryTextGraphicsView(3, self.rootView.scene())
self.thirdView.setSceneRect(0, self.document()._pageHeight*2, self.document()._pageWidth, self.document()._pageHeight)
self.third_proxywidget = self.addWidget(self.thirdView)
self.third_proxywidget.setPos(self.document()._pageWidth*2, 0)
self.setBackgroundBrush(QBrush(Qt.gray))
def view(self):
return self._mainview
def textedit(self):
return self.document().parent()
def document(self):
return self.rootView.document()
class TextGraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.page = 1
self.initScene()
def mousePressEvent(self, event):
SecondaryTextGraphicsView.selectedPage = self.page
return QGraphicsView.mousePressEvent(self, event)
def initScene(self):
self.common_scene = TextGraphicsScene()
self.common_scene.root_view = self
self.setScene(self.common_scene)
self.setSceneRect(0, self.document()._pageHeight*(self.page -1), self.document()._pageWidth, self.document()._pageHeight)
self.resize(int(self.document()._pageWidth), int(self.document()._pageHeight))
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
def view(self):
return self.main_scene._mainview
def textedit(self):
return self.common_scene.textedit
def document(self):
return self.common_scene.textedit.document()
class SecondaryTextGraphicsView(QGraphicsView):
def __init__(self, page, scene, parent=None):
super().__init__(scene, parent)
self.page = page
self.initScene()
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
def initScene(self):
self.setSceneRect(0, self.document()._pageHeight*(self.page-1), self.document()._pageWidth, self.document()._pageHeight)
self.resize(int(self.document()._pageWidth), int(self.document()._pageHeight))
def view(self):
return self.scene().root_view.view()
def textedit(self):
return self.scene().textedit()
def document(self):
return self.scene().textedit.document()
class TextGraphicsScene(QGraphicsScene):
def __init__(self, parent=None):
super().__init__(parent)
self.textedit = TextEdit(scene=self)
self.addWidget(self.textedit)
def view(self):
return self.root_view
def document(self):
return self.textedit.document()
class TextEdit(QTextEdit):
def __init__(self, scene, parent=None):
super().__init__(parent)
self.setAttribute(Qt.WA_InputMethodEnabled, True)
self.setMouseTracking(False)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scene = scene
self.setDocument(TextDocument(parent=self))
self.setWordWrapMode(QTextOption.WrapAtWordBoundaryOrAnywhere)
self.setLineWrapMode(self.LineWrapMode.FixedPixelWidth)
self.setLineWrapColumnOrWidth(self.document()._pageWidth)
self.setAttribute(Qt.WA_InputMethodEnabled, True)
self.setInputMethodHints(Qt.ImhMultiLine)
self.resize(self.document()._pageSize.toSize().width(), self.document()._pageSize.toSize().height()*3)
self.setPlainText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
\Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
def mouseMoveEvent(self, event):
print(event.position())
return QTextEdit.mouseMoveEvent(self, event)
def view(self):
return self.scene.root_view
def pageSize(self):
return self.document()._pageSize
class TextDocument(QTextDocument):
def __init__(self, parent=None):
super().__init__(parent)
self._pageSize = QPageSize.size(QPageSize.A4, QPageSize.Point)
self._pageHeight = self._pageSize.height()
self._pageWidth = self._pageSize.width()
self.setDocumentMargin(30.5)
def main():
import sys
app = QApplication([]) if QApplication.instance() is None else QApplication.instance()
m = MainGraphicsView()
m.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
from your comment:
if I use QGraphicsView and shows the each page, I don't have to calculate the position of QTextLines when the document is horizontally layouted. QGraphicsView can show each page horizontally, but in actual QTextEdit is all vertically layouted. That is why it is very simple.
You need not to draw the lines on the basis of QTextLayout
.
QTextLine
also has draw method.
Please use QTextLine
instead of QTextLayout
.