单击表格单元格后,QtableView 中的某些单元格不会自动重新绘制

发布于 2024-11-14 09:12:09 字数 1687 浏览 2 评论 0原文

我正在使用 QTableView 来实现交互式棋盘游戏。图像将显示在表格的单元格中。我使用带有绘制函数的 QStyledItemDelegate 来绘制表格单元格内的图像。

由于图像应仅显示在表格的某些单元格中,并在用户单击表格单元格时更新,因此使用与表格尺寸相同的双整型数组。根据数组的值,画家应该在表格的特定单元格中绘制图像。最初,表格的 4 个单元格内只有 4 个图像,当用户单击表格中的单元格时,数组会更新,这意味着表格单元格内绘制和显示的内容应该发生更改。

通常,用户单击一个空(白色)单元格,该单元格已成功更新,并且特定图像显示在单元格中。但是,如果有其他单元格包含图像并且应该更新,则不会显示更新,尽管 double int 数组已更新。我还看到了一个奇怪的事情,那就是当我单击其显示应该更新的单元格时,更新就会发生。当有人单击单元格时,无论我如何更新,这种情况当然都会发生。

我尝试在重绘之前先擦除单元格内部的内容,但它仍然不起作用。委托是否在线程中连续运行,并且使用表中每个单元格的索引调用绘制函数?我不明白包含图像的单元格的更新如何不会自动更新,尽管画家应该重新绘制单元格的区域,并且仅在单击单元格后才会发生。或者是因为每次都会调用一个新的画家来执行画家的职能?!

好吧,这是我对委托的画家功能的实现:

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 
     {
         painter->eraseRect(option.rect);

         QStyledItemDelegate::paint(painter, option, index);
     }
  } 

如果您需要解决我的问题,我可以为您提供更多信息。提前致谢。

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, an double int array is used which is of the same dimensions as the table. Depending on the values the 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 rthe 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 
     {
         painter->eraseRect(option.rect);

         QStyledItemDelegate::paint(painter, option, index);
     }
  } 

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光清浅 2024-11-21 09:12:09

我还看到了一件奇怪的事情,那就是当我单击其显示应该更新的单元格时,更新就会发生。

我认为您必须确定女巫单元受到用户在当前单元中所做的更改的影响,并强制这些单元update()。当您想到这一点时,您的委托可以检查 tb1 的内容是否发生更改,以自动决定重新绘制它所属的单元格。

编辑

一种简单的方法,可以是将一个插槽连接到单击的( const QModelIndex & index ),然后在此处确定更改并调用update ( const QModelIndex & index ) 方法 ...

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.

I think you have to determine witch cells are affected by the change made by the user in the current cell and force those cells to update(). When you think of it, your delegate can check if the content of the tb1 change to automatically decide to repaint the cell it belong to.

EDIT

A simple way to do that, could be to connect a slot to the clicked ( const QModelIndex & index ) then in here determine what change and call the update ( const QModelIndex & index ) method ...

暮年 2024-11-21 09:12:09

根据 QT 文档

涂漆后,您应该确保
画家又回到了原来的状态
说明它是在何时供应的
函数被调用。例如,它
调用 QPainter::save() 可能有用
在绘画之前和
之后是 QPainter::restore()。

我认为您的函数中缺少 QPainter 的 save()restore() 方法。

According to QT Documentation

After painting, you should ensure that
the painter is returned to its the
state it was supplied in when this
function was called. For example, it
may be useful to call QPainter::save()
before painting and
QPainter::restore() afterwards.

I think you are missing save() and restore() methods of QPainter in your function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文