0

I have created by myself model (MyListModel) that store list of my objects MyObj. MyObj stores some text information. Then I created class ItemDelegate, in order to manage view of every item and also to add QProgressBar to each item. The problem is that I need busy progressbar, but when I execute app, QProgressBar doesn't do any action.busy progressbar don't work

I'm guessing, it's because QListView only show static data. Is there any way to make it work properly? My realisation of paint method for Delegate:

void StatusItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    StatusItem my_item = index.data().value<StatusItem>();
    wdg->name->setText(my_item.m_name);
    switch (my_item.m_state)
    {
        case 0: wdg->progress->setMaximum(0);  wdg->progress->setMinimum(0); break;
        case 1: wdg->progress->setRange(0, 0); wdg->progress->setValue(100); break;
        case 2: wdg->progress->setHidden(true); break;
    }
    QPalette pal;
    QLinearGradient gradient(0, 0, 0, 100);

    if ((option.state & QStyle::State_Selected) == QStyle::State_Selected)
    {
        pal.setBrush(QPalette::Window, QBrush(QColor(0, 255, 200)));
    }
    else
    {
        gradient.setColorAt(0.0, QColor(255,250,0));
        gradient.setColorAt(1.0, QColor(255,255,255));
        pal.setBrush(QPalette::Window, QBrush(QColor(Qt::transparent)));
        pal.setBrush(QPalette::Window, QBrush(gradient));
    }
  wdg->setPalette(pal);
  wdg->resize(option.rect.size());
  painter->save();
  painter->setRenderHint(QPainter::Antialiasing, true);
  painter->translate(option.rect.topLeft());
  wdg->render(painter);

  painter->restore();
}
Sunrise
  • 1,311
  • 3
  • 18
  • 28

1 Answers1

0

I think the problem exists because the view repaints items only when something is changed. While model data remains unchanged, according cells are not repainted.

In this situation you should cause additional repaints from the delegate. Unfortunately there is no convenient way to do it, but there are longer ways. You need to do the following action in the paint method:

view->update(index);

There are two issues:

  1. You don't have view pointer in the paint method. You can either try to use painter->device() and assume that this is the view's viewport (but it's not guaranteed) or store view in the delegate's class member variable.

  2. Calling update inside paint can cause infinite recursion (I'm not sure about this one). If that's the case, you can delay update using QTimer::singleShot(0, ...). But you will need to create a slot for that somewhere an pass view and index somehow so that they will be accessible in the slot.

Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
  • `view->update(index);` inside `paint` method don't work, calling this function from other place, to check if it'll help, is hard because `paint` method is `const`, and it's impossible to store `QModelIndex` (paint's argument) inside `QItemDelegate`, maybe it will work if create signal that will send `QModelIndex` and slot that will do `view->update(index);`. But for me simpliest solution is to use `QListWidget`, where busy progressbar works propely. – Sunrise May 16 '14 at 16:32