我會盡量清楚,儘管這在我的腦海中有點混亂。PyQt QTableView在更新到PyQt 4.5.1後不顯示圖標
我有一個已經工作了大約一年的PyQt應用程序。在更新到PyQt 4.5.1(從4.3.3開始)後,我的圖標不再出現在QTableView中(此更新與2.5.1中的python 2.6.5更新併發)。恢復到較舊的python和PyQt,一切都按預期工作。
故障是這樣的:
我正在使用模型視圖方法。我的模型,當通過data()方法中的Qt.DecorationRole請求時,將返回一個自定義對象(ColorSwatch),它是QIcon類的一個子類。這一直都很有效(我要提醒的是,由於我不明白的原因,我必須先將它重新改寫爲QVariant)。更新到PyQt 4.5.1後,它出現正確運行(即我沒有得到任何錯誤),但圖標不繪製(雖然它將被繪製的空間是「保留」,即文本已被轉移到讓這個隱形圖標讓路的權利)。
這裏有一些事情,我曾嘗試:
我已經驗證ColorSwatch類確實仍然起作用。這個類用於將圖標繪製到上下文菜單中 - 並且它們正確顯示。
我已經驗證data()方法實際上正在調用並且正在返回此ColorSwatch對象(重新轉換爲QVariant < - 儘管我已經測試過這種方法沒有這種重新設計)。
將蛇血倒在我的鍵盤上並點燃它。
到目前爲止,沒有任何線索告訴我應該做什麼。任何提示將不勝感激。謝謝。
下面是一些(潛在的)相關代碼(注意paramObj.get_icon()返回一個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())
和
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
我知道一些從QVariant轉換到QVariant的自動轉換已經在PyQt的過去幾個時間點上發生了變化。試試這個:QVariant(QIcon(paramObj.get_icon()))。另外,你爲什麼要在那裏檢查達爾文? – Ivo 2010-09-23 10:04:37
Ivo。就是這樣!謝謝。 – bvz 2010-09-23 16:23:06
順便說一下,我正在檢查Darwin,因爲在我最初開發這個時候,我發現通過試驗和錯誤,OSX只會顯示圖標,如果它是作爲QIcon返回的,並且linux只有在返回QVariant 。我在OSX上運行它已經有一段時間了,但不知道是否仍然如此。再次感謝你的幫助! – bvz 2010-09-23 16:27:24