I think that this issue has to do with a by-design decision (that I believe is somehow wrong), but I prefer to ask here before submitting a possible bug report.
I have a QTextEdit that inherits the parent window's palette for its default font colors, and that palette might change on the run if the user wants to change the colors of that text edit window.
While this works fine for standard text, there is a problem with the QPalette.Link
colors: as soon as I change the palette Text
property, the unformatted text is correctly updated, but if I change the Link
property the result doesn't work as expected.
from PyQt5 import QtWidgets
class Test(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
layout = QtWidgets.QGridLayout(self)
paletteBtn = QtWidgets.QPushButton('Set palette')
paletteBtn.clicked.connect(self.selectPalette)
palette = self.palette()
palette.setColor(palette.Link, palette.color(palette.Text))
QtWidgets.QApplication.setPalette(palette)
self.textEdits = []
self.baseEdit = QtWidgets.QTextEdit()
layout.addWidget(self.baseEdit, 1, 0)
self.preTextEdit = QtWidgets.QTextEdit()
layout.addWidget(self.preTextEdit, 1, 1)
self.paletteTextEdit = QtWidgets.QTextEdit()
layout.addWidget(self.paletteTextEdit, 1, 2)
self.staticTextEdit = QtWidgets.QTextEdit()
layout.addWidget(self.staticTextEdit, 1, 3)
for textEditName in ('baseEdit', 'preTextEdit', 'paletteTextEdit', 'staticTextEdit'):
textEdit = getattr(self, textEditName)
self.textEdits.append(textEdit)
textEdit.setHtml('''
<html>
<body>
<b>{}</b><br/>
simple text<br/>
<a href="link">unformatted link!</a>
</body>
</html>
'''.format(textEditName))
self.preTextEdit.document().setDefaultStyleSheet('a {color: green;}')
layout.addWidget(paletteBtn, 0, 0, 1, layout.columnCount())
def selectPalette(self):
palette = self.palette()
new = QtWidgets.QColorDialog.getColor(palette.color(palette.Text), self)
palette.setColor(palette.Text, new)
palette.setColor(palette.Link, new)
for textEdit in self.textEdits:
if textEdit == self.paletteTextEdit:
self.paletteTextEdit.document().setDefaultStyleSheet('a {color: palette(text);')
elif textEdit == self.staticTextEdit:
self.staticTextEdit.document().setDefaultStyleSheet('a {{color: rgb{};}}'.format(
palette.text().color().getRgb()))
textEdit.setPalette(palette)
cursor = textEdit.textCursor()
cursor.movePosition(cursor.End)
textEdit.setTextCursor(cursor)
textEdit.insertHtml('<br/><a href="link">another link!</a>')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
test = Test()
test.show()
sys.exit(app.exec_())
In the following image you can see the starting point applied to the four different approaches. The palette (applied to the application) is consistent.
If I choose a different color for the palette (both Text
and Link
) I would expect that both the default font color and link color would be applied, at least for those widgets that use that palette setting. Unfortunately, that only happens in the last widget that uses the current palette.text().color().getRgb()
for the default stylesheet of the document, and it only works for the new anchor.
At this point we can expect the result whenever I change the color again to blue:
Again, the default text color is correctly applied for all QTextEdit widgets, but it only works for the latest link added to the last text edit.
After some easy toHtml()
checks against all widgets and browsing through the Qt sources, I realized that whenever a new anchor is added, the actual html code embeds the text style of the anchor text (instead of leaving the text format to the default settings and overriding it if it's specified).
While I will probably submit a report, as written at the beginning, I know that some time will be required before that will be taken in consideration and finally (if ever) fixed.
So, the question is: am I missing something/doing something wrong, or is there a way to avoid that behavior and ensure that all unformatted anchors actually use the palette set for the widget (or the application)?
Obviously I'm not talking about parsing/hardfixing the existing code by hand.