Затухание / уменьшение цвета фона ячейки сетки wxpython - PullRequest
2 голосов
/ 21 октября 2010

У меня есть сетка wxpython, и я изменяю цвет фона ячейки, чтобы показать, что с ней что-то случилось.как JavaScript в браузере) для более плавного взгляда.Можно ли это сделать?

Сейчас я просто изменяю цвет фона, а затем возвращаю его обратно через 1,5 секунды.

def do_stuf(self):
    # ... stuff ...
    wx.CallAfter(self.HighlightCell, row, col)

def HighlightCell(self, row, col):
    self.grid.Table.highlight = (row, col)
    self.grid.ForceRefresh()
    wx.CallLater(1500, self.ClearCellHighlight)

def ClearCellHighlight(self):
    self.grid.Table.highlight = None
    self.grid.ForceRefresh()

Затем в виртуальной таблице, Я проверяю, нужно ли выделять ячейку:

def GetAttr(self, row, col, kind):
    """
    Use this callback to set the cell's background color
    """
    attr = wx.grid.GridCellAttr()
    if (row, col) == self.highlight:
        attr.SetBackgroundColour("green")
    elif row % 2:
        attr.SetBackgroundColour("white")
    else:
        attr.SetBackgroundColour("#e7ffff")

    return attr

В качестве альтернативы, есть ли еще один симпатичный способ указать, что содержимое ячейки изменилось?

Ответы [ 2 ]

4 голосов
/ 26 октября 2010

Это то, что я сделал некоторое время назад, чтобы получить ListCtrl с элементами, которые исчезают при удалении.Сохраните код в fade.py и запустите его, чтобы увидеть демо.Не должно быть слишком сложно адаптировать его к сетке.

import wx

class FadeMixin(object):
    ''' FadeMixin provides one public method: DeleteItem. It is meant to
    be mixed in with a ListCtrl to 'fade out' items before they are
    really deleted. Mixin like this:

    Assumption: the background colour of the control is wx.WHITE

    class MyListCtrl(FadeMixin, wx.ListCtrl):
        ...
    '''
    def __init__(self, *args, **kwargs):
        self.__bgColour = wx.WHITE
        super(FadeMixin, self).__init__(*args, **kwargs)

    def DeleteItem(self, index, fadeStep=10, fadeSpeed=50):
        if self.IsEnabled():
            self.__startDeleteItem(index)
        fgColour, bgColour, transparentColour = self.__getColours(index)
        if fgColour == bgColour == transparentColour:
            self.__finishDeleteItem(index)
        else:
            for colour, setColour in [(fgColour, self.SetItemTextColour), 
                                      (bgColour, self.SetItemBackgroundColour)]:
                fadedColour = self.__fadeColour(colour, transparentColour, 
                                                fadeStep)
                setColour(index, fadedColour)
            wx.FutureCall(50, self.DeleteItem, index, fadeStep, fadeSpeed)

    def SetBackgroundColour(self, colour):
        self.__bgColour = colour
        super(FadeMixin, self).SetBackgroundColour(colour)

    def GetBackgroundColour(self):
        return self.__bgColour

    def __startDeleteItem(self, index):
        # Prevent user input during deletion. Things could get messy if
        # the user deletes another item when we're still busy fading out the 
        # first one:
        self.Disable()
        # Unselect the item that is to be deleted to make the fading visible:
        currentState = self.GetItemState(index, wx.LIST_STATE_SELECTED)
        self.SetItemState(index, ~currentState, wx.LIST_STATE_SELECTED)

    def __finishDeleteItem(self, index):
        super(FadeMixin, self).DeleteItem(index)
        self.Enable()

    def __getColours(self, index):
        fgColour = self.GetItemTextColour(index)
        bgColour = self.GetItemBackgroundColour(index)
        transparentColour = self.GetBackgroundColour()
        if not bgColour:
            bgColour = transparentColour
        return fgColour, bgColour, transparentColour

    def __fadeColour(self, colour, transparentColour, fadeStep):
        newColour = []
        for GetIntensity in wx.Colour.Red, wx.Colour.Green, wx.Colour.Blue:
            currentIntensity = GetIntensity(colour) 
            transparentIntensity = GetIntensity(transparentColour)
            if currentIntensity < transparentIntensity:
                newIntensity = min(transparentIntensity,
                                   currentIntensity + fadeStep)
            elif currentIntensity > transparentIntensity:
                newIntensity = max(transparentIntensity, 
                                currentIntensity - fadeStep)
            else:
                newIntensity = transparentIntensity
            newColour.append(newIntensity)
        return wx.Colour(*newColour)


class ListCtrl(FadeMixin, wx.ListCtrl):
    pass


class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs)
        self.list = ListCtrl(self, style=wx.LC_REPORT)
        self.list.InsertColumn(0, 'Column 0')
        self.list.InsertColumn(1, 'Column 1')
        self.fillList()
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelected)
        self.Bind(wx.EVT_LIST_DELETE_ITEM, self.onDeleted)

    def onSelected(self, event):
        self.list.DeleteItem(event.GetIndex())

    def onDeleted(self, event):
        if self.list.GetItemCount() == 1:
            wx.CallAfter(self.fillList, False)

    def fillList(self, firstTime=True):
        for row in range(10):
            self.list.InsertStringItem(row, 'Item %d, Column 0'%row)
            self.list.SetStringItem(row, 1, 'Item %d, Column 1'%row)
        self.list.SetItemBackgroundColour(1, wx.BLUE)
        self.list.SetItemTextColour(2, wx.BLUE)
        self.list.SetItemBackgroundColour(3, wx.GREEN)
        self.list.SetItemTextColour(4, wx.GREEN)
        self.list.SetItemBackgroundColour(5, wx.RED)
        self.list.SetItemTextColour(6, wx.RED)
        self.list.SetItemBackgroundColour(7, wx.BLACK)
        self.list.SetItemTextColour(7, wx.WHITE)
        self.list.SetItemBackgroundColour(8, wx.WHITE)
        self.list.SetItemTextColour(8, wx.BLACK)
        if not firstTime:
            self.list.SetBackgroundColour(wx.BLUE)


app = wx.App(False)
frame = Frame(None, title='Select an item to fade it out')
frame.Show()
app.MainLoop()
1 голос
/ 26 октября 2010

Насколько мне известно, вы можете только установить прозрачность в виджете фрейма и увидеть его влияние на всех детей.Я не помню, почему настройка прозрачности для отдельных виджетов не работает.В любом случае, приличный способ симулировать что-то вроде этого было бы использовать wx.Timer, который циклически перебирает список разных оттенков одного цвета, а затем, когда итерация завершена, верните его в нормальный цвет.Это должно имитировать внешний вид достаточно хорошо.

...