尽管使用了QThread,但GUI仍然冻结

(代码张贴在末尾)按下空格键,通过创建线程并发出对演奏功能的调用来开始演奏中音

if self.playing is False:
    # PlayThread is initiated in PianoRoll when the space bar is hit. 
    Loop iterates and plays data, freezing the GUI

else:
    # This section is not reached because another space bar hit cannot be received while data is looping

我已经查看了以下教程以及有关StackOverflow的各种响应:

  1. https://manojbits.wordpress.com/2013/01/24/threading-in-pyqt4/
  2. joplaete教程

我尝试了以下方法:

  1. 将所有循环代码放置在信号函数中运行
  2. 将循环放入线程的run函数中,并将数据传递到带有send的信号函数中
  3. 将功能与处理对其调用的小部件分开
  4. 使数据结构具有全局性(尝试任何操作)

请让我知道我缺少什么或者是否需要其他代码。

我正在使用开源MIDI音序器模板https://github.com/rhetr/seq-gui

class PlayThread(QtCore.QThread):

    def __init__(self):

        # qtcore.QThread.__init__(self, parent=app)

        super(PlayThread , self).__init__()

        self.signal = QtCore.SIGNAL("signal")

    def run(self):

        global xLocToNoteItems

        # this loop was attempted in the signaled function as well
        for xloc in xLocToNoteItems:

            self.emit(self.signal, xloc)

        # self.emit(self.signal, "arbitrary?")

        # self.emit(QtCore.SIGNAL('update(QString)') + str(i))

在钢琴卷中:

if event.key() == QtCore.Qt.Key_Space:

    if self.playing:

        self.playing = False

        # terminate play thread

        main.playThread.quit()

    else:

        self.playing = True

        # playThread previously attempted to be stored in this (piano roll) class
            # ...was moved to main in case the call was freezing the piano roll
        main.playThread = PlayThread()

    main.connect(main.playThread, main.playThread.signal, main.play)

    main.playThread.start()

播放功能位于钢琴卷小部件中,现在位于主

def play(self, xloc):

    # for xloc in main.xLocToNoteItems:


    global xLocToRhythms
    global xLocToNoteItems

    for noteItem in xLocToNoteItems[xloc]:

        player.note_on(noteItem.note[0], noteItem.note[3], 1)

    offtime = xLocToRhythms[xloc]

    time.sleep(offtime)

    for noteItem in xLocToNoteItems[xloc]:

        player.note_off(noteItem.note[0], noteItem.note[3], 1)

===============>>#1 票数:1 已采纳

您的线程故意发出多个信号以在主线程中执行play()方法。 您的play方法必须在一段合理的时间内运行并阻塞主线程(例如,其中有一个time.sleep )。

您可能还需要将play代码也移到该线程中,但前提是您使用的MIDI库可以安全地从辅助线程中调用。 请注意,如果您打算从多个线程中调用该库,还应该检查该库是否是线程安全的。

  ask by Phillip translate from so

未解决问题?本站智能推荐:

1回复

PyQt-从QThread关闭QMessageBox

我正在一个项目中,尝试响应收到的MIDI数据,使QMesssageBox以“接受”条件退出。 MIDI输入库(pygame.midi)需要轮询输入以查看是否有数据到达,因此我启动了一个QThread来处理此问题,并在数据到达缓冲区时发出“ dataReceived”信号。 然后,我将此信号附
2回复

使用QThread的PyQt4多线程

在QThread调用xml.etree.ElementTree.fromstring()函数时, xml.etree.ElementTree.fromstring()一个无限的块。 此外,许多其他调用使QThread被阻止,如multiprocessing.Process() 。 重要的是说
1回复

pyqt4中的线程错误

我有问题。 我创建了线程,然后从那里打开新窗口。 但这行不通。 它不显示新窗口。 错误在哪里?
1回复

PyQt4是否需要多线程并写入串行

我的简单Python应用程序将PyQt4用于其GUI,单击QPushButton导致该应用程序通过serial发送消息。 GUI元素也经常更新。 问题:我不知道如何实现多线程。 没有多线程进程是否会导致应用程序在发送串行通信时响应性和一致性降低,特别是当GUI元素在发送串行消息的同时进
1回复

PyQt4中QWebView的多个线程

情况是这样的:我有一个加载特定URL的类,也有一个参数列表,需要将其发送到该URL。 我想使用线程“同时”加载该URL,换句话说,而不是加载一个QWebView,而不是加载它而不是加载另一个我想一次打开5个窗口的URL。 好的,所以现在的问题是,每个窗口的速度都会有所不同,因此我需要跟踪
2回复

PyQt4:传统的基于信号/插槽的多线程UI?

使用过多线程PyQt4应用程序的人吗? 我只是想知道,内置的信号/插槽机制与PyQt4框架的QtThread耦合是否比使用事件驱动的异步回调的标准Python线程(在我的代码中设计为以线程安全的方式处理UI组件)具有任何优势。 我正在寻找任何主要的速度或安全问题,任何特定的运行时异常或边
1回复

PyQt4在线程中等待来自GUI的用户输入

我有一个线程类“ MyThread”和我的主应用程序,简称为“ Gui”。 我想从线程类创建一些对象,但在本示例中,我仅创建了一个对象。 线程类完成一些工作,然后向Gui类发出信号,指示需要用户输入(此指示目前仅是更改按钮的文本)。 然后线程应等待用户输入(在这种情况下为单击按钮),然后继
1回复

将stdout和stderr从辅助线程重定向到PyQt4 QTextEdit

堆栈溢出。 再一次,我在一个迫切需要的时候来找你,在疯狂的边缘岌岌可危地摇摇欲坠。 这个问题 - 从标题中可以看出 - 是我在这里回答的其他几个问题的合并。 我有一个PyQt应用程序,我想将stdout和stderr流重新路由到我的GUI中的QTextEdit, 没有延迟 。 最
1回复

降低MIDI播放线程上的CPU

下面的函数在分离的std :: thread上运行。 代码本身是使用JUCE API(因此Array <>对象和MidiMessage)编写的。 我需要实时输出Midi消息,但不必经历循环条件,以免CPU过热。 有任何想法吗? 我对如何以不需要使用计时器进行持续检查
5回复

从C#背景实现Java中的线程

我正在尝试在我的Java GUI应用程序中实现多线程,以便在运行几个密集方法时释放接口。 我主要来自C#开发背景,并且在该环境中使用了几次Threads,并没有太多困难。 大致: C# 创建一个Thread对象 为它分配一个方法来开始 启动线程 现