简体   繁体   中英

Selection highlight in PyQt4 QTableWidget fill selected cell's background with full block color

I am working on a small PyQt4 task manager. A similar question is ask in here Change QTableWidget default selection color, and make it semi transparent . From this post, I try to setStyleSheet for selection background color opacity, but the highlight is still override the cell background color. Is there someone can help me show how to change this to border color?

Image below is my current result

在此处输入图片说明

This is what I willing to achieve, as you see, the highlight selectionis just overlay the background color, but not override it.

在此处输入图片说明

At the end, hopefully my question is clear enough for everyone, if found any unclear or mistake, please kindly let me know, I will fix as fast as possible! Thanks!

One way to change the colors is to use a delegate.

For this we must get the current background color, the task of getting the background color is tedious since a QTableWidget has its own color as its background, it also has the colors that you add to QTableWidgets and other types of elements so my answer currently has limited support but the idea is scalable.

The color to be displayed as the background of the selected element is an average of the background color and a color chosen properly, in this case we choose the color #cbedff

I have implemented all of the above in the following class:

class TableWidget(QTableWidget):
    def __init__(self, *args, **kwargs):
        QTableWidget.__init__(self, *args, **kwargs)

        class StyleDelegateForQTableWidget(QStyledItemDelegate):
            color_default = QColor("#aaedff")

            def paint(self, painter, option, index):
                if option.state & QStyle.State_Selected:
                    option.palette.setColor(QPalette.HighlightedText, Qt.black)
                    color = self.combineColors(self.color_default, self.background(option, index))
                    option.palette.setColor(QPalette.Highlight, color)
                QStyledItemDelegate.paint(self, painter, option, index)

            def background(self, option, index):
                item = self.parent().itemFromIndex(index)
                if item:
                    if item.background() != QBrush():
                        return item.background().color()
                if self.parent().alternatingRowColors():
                    if index.row() % 2 == 1:
                        return option.palette.color(QPalette.AlternateBase)
                return option.palette.color(QPalette.Base)

            @staticmethod
            def combineColors(c1, c2):
                c3 = QColor()
                c3.setRed((c1.red() + c2.red()) / 2)
                c3.setGreen((c1.green() + c2.green()) / 2)
                c3.setBlue((c1.blue() + c2.blue()) / 2)

                return c3

        self.setItemDelegate(StyleDelegateForQTableWidget(self))

Example:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = TableWidget()
    w.setColumnCount(10)
    w.setRowCount(10)
    for i in range(w.rowCount()):
        for j in range(w.columnCount()):
            w.setItem(i, j, QTableWidgetItem("{}".format(i * j)))
            if i < 8 and j < 8:
                color = QColor(qrand() % 256, qrand() % 256, qrand() % 256)
                w.item(i, j).setBackground(color)
    w.show()
    sys.exit(app.exec_())

Deselected:

在此处输入图片说明

Selected:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM