PyQt6 QTextEdit bug

Phil Thompson phil at riverbankcomputing.com
Wed May 31 08:45:35 BST 2023


On 31/05/2023 01:07, Michael Rosenberg wrote:
> Windows 11 / Python 3.11 / PyQt 6.5.0
> 
> I believe I've discovered a bug in the QTextEdit of PyQT6, specifically 
> how
> it exports the current text via toHTML() or toMarkdown() depending on 
> how
> text is added to the QTextEdit. Here is some sample code, as simplified 
> as
> I could manage it.
> 
> First, let's look at some code that works as expected:
> 
> from PyQt6.QtWidgets import QApplication, QWidget, QTextEdit, 
> QVBoxLayout
> 
> import sys
> 
> app = QApplication(sys.argv)
> 
> window = QWidget()
> layout = QVBoxLayout()
> window.setLayout(layout)
> text_edit = QTextEdit()
> layout.addWidget(text_edit)
> 
> text_edit.append("<h1>Main Header</h1><h2>Secondary Header</h2><p>Test
> paragraph.</p>")
> 
> print(text_edit.toHtml())
> print()
> print(text_edit.toMarkdown())
> window.show()
> 
> app.exec()
> 
> Two things to note of this code when executed. First, the appearance of 
> the
> text displayed in the QTextEdit is correct and second, the printed html 
> and
> markdown are correct, namely:
> 
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "
> http://www.w3.org/TR/REC-html40/strict.dtd">
> <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8"
> /><style type="text/css">
> p, li { white-space: pre-wrap; }
> hr { height: 1px; border-width: 0; }
> li.unchecked::marker { content: "\2610"; }
> li.checked::marker { content: "\2612"; }
> </style></head><body style=" font-family:'Segoe UI'; font-size:9pt;
> font-weight:400; font-style:normal;">
> <h1 style=" margin-top:18px; margin-bottom:12px; margin-left:0px;
> margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style="
> font-size:xx-large; font-weight:700;">Main Header</span></h1>
> <h2 style=" margin-top:16px; margin-bottom:12px; margin-left:0px;
> margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style="
> font-size:x-large; font-weight:700;">Secondary Header</span></h2>
> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px;
> margin-right:0px; -qt-block-indent:0; text-indent:0px;">Test
> paragraph.</p></body></html>
> 
> # Main Header
> 
> ## Secondary Header
> 
> Test paragraph.
> 
> Now, let's make a minor modification to the above code. Instead of 
> adding
> the entire desired HTML text to the QTextEdit all at once, let's append
> each line one after the other:
> 
> from PyQt6.QtWidgets import QApplication, QWidget, QTextEdit, 
> QVBoxLayout
> 
> import sys
> 
> app = QApplication(sys.argv)
> 
> window = QWidget()
> layout = QVBoxLayout()
> window.setLayout(layout)
> text_edit = QTextEdit()
> layout.addWidget(text_edit)
> 
> text_edit.append("<h1>Main Header</h1>")
> text_edit.append("<h2>Secondary Header</h2>")
> text_edit.append("<p>Test paragraph.</p>")
> 
> print(text_edit.toHtml())
> print(text_edit.toMarkdown())
> window.show()
> 
> app.exec()
> 
> The appearance of the text in the QTextEdit window is exactly the same 
> as
> previously, but in the HTML and Markdown output, every line has been
> converted to a first level header:
> 
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "
> http://www.w3.org/TR/REC-html40/strict.dtd">
> <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8"
> /><style type="text/css">
> p, li { white-space: pre-wrap; }
> hr { height: 1px; border-width: 0; }
> li.unchecked::marker { content: "\2610"; }
> li.checked::marker { content: "\2612"; }
> </style></head><body style=" font-family:'Segoe UI'; font-size:9pt;
> font-weight:400; font-style:normal;">
> <h1 style=" margin-top:18px; margin-bottom:12px; margin-left:0px;
> margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style="
> font-size:xx-large; font-weight:700;">Main Header</span></h1>
> <h1 style=" margin-top:18px; margin-bottom:12px; margin-left:0px;
> margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style="
> font-size:x-large; font-weight:700;">Secondary Header</span></h1>
> <h1 style=" margin-top:18px; margin-bottom:12px; margin-left:0px;
> margin-right:0px; -qt-block-indent:0; text-indent:0px;">Test
> paragraph.</h1></body></html>
> 
> # Main Header
> 
> # Secondary Header
> 
> # Test paragraph.
> 
> I'm pretty sure this behavior is wrong, particularly as the visual 
> output
> in the GUI is identical in both cases (i.e., displaying the text 
> correctly
> as a level 1 header, level 2 header, and general text paragraph). I 
> suppose
> this could be a Qt6 bug and not PyQt6, but I don't use C so cannot 
> directly
> test whether this behavior is unique to PyQt or general to Qt.

As PyQt doesn't do anything special with QTextEdit it is likely to be a 
Qt bug.

Phil


More information about the PyQt mailing list