【问题标题】:paintevent in continuous loop?连续循环中的paintevent?
【发布时间】:2014-04-22 03:53:44
【问题描述】:

我有以下代码在圆的圆周上绘制椭圆,然后在椭圆之间绘制和弦。和弦画得很好,但事件轰炸了我,进入了无限循环。

def binomial(i, n):

    return math.factorial(n) / float(
    math.factorial(i) * math.factorial(n - i))


def bernstein(t, i, n):

    return binomial(i, n) * (t ** i) * ((1 - t) ** (n - i))


def bezier(t, points):

    n = len(points) - 1
    x = y = 0
    for i, pos in enumerate(points):
        bern = bernstein(t, i, n)
        x += pos[0] * bern
        y += pos[1] * bern
   return x, y


def bezier_curve_range(n, points):

    for i in xrange(n):
        t = i / float(n - 1)
        yield bezier(t, points)

def getControlPt(x1, y1, x2, y2, t):

    new_px = (1 - t) * x1 + t * x2
    new_py = (1 - t) * y1 + t * y2
    return new_px, new_py


class Temp1(QWidget):
    def __init__(self, c, parent=None):
        super(Temp1, self).__init__(parent)
        self.text = "Hi"
        self.cords = c

    def paintEvent(self, e):
        qp = QPainter(self)
        qp.setPen(Qt.red)

        bluePen = QPen(Qt.blue, 1, Qt.DashLine)
        steps = 10000

        for i in range(15):
            for j in range(15):
              if i == j:
                  continue
              px, py = getControlPt(self.cords[i][0], self.cords[i][1], self.cords[j][0], self.cords[j][1], 0.55)
              px1, py1 = getControlPt(px, py, self.cords[j][0], self.cords[j][1], 0.25)
              px2, py2 = getControlPt(px1, py1, self.cords[j][0], self.cords[j][1], 0.75)

              cp = (self.cords[i], (px, py) , (px1, py1), (px2, py2), self.cords[j])
              oldPoint = cp[0]
              qp.setPen(bluePen)

              for point in bezier_curve_range(steps, cp):
                   qp.drawLine(oldPoint[0], oldPoint[1], point[0], point[1])
                   oldPoint = point




class Temp(QPushButton):
    def __init__(self, x, y, w, h, theta, cords, parent=None):
        super(Temp, self).__init__(parent)
        self.w = w
        self.h = h
        self.x = x
        self.y = y
        self.text = "test"
        self.angle = theta
        self.cords = cords

    def paintEvent(self, e):
        qp = QPainter(self)
        qp.setPen(Qt.red)
        qp.drawEllipse(0, 0, self.w - 2, self.h -2)




class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.cords = []
        self.initUI()

    def initUI(self):

        self.setWindowTitle('Points')
        self.drawP()



    def drawP(self):
        theta = 2 * np.pi / 15
        for i in range(15):
            angle = theta * (i + 1)

            dx = int(round(400 + 300 * np.cos(angle)))
            dy = int(round(400 + 300 * np.sin(angle)))
            self.cords.append((dx, dy))
        for i in range(15):    
            t = Temp(self.cords[i][0], self.cords[i][1], 45, 20, np.degrees(angle), self.cords, parent=self)
            t.setGeometry(self.cords[i][0], self.cords[i][1] , 45, 20)
        t1 = Temp1(self.cords, parent = self)
        t1.setGeometry(0, 0, 800, 600)



app = QApplication(sys.argv)
ex = Example()
ex.setGeometry(0, 0, 800, 600)
ex.show()
sys.exit(app.exec_())

问题出在 Temp1 类的 paintevent 函数上。

【问题讨论】:

  • 不要从paintEvent 调用setGeometry - 这是一个逻辑错误。
  • 我无法测试 Temp1.paintEvent 因为我没有您使用的功能,但其余代码看起来不错。可能问题出在其他地方。您是否考虑过使用QGraphicsView?它更方便您的任务。您不必继承任何东西并重新实现绘制事件。 Qt 还支持贝塞尔曲线(例如QPainterPath::cubicTo)。
  • @PavelStrakhov 您好,我添加了贝塞尔曲线的代码,如果这有助于您了解可能发生的情况,请告诉我。

标签: python qt user-interface pyside


【解决方案1】:

如果你在 Temp1.paintEvent 内的嵌套 for 循环中抛出一个 print 'Temp1.paintEvent', e, i, j,你会发现它并没有挂起,它只是很慢,每次你隐藏窗口,然后再把它拉回来,它都有在实际显示之前再次浏览整个paintEvent。如果您有耐心,该窗口最终会弹出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2020-03-24
    • 2016-02-06
    相关资源
    最近更新 更多