Python Qt5 同时运行两个方法

问题描述 投票:0回答:1

我有一个 Qt 计时器,我想在录制时倒计时(使用声音设备包),我将附上下面的内容(我知道它离正确的东西还很远)。我一直在阅读有关多处理和线程的内容,我认为超时允许运行其他函数,但似乎记录函数在写入文件时保持不变,所以我有点困惑。任何建议都有帮助,谢谢!

class CountDown(QWidget):


    def __init__(self, name, index):
        super().__init__()
        self.initUI(name, index)
    
    def initUI(self, name, index):
        self.setWindowTitle("Timer for "+name)

        layout = QVBoxLayout()
        self.setLayout(layout)
        self.time_label = QLabel(self)
        layout.addWidget(self.time_label)
        self.setFixedWidth(500)
        self.setFixedHeight(500)

        # Create a QTimer that updates the time label every second
        timer = QTimer(self)
        self.current_time = 11
        timer.timeout.connect(lambda: self.update_time())
        timer.start(1000)  # Update every 1000 milliseconds (1 second)  

        print("START RECORDING" + name)
        self.record(index, name)
        self.show()

    #need to update time and record simultaneously
    def update_time(self):
        # Get the current time and set it on the label
        if(self.current_time==0): 
            self.close()
        self.current_time-=1
        print(self.current_time)
        self.time_label.setText(f"Current Time: {self.current_time}")

    #Takes in name selected from GUI and finds its index to use for audio device-> records for 1 second
    def record(self, index, name):
        #1 Microphone (USB Lavalier Microp, MME (2 in, 0 out)

        # Sample rate:
        fs = 44100
        # Duration of recording:
        seconds = 5
        myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=1, device=index)
        
        # Wait until recording is finished:
        sd.wait()

        print("STOPPED RECORDING" + name)


        # Save as WAV file:
        write(name+".wav", fs, myrecording)
        return name+".wav"
python multithreading audio multiprocessing python-sounddevice
1个回答
0
投票

我会在这里找到

threading
。并非所有 Qt 都是线程安全的,但如果您的录制线程不直接与 GUI 交互,则几乎不需要任何工作:

...
print("START RECORDING" + name)
self.recording_thread = threading.Thread(target = self.record, args = (index, name))
self.recording_thread.start()
self.show()
...

可以从线程发出信号,因此您可以创建一个可由线程触发的槽(回调)。如果您开始尝试从线程中执行类似 label.setText() 之类的操作,那么您就会遇到麻烦。

from PyQt6.QtCore import pyqtSignal, pyqtSlot #custom signals and slots
from PyQt6.QtWidgets import ...
from PyQt6 ...

import threading

class CountDown(QWidget):

    recording_done = pyqtSignal() #define a signal our thread will emit when done
    
    def __init__(self, name, index):
        super().__init__()
        self.initUI(name, index)
    
    def initUI(self, name, index):
        self.setWindowTitle("Timer for "+name)

        layout = QVBoxLayout()
        self.setLayout(layout)
        self.time_label = QLabel(self)
        layout.addWidget(self.time_label)
        self.setFixedWidth(500)
        self.setFixedHeight(500)
        self.setLayout(layout) #explicitly set the layout of the main widget rather than rely on parent-child relationship of label

        # Create a QTimer that updates the time label every second
        self.timer = QTimer(self)
        self.current_time = 11
        self.timer.timeout.connect(self.update_time) #you shouldn't need a lambda here, just pass the method
        self.timer.start(1000)  # Update every 1000 milliseconds (1 second)  

        print("START RECORDING" + name)
        self.recording_thread = threading.Thread(target=self.record, args=(index, name))
        self.recording_thread.start()
        
        self.recording_done.connect(self.on_recording_done)
        self.show()

    #need to update time and record simultaneously
    @pyqtSlot()
    def update_time(self):
        # Get the current time and set it on the label
        if(self.current_time==0): 
            self.timer.stop()
        self.current_time-=1
        print(self.current_time)
        self.time_label.setText(f"Current Time: {self.current_time}")
        
    @pyqtSlot()
    def on_recording_done(self):
        if self.timer.isActive():
            self.timer.stop()
        self.time_label.setText("recording done")

    #Takes in name selected from GUI and finds its index to use for audio device-> records for 1 second
    def record(self, index, name):
        #1 Microphone (USB Lavalier Microp, MME (2 in, 0 out)
        fs = 44100
        seconds = 5
        myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=1, device=index)
        sd.wait()
        print("STOPPED RECORDING" + name)
        write(name+".wav", fs, myrecording)
        self.recording_done.emit() #signal the Qt event loop in the main process
        #return name+".wav" #you can't get the return value from a thread. If you need to return some value, send it via signals and slots, or mutate a shared variable.

^注意:代码未经测试..阅读更改和理解。

© www.soinside.com 2019 - 2024. All rights reserved.