Search code examples
qtpython-2.7svgpysidenuke

PySide: How to set an SVG icon in QTreeWidget's item and change the size of the icon?


I have a UI that is using SVG icons in Nuke 8. While setting icons with the SVG files works fine, I cannot seem to find a way to change the size of the icons to a larger size in Qt. I have tried setting the icon's size and then load the SVG file, setting the icon on a widget and then place the widget in the QTreeWidgetItem, and setting the style sheet of the widget to use the SVG. I know I can scale up the SVG file before loading the file, but I prefer handling that inside of Qt.

Here's some example code of what I'm doing (This works, but the icon does not scale.):

from PySide import QtGui, QtCore

class TestTreeItem(QtGui.QTreeWidgetItem):
    def __init__(self, parent, value, status):
        super(TestTreeItem, self).__init__(parent)

        # Column 0
        self.setText(value)

        # Column 1
        # Using Qt Resources. All of the maps are to svg files.
        status_map = {0: ":/images/good",
        1: ":/images/warning",
        2: ":/images/error"}

        self.setSizeHint(1, QtCore.QSize(64, 64))
        icon = QtGui.QIcon(status_map[status])
        self.setIcon(1, icon)

Code that doesn't work:

Set the icon size and then load the icon

from PySide import QtGui, QtCore

class TestTreeItem(QtGui.QTreeWidgetItem):
    def __init__(self, parent, value, status):
        super(TestTreeItem, self).__init__(parent)

        # Column 0
        self.setText(value)

        # Column 1
        # Using Qt Resources. All of the maps are to svg files.
        status_map = {0: ":/images/good",
        1: ":/images/warning",
        2: ":/images/error"}

        self.setSizeHint(1, QtCore.QSize(64, 64))
        icon = QtGui.QIcon(QtGui.QSize(64, 64))
        icon.addFile(status_map[status])
        self.setIcon(1, icon)

Create a pixmap and scale it

from PySide import QtGui, QtCore

class TestTreeItem(QtGui.QTreeWidgetItem):
    def __init__(self, parent, value, status):
        super(TestTreeItem, self).__init__(parent)

        # Column 0
        self.setText(value)

        # Column 1
        # Using Qt Resources. All of the maps are to svg files.
        status_map = {0: ":/images/good",
        1: ":/images/warning",
        2: ":/images/error"}

        self.setSizeHint(1, QtCore.QSize(64, 64))
        pixmap = QtGui.QPixmap(status_map[status])
        pixmap.scaled(64, 64)
        icon = QtGui.QIcon(pixmap)
        self.setIcon(1, icon)

Create an empty pixmap and then load the SVG

from PySide import QtGui, QtCore

class TestTreeItem(QtGui.QTreeWidgetItem):
    def __init__(self, parent, value, status):
        super(TestTreeItem, self).__init__(parent)

        # Column 0
        self.setText(value)

        # Column 1
        # Using Qt Resources. All of the maps are to svg files.
        status_map = {0: ":/images/good",
        1: ":/images/warning",
        2: ":/images/error"}

        self.setSizeHint(1, QtCore.QSize(64, 64))
        pixmap = QtGui.QPixmap(QtGui.QSize(64, 64))
        pixmap.load(status_map[status])
        icon = QtGui.QIcon(pixmap)
        self.setIcon(1, icon)

Create a widget and then set the style sheet to use the SVG

from PySide import QtGui, QtCore

class TestTreeItem(QtGui.QTreeWidgetItem):
    def __init__(self, parent, value, status):
        super(TestTreeItem, self).__init__(parent)

        # Column 0
        self.setText(value)

        # Column 1
        # Using Qt Resources. All of the maps are to svg files.
        widget = QtGui.QWidget(parent)
        status_map = {0: ":/images/good",
        1: ":/images/warning",
        2: ":/images/error"}

        self.setSizeHint(1, QtCore.QSize(64, 64))
        widget.setStyleSheet("image: url({});".format(status_map[status]))
        parent.setItemWidget(self, 1, widget)

Solution

  • Alright, I found a solution that works.

    from PySide import QtGui, QtCore, QtSvg
    
    class TestTreeItem(QtGui.QTreeWidgetItem):
        def __init__(self, parent, value, status):
            super(TestTreeItem, self).__init__(parent)
    
            # Column 0
            self.setText(value)
    
            # Column 1
            # Using Qt Resources. All of the maps are to svg files.
            status_map = {0: ":/images/good",
            1: ":/images/warning",
            2: ":/images/error"}
    
            svg_renderer = QtSvg.QSvgRenderer(status_map[status])
            image = QtGui.QImage(64, 64, QtGui.QImage.Format_ARGB32)
            # Set the ARGB to 0 to prevent rendering artifacts
            image.fill(0x00000000)
            svg_renderer.render(QtGui.QPainter(image))
            pixmap = QtGui.QPixmap.fromImage(image)
            icon = QtGui.QIcon(pixmap)
            self.setIcon(1, icon)
    
            self.setSizeHint(1, QtCore.QSize(64, 64))
    

    This is based off of this answer: https://stackoverflow.com/a/8551810/3108288