UOS Python+Qt5实现声卡回路测试

1.回路治具设计:

2.Ui界面:

文档说明:

1.读取声卡信息:
国产化读取的输入设装置名称:

Input(输入):alsa_input、analog-input-mic、analog-input-linein
Output(输出):alsa_output、analog-output-headphones、analog-output-headphones

`pactl list sources |grep alsa_input |grep $strInputDev |grep -iv echo-cancel |grep '名称'`  #查找默认输入设备

使用 sox 命令分析左右声道的这些值。以下是具体的操作步骤:
分解音频文件为左右声道: 假设你有一个立体声音频文件 stereo.wav,首先将其分解为左右声道的单声道文件
sox stereo.wav left.wav remix 1
sox stereo.wav right.wav remix 2

分析左声道: 使用 sox 命令分析左声道 left.wav 的统计信息:
sox left.wav -n stat 2>&1

分析右声道: 使用 sox 命令分析右声道 right.wav 的统计信息:
sox right.wav -n stat 2>&1

解释分析结果: 根据 sox 命令的输出,分别检查左声道和右声道的最大振幅、最小振幅、中线振幅、均方根振幅、粗略频率、最大变化量和音量调整值。确保这些值在合理范围内,并根据以下标准进行评估:
最大振幅和最小振幅:
o最大振幅应接近1,最小振幅应接近-1,但不应频繁达到这些极限值,以避免剪辑失真(clipping)。
中线振幅:
o该值应接近零,表示音频信号是平衡的,没有明显的直流偏移。
均方根振幅(RMS amplitude):
oRMS振幅是音频信号的平均功率,应在0.2到0.5之间,反映音频的总体音量水平。
粗略频率:
o粗略频率反映音频信号的主要频率成分。语音信号通常在300Hz到3400Hz之间,音乐信号频率范围更广。
最大变化量:
o如果最大变化量接近2,表示音频信号中存在很大的动态变化,可能是正常的,也可能表示信号中有突然的噪声或脉冲。
音量调整:
o表示音量是否需要调整。该值应接近1,如果远离1,可能需要进行音量归一化处理。

 

3.源代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'SoundTestWinFrm_New.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
import json
import configparser
import re
import subprocess
import sys
import os
import logging
import wave

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFrame
from PyQt5.QtWidgets import QApplication, QListWidget, QListWidgetItem
from PyQt5.QtGui import QColor
from datetime import datetime
#from subprocess import Popen
#import pyaudio
#import wave
#import librosa #pip install pyaudio librosa
#import numpy as np
import threading
import glob
from PyQt5.QtCore import QTimer, pyqtSignal
import signal


#pip install pyaudio librosa
#import pygame #pip install pygame
#import alsaaudio #pip install pyalsaaudio pip install pyalsaaudio
#sudo apt-get install portaudio19-dev
#pip install pyaudio librosa
#import pulsectl #pip install pulsectl
#apt-get install sox

class AnalysisThread(QtCore.QThread):
    def __init__(self, filename,type, parent=None):
        super(AnalysisThread, self).__init__(parent)
        self.filename = filename
        self.type=type
        self.is_running = True

    def run(self):
        while self.is_running:
            # 在这里执行音频分析
            self.parent().AnalysisSoundFile_Frequency(self.filename)
            self.parent().standard_frequency=int(self.parent().AnalysisSound_FrequencySample)#标准的频响
            self.stop()

    def stop(self):
        self.is_running = False # 或者使用更安全的停止逻辑

class RecordPlayThread(QtCore.QThread):
    finished_signal = QtCore.pyqtSignal()  # 添加完成信号
    set_default_output_device_signal = QtCore.pyqtSignal(str)
    set_default_input_device_signal = QtCore.pyqtSignal(str)
    #analysisSoundFile_Frequency_signal=QtCore.pyqtSignal(str)

    def __init__(self,output_filename,input_filename,duration_seconds,indevice_name,outdevice_name, parent=None):
        super(RecordPlayThread, self).__init__(parent)
        self.output_filename=output_filename
        self.input_filename=input_filename
        self.duration_seconds=duration_seconds#录放时间
        self.indevice_name=indevice_name
        self.outdevice_name=outdevice_name

        # 初始化其他变量
        if parent is not None:
            self.set_default_output_device_signal.connect(parent.set_default_port_and_volume)
            self.set_default_input_device_signal.connect(parent.set_default_port_and_volume)
            #self.analysisSoundFile_Frequency_signal.connect(parent.AnalysisSoundFile_Frequency)
        self.is_running = True

    def run(self):
        while self.is_running:# 执行录放音代码,确保在循环中频繁检查 self.is_running
            #检查录音文件是否存在,如果存在就删除
            if os.path.isfile(self.input_filename):
                os.remove(self.input_filename)
            #执行设置默认音频设备并同步录放音
            # 发出信号而不是直接调用方法
            self.set_default_output_device_signal.emit(self.outdevice_name)
            self.set_default_input_device_signal.emit(self.indevice_name)

            # 录音线程
            record_thread = threading.Thread(target=self.parent().rec_record_audio, args=(self.input_filename, self.duration_seconds))

            # 播放线程
            play_thread = threading.Thread(target=self.parent().play_audio_for_duration, args=(self.output_filename, self.duration_seconds))

            # 启动线程
            record_thread.start()
            play_thread.start()
            # 等待线程完成
            record_thread.join()
            play_thread.join()
            self.parent().AnalysisSoundFile_Frequency(self.input_filename)  # 解析声响

            # # 使用字典将测试端口映射到对应的属性和标准
            # test_ports = {
            #     'front_Left': ('front_Left', 'standard_Left'),
            #     'front_Right': ('front_Right', 'standard_Right'),
            #     'rear_Left': ('rear_Left', 'standard_Left'),
            #     'rear_Right': ('rear_Right', 'standard_Right')
            # }

            # 使用字典将测试端口映射到对应的属性和标准
            test_ports = {
                'front_Left': ('front_Left', 'standard_Left', 'Mean_norm_Left'),
                'front_Right': ('front_Right', 'standard_Right', 'Mean_norm_Right'),
                'rear_Left': ('rear_Left', 'standard_Left', 'Mean_norm_Left'),
                'rear_Right': ('rear_Right', 'standard_Right', 'Mean_norm_Right')
            }

            current_port = self.parent().currentTestPort
            epsilon = 0.0001  # 容差值
            mean_norm_epsilon = 0.12  # 上下限范围

            if current_port in test_ports:
                attribute, standard, mean_norm_standard = test_ports[current_port]
                standard_value = getattr(self.parent(), standard)
                mean_norm_standard_value = getattr(self.parent(), mean_norm_standard)

                # 检查 standard_frequency 是否在 standard_value ± epsilon 范围内
                is_within_range = abs(self.parent().AnalysisSound_FrequencySample - standard_value) < epsilon
                # 检查 Mean_norm 是否在 mean_norm_standard_value ± mean_norm_epsilon 范围内
                is_mean_norm_within_range = abs(self.parent().Mean_norm - mean_norm_standard_value) < mean_norm_epsilon

                # 结合两个条件进行判断
                is_within_range = is_within_range and is_mean_norm_within_range

                setattr(self.parent(), attribute, is_within_range)
            else:
                self.parent().infoListAddData(f"未知的测试端口: {current_port}", 3)

            self.finished_signal.emit()  # 线程完成时发射信号
            self.stop()

            # current_port = self.parent().currentTestPort
            # epsilon = 0.0001  # 容差值
            #
            # if current_port in test_ports:
            #     attribute, standard = test_ports[current_port]
            #     standard_value = getattr(self.parent(), standard)
            #
            #     # 检查standard_frequency是否在standard_value ± epsilon范围内
            #     is_within_range = abs(self.parent().AnalysisSound_FrequencySample - standard_value) < epsilon
            #     #self.parent().infoListAddData(f"AnalysisSound_FrequencySample值:{self.parent().AnalysisSound_FrequencySample}",3)
            #     #self.parent().infoListAddData(f"测试结果is_within_range: {is_within_range}", 3)
            #
            #     setattr(self.parent(), attribute, is_within_range)
            # else:
            #     self.parent().infoListAddData(f"未知的测试端口: {current_port}",3)
            # # else:
            # #     self.parent().infoListAddData(f'standard_frequency:{self.parent().standard_frequency},AnalysisSound_FrequencySample:{self.parent().AnalysisSound_FrequencySample} Check Fail!!',3)
            # self.finished_signal.emit()  # 线程完成时发射信号
            # self.stop()

    def stop(self):
        self.is_running = False  # 或者使用更安全的停止逻辑


