Results 1 to 4 of 4

Thread: Apply the outline of a QTextCharFormat only on the outside of the text

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Apr 2021
    Posts
    4
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Apply the outline of a QTextCharFormat only on the outside of the text

    Unfortunately I think my second edit can not work, I have mistaken print() and paint() functions. QTextDocument has no such paint().
    Last edited by Sylve; 5th April 2021 at 13:18.

  2. #2
    Join Date
    Apr 2021
    Posts
    4
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Apply the outline of a QTextCharFormat only on the outside of the text

    I post my solution (in the end heavily based on the Stackoverflow one), just in case it helps anybody. Note I used Qt 6 intead of 5, but it should not matter.

    Qt Code:
    1. from PyQt6.QtWidgets import *
    2. import sys
    3. from PyQt6 import QtGui
    4. from PyQt6.QtCore import Qt
    5. from PyQt6.QtGui import QTextDocument, QTextCursor
    6. from PyQt6.QtGui import QColor, QPainter, QPainterPath, QBrush, QPen, QPalette, QFont
    7.  
    8. class MyTextDocument(QTextDocument):
    9. def __init__(self, parent, font):
    10. super().__init__()
    11.  
    12. self.parent = parent
    13.  
    14. self.setDefaultFont(font)
    15.  
    16. def drawContents(self, painter):
    17.  
    18. super().drawContents(painter)
    19.  
    20. my_cursor = self.parent.textCursor()
    21. my_char_format = my_cursor.charFormat()
    22.  
    23. my_char_format.setTextOutline(QPen(Qt.GlobalColor.red, 5))
    24. my_cursor.select(QTextCursor.SelectionType.Document)
    25. my_cursor.mergeCharFormat(my_char_format)
    26.  
    27. super().drawContents(painter)
    28.  
    29. my_char_format.setTextOutline(QPen(Qt.GlobalColor.transparent))
    30. my_cursor.mergeCharFormat(my_char_format)
    31.  
    32. super().drawContents(painter)
    33.  
    34.  
    35. class MyTextEdit(QTextEdit):
    36. def __init__(self):
    37. super().__init__()
    38.  
    39. font = self.currentFont()
    40. font.setPointSize(80)
    41. font.setStyleStrategy(QFont.StyleStrategy.PreferAntialias)
    42.  
    43. self.setDocument(MyTextDocument(self, font))
    44.  
    45. self.setText("Does it work?")
    46. self.resize(800, 400)
    47.  
    48. def paintEvent(self, event):
    49. painter = QPainter(self.viewport())
    50.  
    51. super(MyTextEdit, self).paintEvent(event)
    52.  
    53. self.document().drawContents(painter)
    54.  
    55.  
    56. if __name__ == '__main__':
    57. app = QApplication(sys.argv)
    58.  
    59. win = MyTextEdit()
    60. win.show()
    61.  
    62. app.exec_()
    To copy to clipboard, switch view to plain text mode 

    Result:



    Feel free to post if you have something better in mind / any comment!

  3. #3
    Join Date
    Apr 2021
    Posts
    4
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Apply the outline of a QTextCharFormat only on the outside of the text

    I found a very concerning issue with this solution: the line

    Qt Code:
    1. my_cursor.select(QTextCursor.SelectionType.Document)
    To copy to clipboard, switch view to plain text mode 

    calls recursively paintEvent in a infinite loop. I should find a way to disable recursive calls in paintEvent...

    Try out this code to see the issue:

    Qt Code:
    1. from PyQt5.QtWidgets import *
    2. import sys
    3. from PyQt5.QtCore import Qt
    4. from PyQt5.QtGui import QTextDocument, QTextCursor
    5. from PyQt5.QtGui import QPainter, QPen, QFont
    6.  
    7. style_subs = '''
    8. /* looks of subtitles */
    9. QFrame {
    10. background: green;
    11. color: white;
    12. font-family: "Noto Serif CJK JP Light";
    13. border: 0;
    14. }
    15. '''
    16.  
    17. class MyTextEdit(QTextEdit):
    18. def __init__(self):
    19. super().__init__()
    20.  
    21. self.setStyleSheet(style_subs)
    22.  
    23. font = self.currentFont()
    24. font.setPointSize(80)
    25. font.setStyleStrategy(QFont.PreferAntialias)
    26. self.setFont(font)
    27.  
    28. self.setText("Does it work?")
    29.  
    30. self.resize(800, 400)
    31.  
    32. self.n = 0
    33.  
    34. def paintEvent(self, event):
    35. print("painting", self.n, "...")
    36. self.n += 1
    37. painter = QPainter(self.viewport())
    38.  
    39. my_cursor = self.textCursor()
    40. my_char_format = my_cursor.charFormat()
    41.  
    42. my_char_format.setTextOutline(QPen(Qt.red, 10))
    43. my_cursor.select(QTextCursor.SelectionType.Document)
    44. my_cursor.mergeCharFormat(my_char_format)
    45.  
    46. self.document().drawContents(painter)
    47.  
    48. my_char_format.setTextOutline(QPen(Qt.transparent))
    49. my_cursor.mergeCharFormat(my_char_format)
    50.  
    51.  
    52. super(MyTextEdit, self).paintEvent(event)
    53.  
    54.  
    55. if __name__ == '__main__':
    56. app = QApplication(sys.argv)
    57.  
    58. win = MyTextEdit()
    59. win.show()
    60.  
    61. app.exec_()
    To copy to clipboard, switch view to plain text mode 
    Last edited by Sylve; 5th April 2021 at 18:35.

Similar Threads

  1. QTextCharFormat question
    By moez in forum KDE Forum
    Replies: 1
    Last Post: 1st February 2012, 09:14
  2. Replies: 4
    Last Post: 5th August 2011, 20:04
  3. QPushButton: Outline white text in black on transparent background
    By Tito in forum Qt for Embedded and Mobile
    Replies: 3
    Last Post: 20th July 2011, 07:16
  4. QTextCharFormat and Hyperlinks
    By Rayven in forum Qt Programming
    Replies: 0
    Last Post: 8th January 2010, 21:12
  5. Replies: 1
    Last Post: 27th November 2007, 10:10

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.