我试图在我的跨平台pyQt程序中添加一个简单的节拍器,但是要获得准确的计时非常困难。使用PyGame的声音系统播放声音似乎效果最好。我试过声子,但它根本不一致,而且QSound在我的系统上根本不起作用。我尝试过使用python的时间库和qtimer来处理计时,但是QTimeLine似乎最有效。在
在较低的节奏的时机不算太坏。。。还是有点打嗝。然而,更高的节奏一点也不准确。在
如有任何意见/建议,我们将不胜感激!在
下面是一些代码:
class Metronome(object):
def init_metronome(self):
self.metronome_timer = QtCore.QTimeLine(100000)
self.metronome_timer.valueChanged.connect(self.tick)
self.metronome_timer.setCurveShape(3) #linear curve
self.ui.pushButton_metronome.toggled.connect(self.toggle_metronome)
self.ui.spinBox_metronome_bpm.valueChanged.connect(self.set_metronome_bpm)
pygame.mixer.init()
self.sound = pygame.mixer.Sound("./sounds/tick.wav")
def toggle_metronome(self):
if self.ui.pushButton_metronome.isChecked() == True:
self.set_metronome_bpm()
self.metronome_timer.start()
else:
self.metronome_timer.stop()
def set_metronome_bpm(self):
bpm = self.ui.spinBox_metronome_bpm.value()
self.metronome_timer.setUpdateInterval(60./bpm * 1000)
def tick(self):
QtCore.QCoreApplication.processEvents()
self.sound.play()
我不太熟悉Python和Qt的交互,但我对计时器、线程和Qt有经验。在
一般时间限制
Qt中的计时通常用于图形动画。在Qt Timers文档中,它说计时器精确到大约15毫秒,但这取决于平台。在windows中,如果你通读它们的定时器和系统时钟,它会说它们的精度大约为11到16毫秒
线程优先级
线程的优先级也会影响节拍器的结果。您可能应该考虑将线程的优先级设置为时间关键型(请参见^{} ),以便系统为您提供更好的计时,然后告诉您的函数在您完成声音播放后执行睡眠(0)或^{} 调用。在
QObject连接调用
Qt中的Connect调用是使用^{} 完成的,这意味着Qt决定是使用事件队列还是直接调用来连接它。对于时间安排,最好是直接打电话。在
另外,在播放声音后是否调用processEvents。事先这样做会告诉Qt,您希望在到达下一个调用之前处理事件队列中的任何其他内容。查看qt event system上的文档。在
MIDI文件
据我所知,游戏中生成的大多数声音都是使用MIDI文件完成的。它们很小,在许多平台上,它们的声音循环渲染非常一致。也许你可以从100个midi文件中选择一个。也有一些类似ScaleTempo的项目,但它似乎有点旧(上次更新是在2008年)。在
希望有帮助。在
免责声明:我发布的大部分链接都来自qt5。我大部分时间都在qt4.7中编程,但据我所知,计时器和事件系统并没有被安排用于qt5的改造(主要是动画后端优化)。在
相关问题 更多 >
编程相关推荐