Python PyQT绘制多边形

Python PyQT绘制多边形,python,pyqt,qpainter,paintevent,Python,Pyqt,Qpainter,Paintevent,在我的QT应用程序中,我绘制了许多多边形,如下所示: 我正在为这些设置动画,因此一些多边形将接收新颜色。此动画每秒运行4-5次 但是,调用Qt.Painter()4-5次/秒的paintEvent()会重新绘制所有多边形,从而导致性能问题。它每秒只更新一次,速度太慢了。如下图所示,只有前12行中的一些多边形需要更新: 在QT文档中,我读到您无法真正保存已绘制内容的状态。所以你必须重新绘制所有内容。我错过什么了吗?还有什么诀窍可以做到这一点吗 这就是我的paintEvent()的基本外观(简化

在我的QT应用程序中,我绘制了许多多边形,如下所示:

我正在为这些设置动画,因此一些多边形将接收新颜色。此动画每秒运行4-5次

但是,调用
Qt.Painter()
4-5次/秒
paintEvent()
会重新绘制所有多边形,从而导致性能问题。它每秒只更新一次,速度太慢了。如下图所示,只有前12行中的一些多边形需要更新:

在QT文档中,我读到您无法真正保存已绘制内容的状态。所以你必须重新绘制所有内容。我错过什么了吗?还有什么诀窍可以做到这一点吗

这就是我的
paintEvent()
的基本外观(简化、减少圈复杂度)

呼叫(每次Pin更改时更新):


Qt只允许为小部件的一部分(区域)安排更新,从而优化结果。这需要两个步骤:

  • 使用适当的矩形调用,该矩形仅覆盖小部件中需要重新绘制的部分
  • 检查该区域,然后进行喷漆,以便仅喷漆该区域 如果您确定只有前X行将更改颜色,则:

    self.draw_area.update(
        QRect(0, 0, self.draw_area.width(), <height of the repainted rows>)
    
    上面的代码非常简单,您可以为每组行创建多个Qpicture,然后在需要时决定哪一个绘制,甚至可以通过组合
    event.rect()
    检查,如上所述

    这种技术的主要好处是QPainter通常处理QPicture的速度非常快,因此您不必进行行、多边形等所需的所有计算


    最后,您提供的图像看起来非常重复,几乎像一个纹理。在这种情况下,您可以考虑为每个行组使用qPixMax,然后用QBrush创建一个QPixmap。在这种情况下,您只需调用
    painter.fillRect(self.rect(),self.textureBrush)

    如何请求绘制更新?@musicamante从while循环内部执行,该循环将等待直到Pin状态发生更改。我编辑了这个问题,这不好。在GUI程序中(至少在主线程中)应始终避免阻塞函数和循环。请使用QTimer。您能否提供一个示例,说明如何用QTimer替换这3个while循环?我以前试过这个,但没有真正起作用。这对于这个问题来说是离题的。而且,在任何情况下,只需创建一个QTimer,连接到一个函数,该函数根据前一个状态检查新状态,如果它发生了更改,则调用update。但这只是一般用法,我不知道你是如何实现这个变量的状态变化的,因为我知道你可以用一个信号来代替,这会更简单。
    while True:
      while(stempel.readPin(0) == 0):
        QApplication.processEvents()
        time.sleep(0.01)
      self.draw_area.update() # Pin state changed, update polygons
      while(stempel.readPin(0) == 1):
        QApplication.processEvents()
        time.sleep(0.01)
    
    self.draw_area.update(
        QRect(0, 0, self.draw_area.width(), <height of the repainted rows>)
    
    if event.rect().bottom() < <height of the repainted rows>:
        rowRange = range(indexOfTheLastRowToRepaint + 1)
    else:
        rowRange = range(len(self.array))
    
    class DrawArea(QWidget):
        cache = None
        def paintEvent(self, event):
            if not self.cache:
                self.cache = QPicture()
                cachePainter = QPainter(self.cache)
                # draw on the painter
                cachePainter.end()
            painter = QPainter(self)
            painter.drawPicture(0, 0, self.cache)
    
        def resizeEvent(self, event):
            self.cache = None