PyQt QTableView no mostrar iconos después de la actualización a 4.5.1 PyQt
-
04-10-2019 - |
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
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.