PDA

View Full Version : Some cells in QtableView are not repainted automatically after a clicking on a cell



Mezzo
8th June 2011, 19:25
Hello,

I'm using a QTableView in the implementation of an interactive board game. Images are to be displayed in the cells of the table. I'm using a QStyledItemDelegate with a paint function to draw the images inside the table cells.

As the images should be displayed only in certain cells of the table and updated when a user clicks on a table cell, a double int array is used which is of the same dimensions as the table. Depending on the values of the array, the painter should draw images in specific cells of the table. Initially there are only 4 images inside 4 cells of the table and as the user clicks on a cell in the table, the array is updated which should consequently mean that whats drawn and displayed inside the cells of the table should be changed.

Normally the user clicks on an empty (white) cell which is updated successfully and the specific image is shown in the cell. However, if there are other cells which contain an image and should be updated, the update is not shown, although the double int array is updated. I also saw a weird thing, that is when I click on the cells in which their display should have been updated, the update happens. This of-course occurs regardless of how I update when someone clicks on a cell.

I tried to first erase whats inside the cell before redrawing, but its still not working. Does the delegate runs continuously in a thread and the painter function is called with the index of each cell in the table? I do not get how an update on a cell containing an Image does not update automatically although the painter should have redrawn the cell's area and it occurs only after the a click on the cell has been made. Or its cus a new painter is called to the painter's function each time?!

Well, here is my implementation of the painter's function of the delegate:


void Sphere::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if(tb1[index.row()][index.column()] == 1)
{
QImage Q1("Red Sphere.jpg");

QRectF source(0.0, 0.0, 72.0, 70.0);

painter->eraseRect(option.rect);

if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());

painter->drawImage(option.rect, Q1, source);

}
else if(tb1[index.row()][index.column()] == 2)
{
QImage Q1("Blue Sphere.jpg");

QRectF source(0.0, 0.0, 72.0, 70.0);

painter->eraseRect(option.rect);

if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());

painter->drawImage(option.rect, Q1, source);

}
else
{
QStandardItemModel *model = (QStandardItemModel*) index.model();
if(!model->item(index.row(), index.column())->isEnabled())
QStyledItemDelegate::paint(painter, option, index);
else
{
painter->eraseRect(option.rect);
painter->fillRect(option.rect, Qt::white);
}
}
}

I can give you any more info if u needed to solve my problem. Thanks in advance.

Santosh Reddy
9th June 2011, 07:32
I tried to first erase whats inside the cell before redrawing,
erasing is not required, you only need to draw, rest is taken car by the framework

update all the required items from the same scope were you update your double int array. Where do you update your double int array, in the view's event clicked()? If yes then call

void QAbstractItemView::update(const QModelIndex & index) in there for all the items that have to be updated.

Mezzo
9th June 2011, 15:11
I called update ( const QModelIndex & index ) for each cell that should be updated but its still not working. I may have seen it work only once though.

Santosh Reddy
9th June 2011, 15:28
post how you call update(), and how create index ?

Mezzo
9th June 2011, 15:47
Well, first the click signal is received in AtaxxClass as in connect(tableView, SIGNAL(clicked(QModelIndex)), AtaxxClass, SLOT(update()));

then form the update function i use:

QPoint Q(row, col);
ui.tableView->update(ui.tableView->indexAt(Q));

for each cell that should be updated, after updating the array.

Santosh Reddy
9th June 2011, 17:14
Well, first the click signal is received in AtaxxClass as in connect(tableView, SIGNAL(clicked(QModelIndex)), AtaxxClass, SLOT(update()));
There might be problems with this.

1. AtaxxClass is subclass of QTableView, and QTableView already has a public slot named update(QModelIndex);
2. Make sure the SIGNAL & SLOT functions signatures match, else the slot may will not be called


then form the update function i use:
Do you mean you implemented update function? You should not be doing so. You should be calling already exisiting QTableView::update(QModelIndex);

Mezzo
10th June 2011, 20:44
Well, first of all AtaxxClass is a subclass of QMainWindow. And yes, I've implemented the update function, this is were I update the array based on the user selection.

Added after 1 28 minutes:

I got it. I called update(const QModelIndex & index) in the painter's function of the delegate at the beginning (first line) and it worked. Not sure if this was the best way to do it but it worked. Thanks for your help.