0

I am currently trying to add a multiline text editor to the PandasGUI application and have implemented the solution found here: Make row of QTableView expand as editor grows in height

I am using the qtstylish.dark() stylesheet for the application so I would like the text of the QTableview to be white. It is currently black and has been steadfastly resisting my efforts to change the text color.

The reimplemented paint function currently looks like this:

def paint(self, painter, option, index):
    # Remove dotted border on cell focus.  https://stackoverflow.com/a/55252650/3620725
    if option.state & QtWidgets.QStyle.State_HasFocus:
        option.state = option.state ^ QtWidgets.QStyle.State_HasFocus
    
    self.initStyleOption(option, index)
    painter.save()
    doc = QtGui.QTextDocument()
    doc.setDocumentMargin(2)
    doc.setTextWidth(option.rect.width())
    doc.setHtml(option.text)
    option.text = ""
    option.widget.style().drawControl(
        QtWidgets.QStyle.CE_ItemViewItem, option, painter)
    painter.translate(option.rect.left(), option.rect.top())
    doc.drawContents(painter)
    painter.restore()

Some of the things I have tried adding to the function:

painter.setPen(QColor(255, 255, 255, 200))
painter.setPen(QtGui.QPen(QtCore.Qt.white))
option.palette.setColor(QPalette.Normal, QPalette.Foreground, Qt.white)
doc.setDefaultStyleSheet('color: rgb(255, 255, 255);')

I have also tried reimplementing the drawContents and the initStyleOption function without finding success in changing the font color.

M D
  • 19
  • 1
  • 6
  • How are you setting the stylesheet? Is it applied to individual widgets or the whole QApplication? – musicamante Feb 23 '22 at 01:01
  • musicamante - the unsung hero of PyQt :D The stylesheet is applied to the whole application. app = QApplication(sys.argv) app.setStyleSheet(qtstylish.dark()) It can then be changed for the Widget the QTableView is on during runtime. self.setStyleSheet(qtstylish.dark()) self.store.settings.theme.value = 'dark' Changing the settings during runtime will change the style of everything but the text in the QTableView. It will work on the Editor, but not on the view. – M D Feb 23 '22 at 09:05

1 Answers1

0

QTextDocument by default uses the global application palette (which might be overridden by stylesheets).

If the widget uses a different palette, then QTextDocument.drawContents() won't be enough, and a proper context must be used.

The solution is to use the document layout and create a PaintContext instance with the alternate palette:

    def paint(self, painter, option, index):
        # ...
        layout = doc.documentLayout()
        ctx = layout.PaintContext()
        ctx.palette = option.palette
        layout.draw(painter, ctx)
        painter.restore()

Note: you might need to setClipRect() the painter to restrict drawing within the index rectangle, otherwise you might have some drawing artifacts (especially when hovering and scrolling). I couldn't test your code, but the following should suffice:

        # after translation
        clip = QtCore.QRectF(0, 0, 
            option.rect.width(), option.rect.height())
        painter.setClipRect(clip)
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Great, works like a charm. I am not seeing any artefacts even without the `setClipRect()` part. Thanks for helping out! – M D Feb 23 '22 at 20:39