我想为 QTableview 单元格的颜色(及时)设置动画,一旦它的值通过连接的数据模型更新,以吸引最终用户注意某些事情发生了变化。
这个想法是颜色在 fi blue 的渐变中发生变化,在值更改后立即从蓝色开始,并在大约 1 ~ 2 秒内逐渐变为白色。
我想这里必须使用 QStyledItemDelegate ,因为我使用模型视图概念(http://doc.qt.io/qt-5/model-view-programming.html)。
需要一个触发器来触发单元格的值更改才能开始动画,这可以通过 paint() 方法来实现,因为它是在值更改时调用的。可以从传递给paint() 的索引参数中找出行和列,以掌握要为哪个单元格设置动画。
到目前为止一切顺利,您可以将该单元格的颜色设置为蓝色。问题来了;颜色会随着时间的推移逐渐变白。所以我在考虑 QStyledItemDelegate 类中的 QTimer 并为正在动画的单元格维护一个有点记账(可能是用于计算蓝色渐变颜色的倒计时值的简单列表。值越低渐变趋向白色,一旦为 0,结果为白色,这是单元格的默认颜色。在每个 QTimer timeout() 事件中,所有不等于 0 的值都降低 1。QStyledItemDelegate 仅连接到 QTableview 的行我想要彩色动画,即显示值项的位置。
我面临的问题是:
- paint() 是一个 const 方法,因此您不能更改任何类参数。
- 如何在 QTimer 事件上重新绘制单元格颜色(重新绘制整个 QTableview 不是上帝风格)
我设法让它工作,但我认为这是一个肮脏的解决方案。我所做的是维护数据模型中每个单元格的颜色动画的簿记。我认为这是一个肮脏的解决方案,因为彩色动画只是一个视觉方面,所以恕我直言,它不应该驻留在数据模型中。这样,它也不是一个可移植的解决方案,即在另一个项目中,您必须进行大量返工才能使其正常工作。
我将我的应用程序剥离到核心问题。完整的代码可以在这里找到(一个工作的应用程序):https ://github.com/fruitCoder123/animated_tableview_cell
void TableViewDelegateValueWritable::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// Paint background
uint8_t red_gradient = calculate_color_gradient(RGB_RED_MAX, RGB_RED_MIN, red_gradient_step_size, m_step_value);
uint8_t green_gradient = calculate_color_gradient(RGB_GREEN_MAX, RGB_GREEN_MIN, green_gradient_step_size, m_step_value);
painter->fillRect(option.rect, QColor(red_gradient, green_gradient, 255));
// Paint text
QStyledItemDelegate::paint(painter, option, index);
}
uint8_t TableViewDelegateValueWritable::calculate_color_gradient(const uint8_t MAX_COLOR, const uint8_t MIN_COLOR, const uint8_t step_size, uint8_t step) const
{
uint16_t color = (step_size * (1 + MAX_COLOR_GRADIENT_STEP - step)) + MIN_COLOR;
// Handle overflow and rounding errors
if(color > MAX_COLOR || color > (MAX_COLOR-(step_size/2)))
color = MAX_COLOR;
return static_cast<uint8_t>(color);
}
void TableViewDelegateValueWritable::gradient_timer_elapsed()
{
if(m_step_value)
{
m_step_value--;
m_timer->start(GRADIENT_TIMEOUT_VALUE);
//this->paint(m_painter, m_option, m_model_index);
}
}
我花了很长时间才找到一个好的解决方案。我一个月前开始使用 Qt,所以也许我缺乏知识。希望有人可以提示如何以一种很好的方式解决它 - 封装在视图中而不是与数据模型纠缠在一起。