How to display custom python QTextEdit effects like underline in txt or rtf format?
<p>I'm having a problem where when I save the text from QTextEdit as a txt, or rtf, it doesnt save things like underline and font size. Here's the code:</p>

<pre><code># -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

import gi
import signal
gi.require_version('Gtk', '3.0')
import sys
import dbus
import pygtk
import gi
import signal
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import pyqtSlot
from PyQt4.QtCore import QUrl
from PyQt4.QtWebKit import QWebView

import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)

gi.require_version('Notify', '0.7')


try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(679, 600)

        self.underlined = False
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))

        self.saveButton = QtGui.QPushButton(self.centralwidget)
        self.saveButton.setGeometry(QtCore.QRect(10, 0, 88, 28))
        self.saveButton.setObjectName(_fromUtf8("pushButton"))

        self.textEdit = QtGui.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(0, 30, 681, 800))
        self.textEdit.setObjectName(_fromUtf8("textEdit"))

        self.fontButton = QtGui.QPushButton(self.centralwidget)
        self.fontButton.setGeometry(QtCore.QRect(400, 0, 88, 28))
        self.fontButton.setObjectName(_fromUtf8("fontButton"))

        self.fontSize = QtGui.QLineEdit(self.centralwidget)
        self.fontSize.setGeometry(QtCore.QRect(100, 0, 28, 28))
        self.fontSize.setObjectName(_fromUtf8("fontEdit"))
        self.fontSize.returnPressed.connect(self.fontButton.click)

        self.underlineButton = QtGui.QPushButton(self.centralwidget)
        self.underlineButton.setGeometry(QtCore.QRect(130, 0, 28, 28))
        self.underlineButton.setObjectName(_fromUtf8("underlineButton"))

        self.disableUnderlineButton = QtGui.QPushButton(self.centralwidget)
        self.disableUnderlineButton.setGeometry(QtCore.QRect(160, 0, 28, 28))
        self.disableUnderlineButton.setObjectName(_fromUtf8("disableUnderlineButton"))


        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 679, 24))
        self.menubar.setObjectName(_fromUtf8("menubar"))

        self.menuTest = QtGui.QMenu(self.menubar)
        self.menuTest.setObjectName(_fromUtf8("menuTest"))
        MainWindow.setMenuBar(self.menubar)

        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuTest.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        def save(self):
            with open('log.rtf', 'w') as yourFile:
                yourFile.write(str(self.textEdit.toPlainText()))

        def saveFont(self):
            self.textEdit.setFontPointSize(int(self.fontSize.text()))

        def underline(self):
            self.textEdit.setFontUnderline(True)

        def disableUnderline(self):
            self.textEdit.setFontUnderline(False)

        def commander(self):
            save(self)
        self.textEdit.setHtml('&lt;u&gt;hi&lt;/u&gt;')
        self.saveButton.clicked.connect(lambda: save(self))
        self.fontButton.clicked.connect(lambda: saveFont(self))
        self.underlineButton.clicked.connect(lambda: underline(self))
        self.disableUnderlineButton.clicked.connect(lambda: disableUnderline(self))




    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.saveButton.setText(_translate("MainWindow", "Save text", None))
        self.fontButton.setText(_translate("MainWindow", "Save Font", None))
        self.menuTest.setTitle(_translate("MainWindow", "test", None))
        self.underlineButton.setText(_translate("MainWindow", "Uon", None))
        self.disableUnderlineButton.setText(_translate("MainWindow", "Uoff", None))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
</code></pre>

<p>I've attempted to fix this with HTML, and other formats but couldn't get it to work. </p>

<p>It's because you're converting the text to <em>plain text</em> with <code>toPlainText</code>, which doesn't contain any formatting information.</p>

<pre><code>yourFile.write(str(self.textEdit.toPlainText()))
</code></pre>

<p>If you want to maintain the formatting, you need to use <code>toHtml</code>.  </p>

<pre><code>yourFile.write(str(self.textEdit.toHtml()))
</code></pre>

<p>Be aware that this isn't the same thing as <code>rtf</code>.  It's not even entirely standard HTML and it will likely display a bit differently if you try to look at it in another HTML viewer besides the <code>QTextEdit</code>.  In my experience, the HTML generated from the <code>QTextEdit</code>'s is pretty ugly, and only really works well if you plan on only displaying it inside <code>QTextEdits</code>.</p>

python pyqt pyqt4