0

接続されたデータ モデルを介して値が更新されたら、QTableview セルの色を (時間内に) アニメーション化し、何かが変更されたというエンド ユーザーの注意を引きたいと考えています。

fi blue のグラデーションで色が変化し、値の変更直後に青から始まり、約 1 ~ 2 秒で白にフェードアウトするという考え方です。

モデル ビューの概念 ( http://doc.qt.io/qt-5/model-view-programming.html )を使用しているため、ここでは QStyledItemDelegate を使用する必要があると思います。

アニメーションを開始するには、セルの値変更のトリガーが必要です。これは、値の変更で呼び出される paint() メソッドを介して実現できます。paint() に渡された index パラメータから行と列を割り出し、どのセルをアニメートするかを把握できます。

これまでのところ、そのセルの色を青に設定できます。ここで問題が発生します。色は時間ステップで白に向かってフェードします。だから私は QStyledItemDelegate クラスの QTimer について考えていて、アニメーション化されているセルのちょっとした簿記を維持していました (青のグラデーションの色を計算するために使用されるカウントダウン値の単純なリストである可能性があります.値が低いほど、グラデーションは白に向かい、0 になるとセルのデフォルトの色である白になります。各 QTimer timeout() イベントでは、0 以外の値はすべて 1 ずつ引き下げられます。QStyledItemDelegate は、その QTableview の行にのみ接続されます。値アイテムが表示される場所、つまりカラーアニメーションを作成したい。

私が直面している問題は次のとおりです。

  1. paint() は const メソッドであるため、クラス パラメータを変更することはできません。
  2. 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);
    }
}

私は素晴らしい解決策を見つけるために恐ろしい時間を費やしました. 1か月前にQtを始めたので、知識が不足している可能性があります。うまくいけば、誰かがそれをうまく解決する方法のヒントを与えることができます-ビューにカプセル化され、データモデルに絡まることはありません.

4

1 に答える 1