PyQT5 - 使用暂停逐行添加
PyQT5 - Add line one by one using a pause
以下代码每隔一秒绘制一条随机线。我想做的是让每条线都画好。最好的方法是什么?
我知道我需要使用 QTimer
来做一个响应式用户界面,但首先我需要知道如何绘制越来越多的线条...
也许一种方法是绘制所有隐藏的线并显示越来越多的线...或者我必须使用 QGraphicsView
吗?
from random import random
import sys
from time import sleep
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter
from PyQt5.QtCore import QTimer
LINES = [
(500*random(), 500*random(), 500*random(), 500*random())
for _ in range(50)
]
class Interface(QWidget):
def __init__(self):
super().__init__()
self.max = len(LINES)
self.cursor = 0
self.painter = QPainter()
self.setFixedSize(500, 500)
self.show()
def paintEvent(self, e):
self.painter.begin(self)
self.drawsetpbystep()
self.painter.end()
def drawsetpbystep(self):
if self.cursor < self.max:
self.painter.drawLine(*LINES[self.cursor])
self.update()
sleep(0.25)
self.cursor += 1
if __name__ == '__main__':
app = QApplication(sys.argv)
interface = Interface()
sys.exit(app.exec_())
不建议在 PyQt 应用程序中使用 time.sleep
,因为它会阻止负责处理用户输入(通过键盘和鼠标)和实际绘制应用程序的 Qt 事件循环的执行 window。
相反,您应该使用 QTimer
来安排指定方法在您需要的时间执行。在这种情况下,您可能希望使用多个 QTimer.singleShot
调用。计时器调用的第一个方法可能会绘制一个 point/line,然后设置一个计时器来调用另一个方法,该方法将绘制一个 point/line 并设置一个计时器来调用另一个方法......等等。等等
不建议在 GUI 中使用 sleep,在 PyQt 的情况下这是非常危险的,因为 Qt 提供了替代方法来创建与 QTimer、QEventLoop 等相同的效果
另一个错误是QPainter的生命周期非常长,应该只在paintEvent中创建和调用。
最后一个错误是想暂停 paintEvent 的任务,因为您是通过 drawsetpbystep 方法完成的。 paintEvent 方法不仅会被您使用,而且会在您需要时实际使用该应用程序,正确的做法是使用一个标志来指示您何时应该绘制,如下所示:
LINES = [
(500*random(), 500*random(), 500*random(), 500*random())
for _ in range(50)
]
class Interface(QWidget):
def __init__(self):
super().__init__()
self.max = len(LINES)
self.cursor = 0
self.show()
self.paint = False
timer = QTimer(self)
timer.timeout.connect(self.onTimeout)
timer.start(250)
def paintEvent(self, e):
painter = QPainter(self)
if self.paint:
self.drawsetpbystep(painter)
def onTimeout(self):
self.paint = True
self.update()
def drawsetpbystep(self, painter):
if self.cursor < self.max:
painter.drawLine(*LINES[self.cursor])
self.cursor += 1
self.paint = False
if __name__ == '__main__':
app = QApplication(sys.argv)
interface = Interface()
sys.exit(app.exec_())
以下代码每隔一秒绘制一条随机线。我想做的是让每条线都画好。最好的方法是什么?
我知道我需要使用 QTimer
来做一个响应式用户界面,但首先我需要知道如何绘制越来越多的线条...
也许一种方法是绘制所有隐藏的线并显示越来越多的线...或者我必须使用 QGraphicsView
吗?
from random import random
import sys
from time import sleep
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter
from PyQt5.QtCore import QTimer
LINES = [
(500*random(), 500*random(), 500*random(), 500*random())
for _ in range(50)
]
class Interface(QWidget):
def __init__(self):
super().__init__()
self.max = len(LINES)
self.cursor = 0
self.painter = QPainter()
self.setFixedSize(500, 500)
self.show()
def paintEvent(self, e):
self.painter.begin(self)
self.drawsetpbystep()
self.painter.end()
def drawsetpbystep(self):
if self.cursor < self.max:
self.painter.drawLine(*LINES[self.cursor])
self.update()
sleep(0.25)
self.cursor += 1
if __name__ == '__main__':
app = QApplication(sys.argv)
interface = Interface()
sys.exit(app.exec_())
不建议在 PyQt 应用程序中使用 time.sleep
,因为它会阻止负责处理用户输入(通过键盘和鼠标)和实际绘制应用程序的 Qt 事件循环的执行 window。
相反,您应该使用 QTimer
来安排指定方法在您需要的时间执行。在这种情况下,您可能希望使用多个 QTimer.singleShot
调用。计时器调用的第一个方法可能会绘制一个 point/line,然后设置一个计时器来调用另一个方法,该方法将绘制一个 point/line 并设置一个计时器来调用另一个方法......等等。等等
不建议在 GUI 中使用 sleep,在 PyQt 的情况下这是非常危险的,因为 Qt 提供了替代方法来创建与 QTimer、QEventLoop 等相同的效果
另一个错误是QPainter的生命周期非常长,应该只在paintEvent中创建和调用。
最后一个错误是想暂停 paintEvent 的任务,因为您是通过 drawsetpbystep 方法完成的。 paintEvent 方法不仅会被您使用,而且会在您需要时实际使用该应用程序,正确的做法是使用一个标志来指示您何时应该绘制,如下所示:
LINES = [
(500*random(), 500*random(), 500*random(), 500*random())
for _ in range(50)
]
class Interface(QWidget):
def __init__(self):
super().__init__()
self.max = len(LINES)
self.cursor = 0
self.show()
self.paint = False
timer = QTimer(self)
timer.timeout.connect(self.onTimeout)
timer.start(250)
def paintEvent(self, e):
painter = QPainter(self)
if self.paint:
self.drawsetpbystep(painter)
def onTimeout(self):
self.paint = True
self.update()
def drawsetpbystep(self, painter):
if self.cursor < self.max:
painter.drawLine(*LINES[self.cursor])
self.cursor += 1
self.paint = False
if __name__ == '__main__':
app = QApplication(sys.argv)
interface = Interface()
sys.exit(app.exec_())