PDA

View Full Version : A progress bar into treeView or something like that.



nilhcraiv
13th March 2013, 16:22
Hello,

I want to show in QTreeView a lot of QProgressBars as child of each item to indicate a processes, i.e. each item show a text in treeView, and they have QProgressBars as childs. I try it with QItemDelegate, but don't know how I individualy update each QProgressBar. I do it as follows: (I found this code searching on Internet)


CustomItemDelegate::CustomItemDelegate(QObject *parent) :
QItemDelegate(parent)
{
_state = QStyle::State_Enabled;
}

void CustomItemDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if(index.parent().isValid())
{
QStyleOptionProgressBarV2 progressBarOption;
QRect rect = option.rect;
QSize size(rect.width()*3/4,rect.height()*3/4);
rect.setSize(size);
progressBarOption.state = QStyle::State_Enabled;
progressBarOption.direction = QApplication::layoutDirection();
progressBarOption.rect =rect;
progressBarOption.fontMetrics = QApplication::fontMetrics();
QPalette pal = progressBarOption.palette;
QColor col;
col.setNamedColor("#05B8CC");
pal.setColor(QPalette::Highlight,col);
progressBarOption.palette = pal;
progressBarOption.type = QStyleOption::SO_ProgressBar;
progressBarOption.version = 2 ;
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.textAlignment = Qt::AlignCenter;
progressBarOption.textVisible = true;
int progress = index.data(Qt::DisplayRole).toInt();//TCP client or server must changes this value emitting signal bytesWritten(qint64)
progressBarOption.progress = progress;
progressBarOption.text = QString("%1%").arg(progressBarOption.progress);

// Draw the progress bar onto the view.
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter,0);

}
else
{
QItemDelegate::paint(painter, option, index);
}
}

...
...

and in QTreeView



CustomItemDelegate* itemDelegate = new CustomItemDelegate(this);
setItemDelegate( itemDelegate );//To set progressbar in childs of each item.

setModel( "a QAbstractItemModel to build the hierarchy of item");


In this code the progress of QProgressBar is set by text on QModelIndex index. How I can change only a progress in one ProgressBar? My application creates a TCP connection to send a file and I wish show the progress in each progressbar but I don't want update all QAbstractItemModel by setModel()

I have searched a lot, but have not found the solution!

wysota
13th March 2013, 22:40
How I can change only a progress in one ProgressBar? My application creates a TCP connection to send a file and I wish show the progress in each progressbar but I don't want update all QAbstractItemModel by setModel()

If you don't want to update the model then what do you need the model for?

nilhcraiv
14th March 2013, 14:51
Firstly, thanks for your answer.

Sorry, maybe I have not explained well. Now I am creating a new QStandarItemModel and apply it with setModel. The problem is that creating a new QStandardItemModel is a long process because I'm doing it of this way:




class displayInformation .....
....
....

QStandardItemModel* displayInformation::createModel(const QList<Data *> *dataList) //This QStandardItemModel is seting by setModel() in QTreeView
{//Data is a class that contain all information of each item and its chils to show it in QTreeView
int index = 0;

if(!dataList)
return model; //model is a QStandardItemModel*

if(dataList->size()==0){
model->setRowCount(0); index = 0; return model;}

if(dataList->size() < model->rowCount())//To remove a item
{
int check = 0;
for(int i=0;i<model->rowCount();i++)
{
QString showText;
showText = model->item(i)->text();

for(int j=0; j<buddies->size();j++)
{
if(showText == buddies->at(j)->getAddress().toString())
{
check=1;
break;
}
}//for
if(check!=1)
{
model->removeRow(i);//REMOVE THE ITEM
break;
}
return model;
}//If remove item

while(index < buddies->size())//To add item and its chils if it has them
{
QStandardItem *item;
if(dataList)
{
item = createItem(
dataList->at(index)->getAddress().toString(),
dataList->at(index)->getNumConnections())//I create the item whit its chils (connections)
model->setItem(index, item);
}
index++;
}
return model;
}//createModel
.....
....



If I want show 100 QProgressBar as children of text items and after update each prgress of each progress Bar when the signal byttesWritten is emited, my application must perform many calculations. How I can extract each item individually and apply changes?

wysota
14th March 2013, 15:16
Why do you want to create a new model? If just one item in it changes, simply update this one item.

nilhcraiv
14th March 2013, 15:22
Why do you want to create a new model? If just one item in it changes, simply update this one item.

Yes, that is my problem, How I do it? How I simply update this one item? I dont know how a can update this one QModelIndex of QStandarItemModel...

wysota
14th March 2013, 15:28
Using QStandardItem::setData() or QAbstractItemModel::setData() depending on what you're operating on.

nilhcraiv
14th March 2013, 15:57
Thank you. I was confused because the documentation says:


Sets the role data for the item at index to value.

Returns true if successful; otherwise returns false.

The dataChanged() signal should be emitted if the data was successfully set.

The base class implementation returns false. This function and data() must be reimplemented for editable models.


I thought for use setData() is necessary implement this virtual function because by default returns false....

wysota
14th March 2013, 16:02
It returns false in QAbstractItemModel. But QStandardItemModel is a subclass of it which reimplements this method.

nilhcraiv
23rd March 2013, 01:29
Thank you, setData() is what I needed.