PDA

View Full Version : Use of QStyledItemDelegate prevents certain Stylesheets from working [gif]



DoTheEvo
16th February 2016, 19:17
Here is a gif showing the problem, when I dont use delegate we can see red background and magenta highlight but bold tags are ignored.
So I enable my QStyledItemDelegate to get bold text working and we see that the colors from stylesheet get ignored.

http://i.imgur.com/KjWIFqV.gif

Here is the simple code from the example where we can see the delegate used. Is there a way to fix delegate? Me quickly trying stuff, seems that rules that use double colon gets ignored?

Interesting thing is that I only now noticed some stylesheets getting ignored. I used popular dark theme stylesheet (https://github.com/ColinDuquesnoy/QDarkStyleSheet) and it seemed that its working for most stuff. The problem appears when I need to control color of the selection highlight in tableview, to make it blink red when something is wrong with the item and user double clicks it, I had related question here (http://www.qtcentre.org/threads/64954-On-mouse-click-changing-selection-s-background-color-in-tableview) about it, Main problem then was that use of self.setStyleSheet('selection-background-color:red;') did not work on ubuntu like distros, while it did on KDE, i3. Now use of QTableView::item:selected:active {...} works everywhere flawlessly unless I use the rich html text delegate that I am using... which might be badly written, I am far from 100% in writing up delegates.



from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys


class My_Model_table(QAbstractTableModel):
def __init__(self, table_data=[], parent=None):
super().__init__()
self.table_data = table_data

def rowCount(self, parent):
return len(self.table_data)

def columnCount(self, parent):
return 1

def data(self, index, role):
if role == Qt.DisplayRole:
value = self.table_data[index.row()]
return value
if role == Qt.TextAlignmentRole:
return Qt.AlignCenter


class My_table(QTableView):
def __init__(self, parent=None):
super().__init__()

self.setItemDelegate(self.HTMLDelegate())

self.setStyleSheet(
'''
QTableView::item:selected:active {
background: magenta;
}

QTableView::item {
background: red;
}
'''
)

class HTMLDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
super().__init__()
self.doc = QTextDocument(self)

def paint(self, painter, option, index):
painter.save()

options = QStyleOptionViewItem(option)

self.initStyleOption(options, index)
self.doc.setHtml(options.text)
options.text = ""

style = QApplication.style() if options.widget is None \
else options.widget.style()
style.drawControl(QStyle.CE_ItemViewItem, options, painter)

ctx = QAbstractTextDocumentLayout.PaintContext()

if option.state & QStyle.State_Selected:
ctx.palette.setColor(QPalette.Text, option.palette.color(
QPalette.Active, QPalette.HighlightedText))
else:
ctx.palette.setColor(QPalette.Text, option.palette.color(
QPalette.Active, QPalette.Text))

textRect = style.subElementRect(
QStyle.SE_ItemViewItemText, options)

textRect.adjust(20, 0, 0, 0)

thefuckyourshitup_constant = 4
margin = (option.rect.height() - options.fontMetrics.height()) // 2
margin = margin - thefuckyourshitup_constant
textRect.setTop(textRect.top() + margin)

painter.translate(textRect.topLeft())
painter.setClipRect(textRect.translated(-textRect.topLeft()))
self.doc.documentLayout().draw(painter, ctx)

painter.restore()

def sizeHint(self, option, index):
return QSize(self.doc.idealWidth(), self.doc.size().height())


if __name__ == '__main__':
app = QApplication(sys.argv)
data = ['normal', 'text', '<b>bold</b> text', 'hmmm', 'yeap <b>bold</b>']
main_table = My_table()
main_table.setModel(My_Model_table(data))
main_table.show()
sys.exit(app.exec_())