PyQt QTableView не отображает значки после обновления до PyQt 4.5.1 - PullRequest
2 голосов
/ 23 сентября 2010

Я постараюсь быть максимально ясным, хотя все это немного запутано в моей голове.

У меня есть приложение PyQt, которое работает уже около года.После обновления до PyQt 4.5.1 (из 4.3.3) ни один из моих значков больше не появляется в QTableView (это обновление было параллельно с обновлением до python 2.6.5 из 2.5.1).Возвращаясь к старому Python и PyQt, все работает как положено.

Разбивка такова:

Я использую методологию просмотра модели.Моя модель при запросе через Qt.DecorationRole в методе data () вернет пользовательский объект (ColorSwatch), который является подклассом класса QIcon.Это всегда срабатывало (с оговоркой, которую я, по непонятным мне причинам, должен сначала преобразовать как QVariant).После обновления до PyQt 4.5.1 он , по-видимому, работает правильно (т.е. я не получаю никаких ошибок), но значок не рисуется (хотя место, где он будет нарисован, «зарезервировано», то есть текстбыло сдвинуто вправо, чтобы освободить место для этого невидимого значка).

Вот несколько вещей, которые я попробовал:

Я убедился, что класс ColorSwatch все еще функционирует.Этот же класс используется для рисования значков в контекстном меню - и они отображаются правильно.

Я убедился, что метод data () действительно вызывается и возвращает этот объект ColorSwatch (преобразованный в QVariant <-хотя я также проверил и без этого исправления). </p>

Заливая кровь змеи на мою клавиатуру и зажигая ее в огне.

Ничто до сих пор не дало мне никакого представления о том, что мне следует делать.Любые советы будут с благодарностью.Спасибо.

Вот некоторые из (потенциально) соответствующих кодов (обратите внимание, что 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

1 Ответ

1 голос
/ 23 сентября 2010

Ivo ответил на мой вопрос выше.

Фактический код, который работает:

#---------------------------------------------------------------------------
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.

Еще раз спасибо Ivo.

...