Pregunta

voy a tratar de ser lo más claro posible, aunque esto es un poco confuso en mi cabeza.

Tengo una aplicación de PyQt que ha estado trabajando durante casi un año. Después de actualizar a 4.5.1 PyQt (desde 4.3.3) ninguno de mis iconos aparecen en el QTableView más (esta actualización era concurrente con una actualización de Python 2.6.5 desde 2.5.1). Volviendo a la pitón mayor y PyQt, todo funciona como se espera.

El desglose es el siguiente:

Estoy utilizando la metodología de modelo de vista. Mi modelo, cuando se le solicite a través de un Qt.DecorationRole en el método de datos (), devolverá un objeto personalizado (ColorSwatch) que es una subclase de la clase QIcon. Esto siempre ha trabajado (con la salvedad de que, por razones que no entiendo, que refundición como un QVariant primero). Después de la actualización a 4.5.1 PyQt que aparece para funcionar correctamente (es decir, no estoy recibiendo ningún error), pero el icono no llama (aunque el espacio en el que se dibuja es "reservado" es decir, el texto se ha desplazado hacia la derecha para dar paso a este icono invisible).

Aquí hay algunas cosas que he intentado:

He comprobado que la clase ColorSwatch hace seguir funcionando. Esta misma clase se utiliza para dibujar iconos en un menú contextual -. Y aparecen correctamente

He verificado que el método de datos () en realidad se está llamó y está volviendo este objeto ColorSwatch (refundición en un QVariant <- aunque he probado sin esta refundición también).

Verter la sangre de serpiente en mi teclado y encenderlo en llamas.

Nada hasta ahora me ha dado ninguna pista sobre lo que debería hacer. Alguna pista sería muy apreciada. Gracias.

Esta es una parte del código correspondiente (potencialmente) (nota que paramObj.get_icon () devuelve un objeto ColorSwatch):

#---------------------------------------------------------------------------
def data(self, index, role=QtCore.Qt.DisplayRole):
    """
    Returns the text or formatting for a particular cell, depending on the 
    role supplied.
    """


    blah
    blah
    blah



    elif role == QtCore.Qt.DecorationRole:
        if platform.system()=='Darwin':
            return QtGui.QIcon(paramObj.get_icon())
        else:
            return QtCore.QVariant(paramObj.get_icon())

y

import os
import tempfile
import sys
import colorsys
import copy
import fnmatch
import time

from PyQt4 import QtGui
from PyQt4 import QtCore


################################################################################
class ColorSwatch(QtGui.QIcon):
    """
    A subclass of QIcon, this class draws a colored paint chip with a border
    The color and size are determined at construction time, and cannot
    be changed later.
    """

    #---------------------------------------------------------------------------
    def __init__(self, r=1, g=1, b=1, br = 0, bg = 0, bb = 0, w=20, h=20):
        """
        Constructor for the ColorSwatch class. Takes the passed arguments and
        creates a square icon filled with the given color and with a border
        color determined by br, bg, bb. All colors should be in floating point
        format.
        """
        QtGui.QIcon.__init__(self)

        #normalize the color
        r8, g8, b8 = self.normalize_color((r, g, b))

        #convert the r, g, b values to 8 bit colors
        r8, g8, b8 = self.fp_to_8b_color((r8, g8, b8))

        #Create the pixmap and painter objects
        paintChip = QtGui.QPixmap(w, h)
        painter = QtGui.QPainter()
        painter.begin(paintChip)

        #fill the swatch
        baseColor = QtGui.QColor(r8, g8, b8)
        painter.fillRect(0, 0, w, h, baseColor)

        #if any of the values were super brights (>1), draw a smaller, white
        #box inset to make sure the user knows
        if r > 1 or g > 1 or b > 1:
            painter.fillRect(5, 5, w-10, h-10, QtGui.QColor(255, 255, 255))

        #if all values are 0, put a faint x through the icon
# # #         brush = QtGui.QBrush()
# # #         brush.setColor(QtGui.QColor(30, 30, 30))
        painter.setPen(QtGui.QColor(200, 200, 200))
        if r ==0 and g == 0 and b == 0:
            painter.drawLine(0, 0, w, h)
            painter.drawLine(w-1, 0, -1, h)
# # #         
# # #         #normalize the color
# # #         r8, g8, b8 = self.normalize_color((r8, g8, b8))

        #now draw the border(s)
        #convert the r, g, b values to 8 bit colors
        r8, g8, b8 = self.fp_to_8b_color((br, bg, bb))

        #draw the border
        painter.setPen(QtGui.QColor(r8, g8, b8))
        painter.drawRect(0,0,w-1,h-1)

        #if any of the values were super brights (>1), draw a border around the
        #inset box as well.
        if r > 1 or g > 1 or b > 1:
            painter.drawRect(5,5,w-11,h-11)

        #done drawing
        painter.end()

        #add it (both to the normal and the selected modes)
        self.addPixmap(paintChip, QtGui.QIcon.Normal)
        self.addPixmap(paintChip, QtGui.QIcon.Selected)


    #---------------------------------------------------------------------------
    def fp_to_8b_color(self, color):
        """
        Convert a floating point color value (passed in the form of a three 
        element tuple) to a regular 8-bit 0-255 value. Returns a 3 item tuple.
        """
        r = max(min(int(color[0]*255),255),0)
        g = max(min(int(color[1]*255),255),0)
        b = max(min(int(color[2]*255),255),0)
        return (r,g,b)


    #---------------------------------------------------------------------------
    def normalize_color(self, color):
        """
        "normalizes" a color value so that if there are any super-whites, it 
        balances all the other floating point values so that we end up with a 
        "real" color.  Negative values will result in undefined behavior.
        Mainly used to make the color chip "look right" when using super whites.
        """
        maxValue = max(color)
        if maxValue > 1:
            return (color[0]/maxValue, color[1]/maxValue, color[2]/maxValue)
        else:
            return color
¿Fue útil?

Solución

Ivo respondió a mi pregunta anterior.

el código real que funciona es:

#---------------------------------------------------------------------------
def data(self, index, role=QtCore.Qt.DisplayRole):
    """
    Returns the text or formatting for a particular cell, depending on the 
    role supplied.
    """


    blah
    blah
    blah



    elif role == QtCore.Qt.DecorationRole:
        if platform.system()=='Darwin':
            return QtGui.QIcon(paramObj.get_icon())
        else:
            return QtCore.QVariant(QtGui.QIcon(paramObj.get_icon()))
            #Note that it is first cast as a QIcon before
            #being cast as a QVariant.

Gracias de nuevo Ivo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top