class SoundTest(QWidget):
    updateTimer = pyqtSignal(bool)  # 定义一个信号

    # 定义颜色代码
    COLOR_SUCCESS = "\033[1;32;43m"
    COLOR_ERROR = "\033[1;31m"
    COLOR_RESET = "\033[0m"

    def __init__(self):
        super().__init__()

        # ... 现有的初始化代码 ...
        self.analysis_threads = []  # 存储所有的 AnalysisThread 实例
        self.record_play_threads = []  # 存储所有的 RecordPlayThread 实例

        # 设置环境变量
        os.environ["XDG_RUNTIME_DIR"] = "/run/user/{}".format(os.getuid())

        self.setupUi()
        self.testArgs = []  # 测试参数信息
        self.soundFile = []  # 音频文件
        self.itemName = ''  # 项目名称
        self.testStandardArgs = ''  # 测试标准参数
        self.logger = None
        self.config = None

        self.AnalysisSound_FrequencySample = 0#解析的音频频率标准值
        self.Mean_norm=0                      #平均归一化值(振幅绝对值的平均值,显示音频信号的平均能量水平)
        self.Device_1AnalysisSound_Frequency = 0  # 硬件设备1解析音频频率值
        self.Device_2AnalysisSound_Frequency = 0  # 硬件设备2解析音频频率值
        self.standard_Left=0.9999
        self.standard_Right=0.9999
        self.Mean_norm_Left=0.3040
        self.Mean_norm_Right=0.3040
        self.standard_frequency=0
        self.tempTestPassItem = 0  # 临时测试PASS项

        self.output_devices = []  # 输出音频设备名称
        self.input_devices = []  # 输入音频设备名称
        self.inputDevName=''     # 输入音频设备名称
        self.inputPort=''        # 输入音频端口
        self.outputDevName=''    # 输出音频设备名称
        self.outPort=''          # 输出音频端口
        self.testPortCount=0     # 测试接口数
        self.testPassItem=0      # 测试PASS项
        self.front_Device = False
        self.rear_Device = False

        self.front_Left=False  #前置左声道
        self.front_Right=False #前置右声道

        self.rear_Left=False   #后置左声道
        self.rear_Right=False  #后置右声道
        self.currentTestPort = 'front_Left'  # 默认测试接口包含front_Left(前置左声道)、front_Left(前置右声道)、rear_Left(后置左声道)、rear_Right(后置右声道)

        self.testStandardArgs = ''  # 测试标准参数

        self.loggerrinfo()  # 创建日志文件
        self.getitemName()  # 获取项目名称

        # 读取配置

        # 读取测试配置
        self.itemName = self.config.get('TestItemNameArrays', 'SoundTestName')
        self.itemFailSleepExit = int(self.config.get('TestItemWinFrmSleepExit', 'SoundTestName'))  # 项目测试Fail延时退出
        self.testArgs = self.readJsonInfo('./Conf/TestArgs.json')  # 读取测试参数信息

        #禁用HDMI
        self.disable_hdmi_audio()

        # 安装sox文件
        if self.install_sox() == True:
            if self.readJsonTestArgs() == True:
                self.ReadPortCount = int(self.testStandardArgs)  # 读取测试参数 #读取标准值

                # 读取音频文件
                self.soundFile.append('./' + self.config.get('SoundHd', 'F_L'))  # 高音左声道
                self.soundFile.append('./' + self.config.get('SoundHd', 'F_R'))  # 高音左声道

                if self.getTestPortCount() == True:
                    self.infoListAddData(f'读取音频:{str(self.testPortCount)}.个端口-实际配置端口:{self.ReadPortCount}', 1)

                    #self.lbl_MesInfo.setText('标准音频文件频率解析中...')
                    self.delete_wav_files('.')  # 删除目录生成的所有音频文件

                    #创建一个定时器来检查视频是否播放结束
                    self.timer_1 = QTimer(self)
                    self.timer_1.setInterval(1000)  # 每秒检查一次
                    self.timer_1.timeout.connect(self.check_Test)
                    self.timer_1.start()

                    # 连接信号到槽
                    self.updateTimer.connect(self.handleTimer)

                else:
                    self.infoListAddData(f'读取音频:{str(self.testPortCount)}.个端口-实际配置端口:{self.ReadPortCount}', 3)
        else:
            sys.exit(1)

    # 解析音频文件声响频率 fileName:文件名称
    def AnalysisSoundFile_Frequency(self,file_name):
        try:
            #self.find_and_kill_process()#结束录音线程
            # 加载音频文件
            audio_path = file_name
            if not os.path.isfile(audio_path):
                self.infoListAddData("Error: File does not exist.",3)
                sys.exit(1)
            else:
                # Call the sox command and capture the output
                command = f"sox {file_name} -n stat"
                process = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE, text=True)
                stderr = process.communicate()[1]

                # Parse the output to find the "Maximum amplitude" line
                for line in stderr.split('\n'):
                    if "Maximum amplitude" in line:
                        max_amplitude = line.split()[2]
                        self.AnalysisSound_FrequencySample = float(max_amplitude)
                        self.infoListAddData(f"Read File {file_name} Peak Frequency: {self.AnalysisSound_FrequencySample} Hz", 1)
                    elif "Mean    norm" in line:
                        meannorm=line.split()[2]
                        self.Mean_norm=float(meannorm)
                        self.infoListAddData(f"Read File {file_name} Mean norm:{self.Mean_norm}",1)
                        #return float(max_amplitude)
                        return True
            return False

        except Exception as e:
            self.infoListAddData(f"An error occurred: {e}",3)
            return None
    # def AnalysisSoundFile_Frequency(self, fileNme, type):
    #     try:
    #         # 加载音频文件
    #         audio_path = fileNme
    #         if not os.path.isfile(audio_path):
    #             print("Error: File does not exist.")
    #             sys.exit(1)
    #         else:
    #             # y, sr = librosa.load(audio_path)
    #             y, sr = self.load_wave_file(audio_path)
    #             print(f"Sample rate: {sr}, Data length: {len(y)}")
    #             # 获取频率和时间
    #             fft = np.fft.fft(y)
    #             magnitude = np.abs(fft)
    #             frequency = np.linspace(0, sr, len(magnitude))
    #
    #             # 只获取左侧频谱,因为右侧是对称的
    #             left_frequency = frequency[:int(len(frequency) / 2)]
    #             left_magnitude = magnitude[:int(len(frequency) / 2)]
    #
    #             # 找到最大幅度的频率
    #             max_magnitude = np.argmax(left_magnitude)
    #             peak_freq = left_frequency[max_magnitude]
    #
    #             # print(f"{fileNme} Peak Frequency: {peak_freq} Hz")
    #
    #             if type == 1:
    #                 self.AnalysisSound_FrequencySample = peak_freq
    #                 self.infoListAddData(f"Sample {fileNme} Peak Frequency: {peak_freq} Hz", 1)
    #             elif type == 2:
    #                 self.Device_1AnalysisSound_Frequency = peak_freq
    #                 self.infoListAddData(
    #                     f"Recordhw-{self.Recordhw[0]}-Playbackhw:{self.Playbackhw[0]} {fileNme} Peak Frequency: {peak_freq} Hz",
    #                     1)
    #             elif type == 3:
    #                 self.Device_2AnalysisSound_Frequency = peak_freq
    #                 self.infoListAddData(
    #                     f"Recordhw-{self.Recordhw[0]}-Playbackhw:{self.Playbackhw[0]} {fileNme} Peak Frequency: {peak_freq} Hz",
    #                     1)
    #     except Exception as e:
    #         self.showLog("AnalysisSoundFile_Frequency Err:" + str(e), False)
    #         self.infoListAddData(f"AnalysisSoundFile_Frequency Err:{str(e)}", 3)
    #         # sys.exit(1)

    def load_wave_file(self,file_path):
        try:
            with wave.open(file_path, 'rb') as wf:
                frames = wf.readframes(wf.getnframes())
                # Assuming audio is mono
                audio_data = np.frombuffer(frames, dtype=np.int16)
                return audio_data, wf.getframerate()
        except wave.Error as e:
            print(f"Error loading wave file: {str(e)}")
            sys.exit(1)

    # 启动多线程
    def RecordPlay_analysis_threads(self):
        try:
            self.lbl_MesInfo.setText('音频接口检测中...')
            # 创建多个线程
            self.threads = []
            if self.is_hdmi_disconnected():#判断当前设置是否接入有效,确认是前置还是后置
                self.lbl_MesInfo.setText('获取音频端口信息..')
                if self.DetectsTheCurrentTestDevice():  # 判断当前设置是否接入有效,确认是前置还是后置
                    #if self.get_audio_devices():  # 获取音频输入输出端口信息
                    if self.currentTestPort == 'front_Left' and self.front_Left == False:  # 前置左声道测试
                        self.lbl_MesInfo.setText('开始测试前置左声道测试..')
                        self.infoListAddData('开始测试前置左声道测试..', 1)
                        # 注意这里传递了 self 作为 parent
                        thread = RecordPlayThread(self.soundFile[0], 'front_RecordLeft.WAV', 1, self.inputDevName,self.outputDevName, self)
                        thread.finished_signal.connect(self.on_thread_finished)  # 连接信号
                        self.threads.append(thread)
                        self.record_play_threads.append(thread)
                        thread.start()
                    elif self.currentTestPort == 'front_Right' and self.front_Right == False:  # 前置右声道测试
                        self.lbl_MesInfo.setText('开始测试前置右声道测试..')
                        self.infoListAddData('开始测试前置右声道测试..', 1)
                        # 注意这里传递了 self 作为 parent
                        thread = RecordPlayThread(self.soundFile[1], 'front_RecordRight.WAV', 1, self.inputDevName,self.outputDevName, self)
                        thread.finished_signal.connect(self.on_thread_finished)  # 连接信号
                        self.threads.append(thread)
                        self.record_play_threads.append(thread)
                        thread.start()
                    elif self.currentTestPort == 'rear_Left' and self.rear_Left == False:  # 后置左声道测试
                        self.infoListAddData('开始测试后置左声道测试..', 1)
                        # 注意这里传递了 self 作为 parent
                        thread = RecordPlayThread(self.soundFile[0], 'rear_RecordLeft.WAV', 1, self.inputDevName,self.outputDevName, self)
                        thread.finished_signal.connect(self.on_thread_finished)  # 连接信号
                        self.threads.append(thread)
                        self.record_play_threads.append(thread)
                        thread.start()
                    elif self.currentTestPort == 'rear_Right' and self.rear_Right == False:  # 后置右声道测试
                        self.infoListAddData('开始测试后置右声道测试..', 1)
                        # 注意这里传递了 self 作为 parent
                        thread = RecordPlayThread(self.soundFile[1], 'rear_RecordRight.WAV', 1, self.inputDevName,self.outputDevName, self)
                        thread.finished_signal.connect(self.on_thread_finished)  # 连接信号
                        self.threads.append(thread)
                        self.record_play_threads.append(thread)
                        thread.start()
                    else:
                        self.updateTimer.emit(True)  # 启动时钟
                else:
                    self.updateTimer.emit(True)  # 启动时钟
            else:
                self.infoListAddData(f"音频回路测试,请移除HDMI连接!!", 3)
                self.updateTimer.emit(True)  # 启动时钟
        except Exception as e:
            self.infoListAddData(f"RecordPlay_analysis_threads Err:{str(e)}", 3)
            return False

    #查询与结束音频录音
    def find_and_kill_process(self):
        try:
            # Construct the command to find the process
            search_command = "ps -ef | grep -v grep | grep 'rec ./sample_1.wav'"
            process = subprocess.Popen(search_command, shell=True, stdout=subprocess.PIPE, text=True)
            stdout, _ = process.communicate()

            # Extract the process ID (PID)
            for line in stdout.split('\n'):
                if line:
                    pid = int(line.split()[1])
                    # Kill the process
                    os.kill(pid, signal.SIGKILL)
                    print(f"Process {pid} has been killed.")
                    self.infoListAddData(f"Process {pid} has been killed.", 1)
        except Exception as e:
            self.infoListAddData(f"An error occurred: {e}",3)

    # rec音频录制
    def rec_record_audio(self, output_filename, duration_seconds):
        try:
            # 调用rec命令录制音频
            # 检查文件是否存在
            if os.path.exists(output_filename):
                # 删除文件
                os.remove(output_filename)
            self.infoListAddData(f'音频录入--------------{output_filename}', 1)
            subprocess.run(['rec', output_filename, 'trim', '0', str(duration_seconds)], check=True)
            self.infoListAddData(f"Audio recorded to {output_filename}",2)
        except subprocess.CalledProcessError as e:
            self.infoListAddData(f"Error recording audio: {e}",3)

    # play 音频播放
    def play_audio_for_duration(self, input_filename, duration_seconds):
        try:
            # 使用play命令和trim效果播放特定时长的音频
            self.infoListAddData(f'音频播放--------------{input_filename}', 1)
            subprocess.run(['play', input_filename, 'trim', '0', str(duration_seconds)], check=True)
            self.infoListAddData(f"Played {duration_seconds} seconds of {input_filename}",2)
        except subprocess.CalledProcessError as e:
            self.infoListAddData(f"Error playing audio: {e}",3)

    def on_thread_finished(self):
        if all(not thread.isRunning() for thread in self.threads):
            self.handle_all_threads_finished()

    # 所有线程完成后执行的代码
    def handle_all_threads_finished(self):
        self.infoListAddData(f'测试完成的音频接口信息:inputPort-{self.inputDevName}-{self.inputPort},outputPort-{self.outputDevName}-{self.outPort}', 1)
        if self.currentTestPort=='front_Left':#前置左声测试道判断
            if self.front_Left==True:
                self.infoListAddData(f'前置音频左声道测试PASS', 2)
                self.lbl_Front_Out_Port.setText('PASS')
                self.lbl_Front_Out_Port.setStyleSheet('color:green;')
                self.testPassItem += 1
            else:
                self.infoListAddData(f'前置音频左声道测试FAIL', 3)
                self.lbl_Front_Out_Port.setText('FAIL')
                self.lbl_Front_Out_Port.setStyleSheet('color:red;')
        elif self.currentTestPort=='front_Right':#前置右声道测试判断
            if self.front_Right==True:
                self.infoListAddData(f'前置音频右声道测试PASS', 2)
                self.lbl_Front_In_Port.setText('PASS')
                self.lbl_Front_In_Port.setStyleSheet('color:green;')
                self.testPassItem += 1
            else:
                self.infoListAddData(f'前置音频右声道测试FAIL', 3)
                self.lbl_Front_In_Port.setText('FAIL')
                self.lbl_Front_In_Port.setStyleSheet('color:red;')
        elif self.currentTestPort=='rear_Left':
            if self.rear_Left==True:
                self.infoListAddData(f'后置音频左声道测试PASS', 2)
                self.lbl_Rear_Out_Port.setText('PASS')
                self.lbl_Rear_Out_Port.setStyleSheet('color:green;')
                self.testPassItem += 1
            else:
                self.infoListAddData(f'后置音频左声道测试FAIL', 3)
                self.lbl_Rear_Out_Port.setText('FAIL')
                self.lbl_Rear_Out_Port.setStyleSheet('color:red;')
        elif self.currentTestPort=='rear_Right':
            if self.rear_Right==True:
                self.infoListAddData(f'后置音频右声道测试PASS', 2)
                self.lbl_Rear_In_Port.setText('PASS')
                self.lbl_Rear_In_Port.setStyleSheet('color:green;')
                self.testPassItem += 1
            else:
                self.infoListAddData(f'后置音频右声道测试FAIL', 3)
                self.lbl_Rear_In_Port.setText('FAIL')
                self.lbl_Rear_In_Port.setStyleSheet('color:red;')

        self.updateTimer.emit(True)  # 启动时钟

    # 定义判断音频是否完成测试
    def get_audio_devices(self):
        try:
            # 检查输出设备是否使用过
            if self.outputDevName in self.output_devices:
                return False
            # 检查输入设备是否使用过
            if self.inputDevName in self.input_devices:
                return False
            return True
        except Exception as e:
            self.infoListAddData(f"get_audio_devices Err: {str(e)}", 3)
            return False

    # 定义触发器
    def handleTimer(self, start):
        if start:
            self.timer_1.start()
        else:
            self.timer_1.stop()

    # 校验是否完成测试
    def check_Test(self):
        try:
            if self.testPassItem==4:#判断是否PASS
                self.lbl_MesInfo.setText('音频测试PASS')
                self.updateJsonTestArgs(self.itemName,str(self.testPassItem),'PASS')
                sys.exit(0)
            else:
                #self.infoListAddData(f'音频已完成{self.testPassItem}项测试', 1)
                self.updateTimer.emit(False)  # 发射信号以停止定时器
                self.RecordPlay_analysis_threads()
        except Exception as e:
            #self.showLog(f"check_Test Err:{e}", False)
            self.infoListAddData(f"check_Test Err:{str(e)}",3)
            return False

    #查检是否边接了HDMI
    def is_hdmi_disconnected(self):
        # 定义设备名称变量
        dev_name_values = ["HDMI", "HDMI-1", "HDMI-2", "HDMI-3"]

        # 执行xrandr命令并获取输出
        xrandr_output = subprocess.getoutput("xrandr")

        # 检查每个设备的连接状态
        hdmi_connected = any(f"{dev} connected" in xrandr_output for dev in dev_name_values)

        g_n_machine_type = 5  # 示例值,根据实际情况设置

        # 判断连接状态
        if hdmi_connected:
            return False

        return True

    #设置麦克风和扬声器的端口为默认及音量大小
    def set_default_port_and_volume(self):
        self.inputDevName = self.get_input_device()
        #self.infoListAddData(f"输入设备DevName: {self.inputDevName}",1)
        if self.inputDevName:
            self.inputPort = self.get_input_port(self.inputDevName)
            #self.infoListAddData(f"输入端口InputPort: {self.inputPort}", 1)
            self.run_command(f"pactl set-default-source {self.inputDevName}")
            self.run_command(f"pactl set-source-port {self.inputDevName} {self.inputPort}")
            self.run_command(f"pactl set-source-mute {self.inputDevName} 0")
            self.run_command(f"pactl set-source-volume {self.inputDevName} 60%")
        else:
            return False
        self.outputDevName = self.get_output_device()
        #self.infoListAddData(f"输出设备DevName: {self.outputDevName}",1)
        if self.outputDevName:
            self.outPort = self.get_output_port(self.outputDevName)
            #self.infoListAddData(f"输出端口outPort: {self.outPort}", 1)
            self.run_command(f"pactl set-default-sink {self.outputDevName}")
            self.run_command(f"pactl set-sink-port {self.outputDevName} {self.outPort}")
            self.run_command(f"pactl set-sink-mute {self.outputDevName} 0")
            self.run_command(f"pactl set-sink-volume {self.outputDevName} 100%")
        else:
            return  False
        return True

    # 检测当前测试设备并进行判断
    def DetectsTheCurrentTestDevice(self):
        try:
            if self.set_default_port_and_volume():
                if 'rear' in self.inputPort:  # 判断当前为后置接口
                    #self.infoListAddData("后置音频:" + self.inputPort, 1)
                    if self.rear_Left==False:#设置当前为,后置左声道测试
                        #print('rear', len(self.readTestAudioDevice))
                        self.currentTestPort = 'rear_Left'
                        self.label_2.setStyleSheet('')  # 前置端口背景颜色设置为默认透明
                        self.label_3.setStyleSheet("background-color: lightgreen;")  # 后置端口背景色设置为浅绿色
                        self.lbl_MesInfo.setText('后置音频左声道测试..')
                        return True
                    elif self.rear_Right==False:#设置当前为,后置右声道测试
                        self.currentTestPort = 'rear_Right'
                        self.label_2.setStyleSheet('')  # 前置端口背景颜色设置为默认透明
                        self.label_3.setStyleSheet("background-color: lightgreen;")  # 后置端口背景色设置为浅绿色
                        self.lbl_MesInfo.setText('后置音频右声道测试..')
                        return True
                elif 'front' in self.inputPort:  # 判断当前为前置接口
                    #print('front', len(self.readTestAudioDevice))
                    #self.infoListAddData("前置音频:" + self.inputPort, 1)
                    if self.front_Left==False:#设置当前为,前置左声道测试
                        self.currentTestPort = 'front_Left'
                        self.label_2.setStyleSheet('background-color: lightgreen;')  # 前置端口背景颜色设置为浅绿色
                        self.label_3.setStyleSheet("")  # 后置端口背景色设置默认透明
                        self.lbl_MesInfo.setText('前置音频接口测试')
                        return True
                    elif self.front_Right==False:#设置当前为,前置右声道测试
                        self.currentTestPort = 'front_Right'
                        self.label_2.setStyleSheet('background-color: lightgreen;')  # 前置端口背景颜色设置为浅绿色
                        self.label_3.setStyleSheet("")  # 后置端口背景色设置默认透明
                        self.lbl_MesInfo.setText('前置音频接口测试')
                        return True
                return False
            else:
                return False
        except Exception as e:
            #self.ShowLog(f"DetectsTheCurrentTestDevice Err:{e}", False)
            self.infoListAddData(f"DetectsTheCurrentTestDevice Err:{str(e)}", 3)
            return False

    #执行命令行
    def run_command(self,command):
        result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        if result.returncode != 0:
            #self.infoListAddData(f"Error running command: {command}",3)
            #self.infoListAddData(result.stderr,3)
            return None
        return result.stdout.strip()

    #获取输入硬件
    def get_input_device(self):
        try:
            cmd_input_device = "pactl list sources | grep -E 'alsa_input|analog-input-mic|analog-input-linein' | grep -iv echo-cancel | grep '名称'"
            strDevFullName = self.run_command(cmd_input_device)
            strDevName = strDevFullName.split(":")[-1].strip() if ':' in strDevFullName else ""
            return strDevName
        except Exception as e:
            return None

    # 获取输入端口
    def get_input_port(self, strDevName):
        if not strDevName:
            return None
        # 列出所有 sources 的详细信息并过滤出包含设备名称的部分
        result = subprocess.run(['pactl', 'list', 'sources'], stdout=subprocess.PIPE, text=True)
        # 获取命令输出
        content = result.stdout
        # 定义正则表达式模式,匹配指定的 sink_name
        pattern = rf"名称:{re.escape(strDevName)}.*?活动端口:(.*?)\n"
        match = re.search(pattern, content, re.DOTALL)

        if match:
            active_port = match.group(1).strip()
            return active_port
        else:
            return None
        # cmd_input_port = f"pactl list sources | grep '活动端口'"
        # strInputPortLine = self.run_command(cmd_input_port)
        # # 从活动端口行中提取端口名称
        # strInputPort = strInputPortLine.split(":")[-1].strip() if ':' in strInputPortLine else ""
        # #self.infoListAddData(f"活动端口行: {strInputPortLine}", 1)
        # return strInputPort

    #获取输出硬件
    def get_output_device(self):
        try:
            cmd_output_device = "pactl list sinks | grep -E 'alsa_output|analog-output-headphones|analog-output-lineout' | grep -iv 'hdmi' | grep -iv 'echo-cancel' | grep '名称'"
            strDevFullName = self.run_command(cmd_output_device)
            strDevName = strDevFullName.split(":")[-1].strip() if ':' in strDevFullName else ""
            return strDevName
        except Exception as e:
            return None

    # 获取当前产测试端口测试
    def getTestPortCount(self):
        try:
            # 运行命令并获取输出
            process = subprocess.Popen('pactl list cards | grep "available"', stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE, shell=True, encoding='utf-8')
            # 逐行读取输出
            while True:
                output = process.stdout.readline()
                if output == '' and process.poll() is not None:
                    break
                if 'hdmi' not in output.lower():
                    self.testPortCount += 1
            # print(self.ReadPortCount,self.testPortCount)
            if int(self.ReadPortCount) == self.testPortCount:
                return True
            else:
                return False
        except Exception as e:
            self.showLog(f"GetTestPortCount Err:{e}", False)
            self.infoListAddData(f"GetTestPortCount Err:{str(e)}", 3)
            return False

    #获取输出端口
    def get_output_port(self,strDevName):
        if not strDevName:
            return ""
        # 执行 pactl list sinks 命令
        result = subprocess.run(['pactl', 'list', 'sinks'], stdout=subprocess.PIPE, text=True)
        # 获取命令输出
        content = result.stdout
        # 定义正则表达式模式,匹配指定的 sink_name
        pattern = rf"名称:{re.escape(strDevName)}.*?活动端口:(.*?)\n"
        match = re.search(pattern, content, re.DOTALL)

        if match:
            active_port = match.group(1).strip()
            return active_port
        else:
            return None
        # cmd_output_port = f"pactl list sinks | grep -A 20 {strDevName} | grep 'ports:' -A 1 | tail -n 1 | awk '{{print $1}}'"
        # strOutputPort = self.run_command(cmd_output_port)
        # return strOutputPort

    # messtr:信息字符串 infoType:信息类型 1=提示信息,2=测试PASS信息,3=测试FAIL信息
    def infoListAddData(self, messtr, infoType):
        try:
            # 获取当前时间
            current_time = datetime.now()

            # 格式化日期和时间
            formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")

            # item = QListWidgetItem(messtr)
            item = QListWidgetItem(f"{formatted_time} - {messtr}")
            if infoType == 1:
                item.setForeground(QColor("blue"))
            elif infoType == 2:
                item.setForeground(QColor("green"))
            elif infoType == 3:
                item.setForeground(QColor("red"))
            # self.ltwgt_Log.addItem(year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second+' '+item)

            self.ltwgt_Log.addItem(item)
            # 将光标移动到最底部以显示最新消息
            self.ltwgt_Log.scrollToBottom()
            # self.ltwgt_Log.addItem(item)
            # self.ltwgt_Log.setEnabled(False)
            # # 将光标移动到最底部
            # self.ltwgt_Log.scrollToBottom()
        except Exception as e:
            self.showLog("infoListAddData Err:" + str(e), False)
            sys.exit(1)

    # 删除当前目录下所有*.wav文件
    def delete_wav_files(self, directory):
        # 构造当前目录中所有.wav文件的路径模式
        path_pattern = os.path.join(directory, '*.wav')

        # 使用glob模块找到所有匹配的文件
        wav_files = glob.glob(path_pattern)

        # 遍历所有找到的.wav文件并删除它们
        for file_path in wav_files:
            try:
                os.remove(file_path)
                self.infoListAddData(f"Deleted: {file_path}",1)
            except Exception as e:
                self.infoListAddData(f"Error deleting {file_path}: {e}",3)

    # 禁用HDMI音频输出
    def disable_hdmi_audio(self):
        try:
            # 获取所有 sinks 的列表
            result = subprocess.run(['pactl', 'list', 'short', 'sinks'], capture_output=True, text=True, check=True)
            lines = result.stdout.split('\n')

            # 查找 HDMI 设备
            hdmi_sink = None
            for line in lines:
                if 'hdmi' in line.lower():
                    hdmi_sink = line.split('\t')[1]
                    break

            # 禁用找到的 HDMI 设备
            if hdmi_sink:
                subprocess.run(['pactl', 'set-sink-mute', hdmi_sink, '1'], check=True)
                self.infoListAddData("HDMI audio output has been disabled.",1)
            else:
                self.infoListAddData("No HDMI audio output found.",1)

        except subprocess.CalledProcessError as e:
            self.infoListAddData(f"Error disabling HDMI audio output: {e}",1)

    # 安装sox文件
    # def install_sox(self, deb_directory='./Installation_Package/sox/'):
    def install_sox(self, directory='./Installation_Package/sox/'):
        """
        Install all .deb packages in a specified directory using dpkg, only if 'sox' is not already installed.
        Returns True if the installation was performed, False if 'sox' was already installed or if an error occurred.

        Args:
        directory (str): The path to the directory containing .deb files.

        Returns:
        bool: True if installation was executed, False otherwise.
        """
        print("Checking if 'sox' is already installed...")
        check_sox = subprocess.run(['dpkg', '-s', 'sox'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        if 'install ok installed' in check_sox.stdout.decode():
            print("'sox' is already installed. No installation necessary.")
            return True  # sox已安装,无需执行安装命令

        print("'sox' is not installed. Proceeding with installation...")
        # 如果sox未安装,则安装.deb文件
        command = 'sudo dpkg -i *.deb'
        result = subprocess.run(command, shell=True, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        if result.returncode == 0:
            return True
        else:
            print(f"Installation failed with error: {result.stderr.decode()}")
            return False

    # 定义一个函数使得函数窗口居中显示
    def center(self):
        # 获取屏幕尺寸
        screen_geometry = app.desktop().availableGeometry()
        # 计算窗口居中位置
        x = (screen_geometry.width() - self.width()) // 2
        y = (screen_geometry.height() - self.height()) // 2
        # 设置窗口位置
        self.move(x, y)

    # 更新测试参数json,itemName:项目名称,readValue:读取值,testResult:测试结果
    def updateJsonTestArgs(self, itemName, readValue, testResult):
        try:
            self.testArgs = self.readJsonInfo('./Conf/TestArgs.json')
            if self.testArgs is None:
                raise Exception("Failed to read configuration, aborting update.")

            for js in self.testArgs:
                if itemName in js['ItemScript']:
                    js['Read'] = readValue
                    js['TestResult'] = testResult

            with open("./Conf/TestArgs.json", "w") as write_file:
                json.dump(self.testArgs, write_file, indent=4)  # Use indent for pretty printing

            return True
        except Exception as e:
            self.showLog(f"Update TestArgs.json ItemName: {itemName} Info Err: {str(e)}", False)
            sys.exit(1)

    # 读取json信息,fileName:文件名称
    def readJsonInfo(self, fileName):
        try:
            if os.path.exists(fileName):
                f = open(fileName, 'r', encoding='utf-8')
            return json.loads(f.read())
        except Exception as e:
            self.showLog("Read " + fileName + " Err:" + str(e), False)
            sys.exit(1)

    # 读取项目参数信息,itemName:项目名称
    def readJsonTestArgs(self):
        try:
            self.testArgs = self.readJsonInfo('./Conf/TestArgs.json')
            for js in self.testArgs:
                print(self.itemName, js['ItemScript'])
                if self.itemName in js['ItemScript']:
                    self.testStandardArgs = js['Standard']
                    return True
            return False
        except Exception as e:
            self.showLog("Read TestArgs.json ItemName:" + self.itemName + " Info Err:" + str(e), False)
            sys.exit(1)

    # 获取项目名称
    def getitemName(self):
        try:
            # 获取当前执行文件的完整路径
            full_path = sys.argv[0]
            # 从完整路径中提取文件名
            file_name = os.path.basename(full_path)
            self.itemName = file_name  # 项目名称
        except Exception as e:
            self.showLog(f'Get Item Name Err:{str(e)}', False)

    # 日志信息
    def loggerrinfo(self):
        try:
            # 确保日志文件的目录存在
            log_directory = './log'
            if not os.path.exists(log_directory):
                os.makedirs(log_directory)

            self.config = configparser.ConfigParser()  # 创建配置解析器对象
            self.config.read('./Conf/config.conf', encoding='utf-8')  # 读取配置文件,如果配置文件不存在则创建
            # 生成日志信息
            self.logger = logging.getLogger('my_logger')  # 创建日志记录器
            self.logger.setLevel(logging.DEBUG)  # 设置日志级别为DEBUG
            file_handler = logging.FileHandler(f'{log_directory}/log.txt')  # 创建文件处理器
            formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')  # 创建格式化器
            file_handler.setFormatter(formatter)  # 将格式化器设置到文件处理器
            self.logger.addHandler(file_handler)  # 将文件处理器添加到日志记录器
        except Exception as e:
            self.showLog(f'Create logger_info Error: {str(e)}', False)

    # 打印的信息
    def showLog(self, log, isPass):
        try:
            if isPass == True:
                print("\033[1;32;43m" + str(log) + " \033[0m")
                self.lbl_MesInfo.setStyleSheet("color:green;")
                self.logger.info(str(log))
            else:
                print("\033[1;31m" + str(log) + " \033[0m")
                self.lbl_MesInfo.setStyleSheet("color:green;")
                self.logger.error(str(log))
            self.lbl_MesInfo.setText(str(log))
        except Exception as e:
            print("\033[1;31m" + str(e) + " \033[0m")
            sys.exit(1)

    #初始化UI
    def setupUi(self):
        self.setObjectName("Form")
        self.resize(1000, 900)

        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("IMAGE/Sound.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        self.gridLayout = QtWidgets.QGridLayout(self)
        self.gridLayout.setObjectName("gridLayout")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.lbl_logo = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_logo.setFont(font)
        self.lbl_logo.setText("")
        self.lbl_logo.setPixmap(QtGui.QPixmap("IMAGE/logo.jpg"))
        self.lbl_logo.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_logo.setObjectName("lbl_logo")
        self.verticalLayout_3.addWidget(self.lbl_logo)
        self.lbl_Title = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.lbl_Title.setFont(font)
        self.lbl_Title.setStyleSheet("background-color: rgb(85, 255, 127);\n"
"color: rgb(85, 85, 127);")
        self.lbl_Title.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Title.setObjectName("lbl_Title")
        self.verticalLayout_3.addWidget(self.lbl_Title)
        self.horizontalLayout.addLayout(self.verticalLayout_3)
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.label_2 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.label_2.setFont(font)
        self.label_2.setStyleSheet("background-color: rgb(170, 170, 127);\n"
"color: rgb(255, 255, 255);")
        self.label_2.setAlignment(QtCore.Qt.AlignCenter)
        self.label_2.setObjectName("label_2")
        self.verticalLayout_4.addWidget(self.label_2)
        self.label_6 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.label_6.setFont(font)
        self.label_6.setStyleSheet("background-color: rgb(170, 170, 0);\n"
"color: rgb(255, 255, 255);")
        self.label_6.setAlignment(QtCore.Qt.AlignCenter)
        self.label_6.setObjectName("label_6")
        self.verticalLayout_4.addWidget(self.label_6)
        self.label_3 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.label_3.setFont(font)
        self.label_3.setStyleSheet("background-color: rgb(170, 170, 0);\n"
"color: rgb(255, 255, 255);")
        self.label_3.setAlignment(QtCore.Qt.AlignCenter)
        self.label_3.setObjectName("label_3")
        self.verticalLayout_4.addWidget(self.label_3)
        self.verticalLayout_4.setStretch(0, 20)
        self.verticalLayout_4.setStretch(1, 40)
        self.verticalLayout_4.setStretch(2, 40)
        self.horizontalLayout.addLayout(self.verticalLayout_4)
        self.verticalLayout_5 = QtWidgets.QVBoxLayout()
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.label_4 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.label_4.setFont(font)
        self.label_4.setStyleSheet("background-color: rgb(170, 170, 127);\n"
"color: rgb(255, 255, 255);")
        self.label_4.setAlignment(QtCore.Qt.AlignCenter)
        self.label_4.setObjectName("label_4")
        self.verticalLayout_5.addWidget(self.label_4)
        self.verticalLayout_8 = QtWidgets.QVBoxLayout()
        self.verticalLayout_8.setObjectName("verticalLayout_8")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.verticalLayout_9 = QtWidgets.QVBoxLayout()
        self.verticalLayout_9.setObjectName("verticalLayout_9")
        self.label_7 = QtWidgets.QLabel(self)
        self.label_7.setStyleSheet("background-color: rgb(255, 85, 0);\n"
"color: rgb(85, 85, 127);")
        self.label_7.setAlignment(QtCore.Qt.AlignCenter)
        self.label_7.setObjectName("label_7")
        self.verticalLayout_9.addWidget(self.label_7)
        self.lbl_Front_Out_Port = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Front_Out_Port.setFont(font)
        self.lbl_Front_Out_Port.setStyleSheet("color: rgb(170, 170, 127);")
        self.lbl_Front_Out_Port.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Front_Out_Port.setObjectName("lbl_Front_Out_Port")
        self.verticalLayout_9.addWidget(self.lbl_Front_Out_Port)
        self.horizontalLayout_3.addLayout(self.verticalLayout_9)
        self.verticalLayout_10 = QtWidgets.QVBoxLayout()
        self.verticalLayout_10.setObjectName("verticalLayout_10")
        self.label_10 = QtWidgets.QLabel(self)
        self.label_10.setStyleSheet("background-color: rgb(255, 85, 0);\n"
"color: rgb(85, 85, 127);")
        self.label_10.setAlignment(QtCore.Qt.AlignCenter)
        self.label_10.setObjectName("label_10")
        self.verticalLayout_10.addWidget(self.label_10)
        self.lbl_Front_In_Port = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Front_In_Port.setFont(font)
        self.lbl_Front_In_Port.setStyleSheet("color: rgb(170, 170, 127);")
        self.lbl_Front_In_Port.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Front_In_Port.setObjectName("lbl_Front_In_Port")
        self.verticalLayout_10.addWidget(self.lbl_Front_In_Port)
        self.horizontalLayout_3.addLayout(self.verticalLayout_10)
        self.verticalLayout_8.addLayout(self.horizontalLayout_3)
        self.verticalLayout_5.addLayout(self.verticalLayout_8)
        self.verticalLayout_5.setStretch(0, 20)
        self.verticalLayout_5.setStretch(1, 80)
        self.horizontalLayout.addLayout(self.verticalLayout_5)
        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.label_5 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.label_5.setFont(font)
        self.label_5.setStyleSheet("background-color: rgb(170, 170, 127);\n"
"color: rgb(255, 255, 255);")
        self.label_5.setAlignment(QtCore.Qt.AlignCenter)
        self.label_5.setObjectName("label_5")
        self.verticalLayout_6.addWidget(self.label_5)
        self.verticalLayout_7 = QtWidgets.QVBoxLayout()
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.verticalLayout_11 = QtWidgets.QVBoxLayout()
        self.verticalLayout_11.setObjectName("verticalLayout_11")
        self.label_12 = QtWidgets.QLabel(self)
        self.label_12.setStyleSheet("background-color: rgb(255, 85, 0);\n"
"color: rgb(85, 85, 127);")
        self.label_12.setAlignment(QtCore.Qt.AlignCenter)
        self.label_12.setObjectName("label_12")
        self.verticalLayout_11.addWidget(self.label_12)
        self.lbl_Rear_Out_Port = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Rear_Out_Port.setFont(font)
        self.lbl_Rear_Out_Port.setStyleSheet("color: rgb(170, 170, 127);")
        self.lbl_Rear_Out_Port.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Rear_Out_Port.setObjectName("lbl_Rear_Out_Port")
        self.verticalLayout_11.addWidget(self.lbl_Rear_Out_Port)
        self.horizontalLayout_4.addLayout(self.verticalLayout_11)
        self.verticalLayout_12 = QtWidgets.QVBoxLayout()
        self.verticalLayout_12.setObjectName("verticalLayout_12")
        self.label_13 = QtWidgets.QLabel(self)
        self.label_13.setStyleSheet("background-color: rgb(255, 85, 0);\n"
"color: rgb(85, 85, 127);")
        self.label_13.setAlignment(QtCore.Qt.AlignCenter)
        self.label_13.setObjectName("label_13")
        self.verticalLayout_12.addWidget(self.label_13)
        self.lbl_Rear_In_Port = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.lbl_Rear_In_Port.setFont(font)
        self.lbl_Rear_In_Port.setStyleSheet("color: rgb(170, 170, 127);")
        self.lbl_Rear_In_Port.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_Rear_In_Port.setObjectName("lbl_Rear_In_Port")
        self.verticalLayout_12.addWidget(self.lbl_Rear_In_Port)
        self.horizontalLayout_4.addLayout(self.verticalLayout_12)
        self.verticalLayout_7.addLayout(self.horizontalLayout_4)
        self.verticalLayout_6.addLayout(self.verticalLayout_7)
        self.verticalLayout_6.setStretch(0, 20)
        self.verticalLayout_6.setStretch(1, 80)
        self.horizontalLayout.addLayout(self.verticalLayout_6)
        self.horizontalLayout.setStretch(0, 30)
        self.horizontalLayout.setStretch(1, 20)
        self.horizontalLayout.setStretch(2, 25)
        self.horizontalLayout.setStretch(3, 25)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.lbl_MesInfo = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(22)
        font.setBold(True)
        font.setWeight(75)
        self.lbl_MesInfo.setFont(font)
        self.lbl_MesInfo.setStyleSheet("background-color: rgb(0, 170, 127);\n"
"color: rgb(255, 170, 0);")
        self.lbl_MesInfo.setAlignment(QtCore.Qt.AlignCenter)
        self.lbl_MesInfo.setObjectName("lbl_MesInfo")
        self.horizontalLayout_2.addWidget(self.lbl_MesInfo)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.label = QtWidgets.QLabel(self)
        self.label.setStyleSheet("background-color: rgb(170, 170, 127);\n"
"color: rgb(255, 255, 255);")
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.ltwgt_Log = QtWidgets.QListWidget(self)
        self.ltwgt_Log.setObjectName("ltwgt_Log")
        self.verticalLayout_2.addWidget(self.ltwgt_Log)
        self.verticalLayout.addLayout(self.verticalLayout_2)
        self.verticalLayout.setStretch(0, 20)
        self.verticalLayout.setStretch(1, 8)
        self.verticalLayout.setStretch(2, 2)
        self.verticalLayout.setStretch(3, 70)
        self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)

        self.retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowCloseButtonHint)  # 只显示最小化按钮和关闭按钮

    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("Form", "SoundTestWinFrm"))
        self.lbl_Title.setText(_translate("Form", "音频回路测试"))
        self.label_2.setText(_translate("Form", "项目名称"))
        self.label_6.setText(_translate("Form", "端口信息"))
        self.label_3.setText(_translate("Form", "测试结果"))
        self.label_4.setText(_translate("Form", "前置"))
        self.label_7.setText(_translate("Form", "左声道"))
        self.lbl_Front_Out_Port.setText(_translate("Form", "N/A"))
        self.label_10.setText(_translate("Form", "右声道"))
        self.lbl_Front_In_Port.setText(_translate("Form", "N/A"))
        self.label_5.setText(_translate("Form", "后置"))
        self.label_12.setText(_translate("Form", "左声道"))
        self.lbl_Rear_Out_Port.setText(_translate("Form", "N/A"))
        self.label_13.setText(_translate("Form", "右声道"))
        self.lbl_Rear_In_Port.setText(_translate("Form", "N/A"))
        self.lbl_MesInfo.setText(_translate("Form", "Wait"))
        self.label.setText(_translate("Form", "日志"))

    # 手动关闭窗口
    def closeEvent(self, event):
        # 创建一个消息框,上面有两个按钮:“是”和“否”
        # reply = QMessageBox.question(self, '退出', "你确定要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

        # 如果用户点击了“是”,则执行event.accept()来关闭窗口
        # if reply == QMessageBox.Yes:
        #    event.accept()
        #    sys.exit(1)
        # else:
        # 如果用户点击了“否”,则忽略event,不关闭窗口
        #    event.ignore()
        sys.exit(1)


if __name__=='__main__':
    app=QApplication(sys.argv)
    win=SoundTest()
    win.center()  # 居中
    win.show()
    sys.exit(app.exec_())

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值