第一次提交
1、hpi的可用代码; 2、修复了多次点击曝光后,福亮度数据错误的问题; 3、定标方式为大的蓝菲积分球的标准能量曲线,而不是基于asd的能量曲线;
This commit is contained in:
0
library/__init__.py
Normal file
0
library/__init__.py
Normal file
514
library/config.py
Normal file
514
library/config.py
Normal file
@ -0,0 +1,514 @@
|
||||
# 标准库
|
||||
import traceback, os
|
||||
|
||||
# 三方库
|
||||
import configparser
|
||||
from PyQt5.QtCore import QObject, pyqtSignal
|
||||
|
||||
# 自己写的库
|
||||
from library.dir_manager import DirManager
|
||||
|
||||
|
||||
# class ConfigFile():
|
||||
# def __init__(self):
|
||||
# self.base_dir = get_path()
|
||||
#
|
||||
# self.log_dir = self.base_dir + '//log'
|
||||
# self.create_directory(self.log_dir)
|
||||
#
|
||||
# self.corning_config_file = self.log_dir + '//corning_config.ini'
|
||||
#
|
||||
# self.read_config_file()
|
||||
#
|
||||
# self.signals = WorkerSignals()
|
||||
# self.signals.image_signal.connect(self.image_record_param_changed)
|
||||
# self.signals.spectral_signal.connect(self.spectral_record_param_changed)
|
||||
#
|
||||
#
|
||||
# # 查看是否存在保存光谱和影像文件的目录,如果没有就创建
|
||||
# def create_directory(self, directory):
|
||||
# if not os.path.exists(directory):
|
||||
# print('创建文件夹:', directory)
|
||||
# os.makedirs(directory)
|
||||
#
|
||||
# # 读取配置文件,如果没有就创建
|
||||
# def read_config_file(self):
|
||||
# if os.path.exists(self.corning_config_file):
|
||||
# '''
|
||||
# 如果存在配置文件,就从配置文件中读取软件配置信息
|
||||
# '''
|
||||
# print('配置文件存在!')
|
||||
#
|
||||
# config = configparser.ConfigParser()
|
||||
# config.read(self.corning_config_file)
|
||||
#
|
||||
# self.image_dir = config.get('image_record_param', 'image_dir')
|
||||
# self.create_directory(self.image_dir)
|
||||
# self.default_image_name = config.get('image_record_param', 'default_image_name')
|
||||
# self.framerate = int(config.get('image_record_param', 'framerate'))
|
||||
# self.exposure_time = int(config.get('image_record_param', 'exposure_time'))
|
||||
# self.gain = int(float(config.get('image_record_param', 'gain')))
|
||||
# self.frame_number = int(config.get('image_record_param', 'frame_number'))
|
||||
#
|
||||
# self.spectral_dir = config.get('spectral_record_param', 'spectral_dir')
|
||||
# self.create_directory(self.spectral_dir)
|
||||
# self.default_spectral_name = config.get('spectral_record_param', 'default_spectral_name')
|
||||
#
|
||||
# self.binning = int(config.get('bin', 'binning'))
|
||||
# if self.binning == 1:
|
||||
# self.start_column = int(config.get('bin', 'start_column_binning_1'))
|
||||
# self.end_column = int(config.get('bin', 'end_column_binning_1'))
|
||||
# self.start_row = int(config.get('bin', 'start_row_binning_1'))
|
||||
# self.end_row = int(config.get('bin', 'end_row_binning_1'))
|
||||
# elif self.binning == 2:
|
||||
# self.start_column = int(config.get('bin', 'start_column_binning_2'))
|
||||
# self.end_column = int(config.get('bin', 'end_column_binning_2'))
|
||||
# self.start_row = int(config.get('bin', 'start_row_binning_2'))
|
||||
# self.end_row = int(config.get('bin', 'end_row_binning_2'))
|
||||
#
|
||||
# # print(self.default_dir, self.binning, self.start_column, self.end_column, self.start_row, self.end_row)
|
||||
#
|
||||
# else:
|
||||
# '''
|
||||
# 1、如果不存在配置文件,就建立配置文件;
|
||||
# 2、并且手动创建配置变量
|
||||
# '''
|
||||
# config = configparser.ConfigParser()
|
||||
#
|
||||
# # config.add_section('effective_window')
|
||||
# # startRow = 339
|
||||
# # endRow = 639
|
||||
# # startColumn = 285
|
||||
# # endColumn = 1649
|
||||
#
|
||||
#
|
||||
# config.add_section('bin')
|
||||
# config.set('bin', 'binning', '1')
|
||||
#
|
||||
# config.set('bin', 'start_column_binning_1', '12')
|
||||
# config.set('bin', 'end_column_binning_1', '1376')
|
||||
# config.set('bin', 'start_row_binning_1', '1')
|
||||
# config.set('bin', 'end_row_binning_1', '301')
|
||||
#
|
||||
# config.set('bin', 'start_column_binning_2', '13')
|
||||
# config.set('bin', 'end_column_binning_2', '695')
|
||||
# config.set('bin', 'start_row_binning_2', '1')
|
||||
# config.set('bin', 'end_row_binning_2', '150')
|
||||
#
|
||||
# config.add_section('image_record_param')
|
||||
# config.set('image_record_param', 'image_dir', self.base_dir + '/image')
|
||||
# config.set('image_record_param', 'default_image_name', 'testimage')
|
||||
# config.set('image_record_param', 'framerate', '20')
|
||||
# config.set('image_record_param', 'exposure_time', '500')
|
||||
# config.set('image_record_param', 'gain', '0')
|
||||
# config.set('image_record_param', 'frame_number', '20')
|
||||
#
|
||||
# config.add_section('spectral_record_param')
|
||||
# config.set('spectral_record_param', 'spectral_dir', self.base_dir + '/spectral')
|
||||
# config.set('spectral_record_param', 'default_spectral_name', 'testspectral')
|
||||
# # config.set('spectral_record_param', 'start_column_binning_1', '12')
|
||||
#
|
||||
# with open(self.corning_config_file, mode='w') as f:
|
||||
# config.write(f)
|
||||
# print('创建配置文件成功!')
|
||||
#
|
||||
# # 如果没有配置文件,就手动创建配置变量
|
||||
# self.image_dir = self.base_dir + '/image'
|
||||
# self.create_directory(self.image_dir)
|
||||
# self.default_image_name = 'testimage'
|
||||
# self.framerate = 20
|
||||
# self.exposure_time = 500
|
||||
# self.gain = 0
|
||||
# self.frame_number = 20
|
||||
#
|
||||
# self.spectral_dir = self.base_dir + '/spectral'
|
||||
# self.create_directory(self.spectral_dir)
|
||||
# self.default_spectral_name = 'testspectral'
|
||||
#
|
||||
# self.binning = int(config.get('bin', 'binning'))
|
||||
# self.start_column = int(config.get('bin', 'start_column_binning_1'))
|
||||
# self.end_column = int(config.get('bin', 'end_column_binning_1'))
|
||||
# self.start_row = int(config.get('bin', 'start_row_binning_1'))
|
||||
# self.end_row = int(config.get('bin', 'end_row_binning_1'))
|
||||
#
|
||||
# # self.start_column = 12
|
||||
# # self.end_column = 1376
|
||||
# # self.start_row = 1
|
||||
# # self.end_row = 300
|
||||
#
|
||||
# def image_record_param_changed(self, dictionary):
|
||||
# '''
|
||||
# :param dictionary: {'image_dir':值, 'image_record_param': 值}
|
||||
# :return:
|
||||
# '''
|
||||
# try:
|
||||
# # print('接收的参数个数:', len(dictionary.keys()))
|
||||
#
|
||||
# config = configparser.ConfigParser()
|
||||
# config.read(self.corning_config_file)
|
||||
#
|
||||
# for key in dictionary.keys():
|
||||
# if key == 'image_dir':
|
||||
# self.image_dir = dictionary[key]
|
||||
# config.set('image_record_param', key, dictionary[key])
|
||||
# if key == 'default_image_name':
|
||||
# self.default_image_name = dictionary[key]
|
||||
# config.set('image_record_param', key, dictionary[key])
|
||||
# if key == 'framerate':
|
||||
# self.framerate = dictionary[key]
|
||||
# config.set('image_record_param', key, str(dictionary[key]))
|
||||
# if key == 'exposure_time':
|
||||
# self.exposure_time = dictionary[key]
|
||||
# config.set('image_record_param', key, str(dictionary[key]))
|
||||
# if key == 'gain':
|
||||
# self.gain = dictionary[key]
|
||||
# config.set('image_record_param', key, str(dictionary[key]))
|
||||
# if key == 'frame_number':
|
||||
# self.frame_number = dictionary[key]
|
||||
# config.set('image_record_param', key, str(dictionary[key]))
|
||||
# except:
|
||||
# traceback.print_exc()
|
||||
#
|
||||
# with open(self.corning_config_file, 'w') as f:
|
||||
# config.write(f)
|
||||
#
|
||||
# def spectral_record_param_changed(self, dictionary):
|
||||
# '''
|
||||
# :param dictionary: {'image_dir':值, 'image_record_param': 值}
|
||||
# :return:
|
||||
# '''
|
||||
# print(len(dictionary.keys()))
|
||||
#
|
||||
# config = configparser.ConfigParser()
|
||||
# config.read(self.corning_config_file)
|
||||
#
|
||||
# try:
|
||||
# for key in dictionary.keys():
|
||||
# if key == 'spectral_dir':
|
||||
# self.spectral_dir = dictionary[key]
|
||||
# config.set('spectral_record_param', key, dictionary[key])
|
||||
# if key == 'default_spectral_name':
|
||||
# self.default_spectral_name = dictionary[key]
|
||||
# config.set('spectral_record_param', key, dictionary[key])
|
||||
# except:
|
||||
# traceback.print_exc()
|
||||
#
|
||||
# with open(self.corning_config_file, 'w') as f:
|
||||
# config.write(f)
|
||||
|
||||
|
||||
class ConfigFile(QObject, DirManager):
|
||||
# 信号必须定义为类属性,不能放在__init__方法里
|
||||
image_signal = pyqtSignal(dict)
|
||||
spectral_signal = pyqtSignal(dict)
|
||||
|
||||
def __init__(self):
|
||||
'''
|
||||
配置文件读取和写入类,采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取并保存在此类中,
|
||||
'''
|
||||
super(ConfigFile, self).__init__()
|
||||
|
||||
self.corning_config_file = self.log_dir + '//corning_config.ini'
|
||||
|
||||
self.read_config_file()
|
||||
|
||||
self.image_signal.connect(self.image_record_param_changed)
|
||||
self.spectral_signal.connect(self.spectral_record_param_changed)
|
||||
|
||||
# 读取配置文件,如果没有就创建
|
||||
def read_config_file(self):
|
||||
if os.path.exists(self.corning_config_file):
|
||||
'''
|
||||
如果存在配置文件,就从配置文件中读取软件配置信息
|
||||
'''
|
||||
print('配置文件存在!')
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.corning_config_file)
|
||||
|
||||
# self.image_dir = config.get('image_record_param', 'image_dir')
|
||||
# self.create_directory(self.image_dir)
|
||||
# self.default_image_name = config.get('image_record_param', 'default_image_name')
|
||||
# self.framerate = int(config.get('image_record_param', 'framerate'))
|
||||
# self.exposure_time = int(float(config.get('image_record_param', 'exposure_time')))
|
||||
# self.gain = int(float(config.get('image_record_param', 'gain')))
|
||||
# self.frame_number = int(config.get('image_record_param', 'frame_number'))
|
||||
# self.arcus_speed = int(config.get('image_record_param', 'arcus_speed'))
|
||||
#
|
||||
# self.spectral_dir = config.get('spectral_record_param', 'spectral_dir')
|
||||
# self.create_directory(self.spectral_dir)
|
||||
# self.default_spectral_name = config.get('spectral_record_param', 'default_spectral_name')
|
||||
# self.spectral_number = int(config.get('spectral_record_param', 'spectral_number'))
|
||||
# self.framenumber_average = int(config.get('spectral_record_param', 'framenumber_average'))
|
||||
# self.exposure_time_spectral = int(config.get('spectral_record_param', 'exposure_time_spectral'))
|
||||
#
|
||||
# self.binning = int(config.get('bin', 'binning'))
|
||||
# if self.binning == 1:
|
||||
# self.start_column = int(config.get('bin', 'start_column_binning_1'))
|
||||
# self.end_column = int(config.get('bin', 'end_column_binning_1'))
|
||||
# self.start_row = int(config.get('bin', 'start_row_binning_1'))
|
||||
# self.end_row = int(config.get('bin', 'end_row_binning_1'))
|
||||
# elif self.binning == 2:
|
||||
# self.start_column = int(config.get('bin', 'start_column_binning_2'))
|
||||
# self.end_column = int(config.get('bin', 'end_column_binning_2'))
|
||||
# self.start_row = int(config.get('bin', 'start_row_binning_2'))
|
||||
# self.end_row = int(config.get('bin', 'end_row_binning_2'))
|
||||
#
|
||||
# # print(self.default_dir, self.binning, self.start_column, self.end_column, self.start_row, self.end_row)
|
||||
else:
|
||||
'''
|
||||
1、如果不存在配置文件,就建立配置文件;
|
||||
2、并且手动创建配置变量
|
||||
'''
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
|
||||
|
||||
config.add_section('bin')
|
||||
config.set('bin', 'binning', '1')
|
||||
|
||||
# # Serial number = 008
|
||||
# config.set('bin', 'start_column_binning_1', '12')
|
||||
# config.set('bin', 'end_column_binning_1', '1376')
|
||||
# config.set('bin', 'start_row_binning_1', '2')
|
||||
# config.set('bin', 'end_row_binning_1', '302')
|
||||
#
|
||||
# config.set('bin', 'start_column_binning_2', '13')
|
||||
# config.set('bin', 'end_column_binning_2', '695')
|
||||
# config.set('bin', 'start_row_binning_2', '0')
|
||||
# config.set('bin', 'end_row_binning_2', '150')
|
||||
|
||||
# # Serial number = 0073
|
||||
# config.set('bin', 'start_column_binning_1', '12')
|
||||
# config.set('bin', 'end_column_binning_1', '1376')
|
||||
# config.set('bin', 'start_row_binning_1', '1')
|
||||
# config.set('bin', 'end_row_binning_1', '301')
|
||||
#
|
||||
# config.set('bin', 'start_column_binning_2', '13')
|
||||
# config.set('bin', 'end_column_binning_2', '695')
|
||||
# config.set('bin', 'start_row_binning_2', '0')
|
||||
# config.set('bin', 'end_row_binning_2', '150')
|
||||
|
||||
# # Serial number = 0095
|
||||
# config.set('bin', 'start_column_binning_1', '12')
|
||||
# config.set('bin', 'end_column_binning_1', '1376')
|
||||
# config.set('bin', 'start_row_binning_1', '1')
|
||||
# config.set('bin', 'end_row_binning_1', '301')
|
||||
#
|
||||
# config.set('bin', 'start_column_binning_2', '13')
|
||||
# config.set('bin', 'end_column_binning_2', '695')
|
||||
# config.set('bin', 'start_row_binning_2', '0')
|
||||
# config.set('bin', 'end_row_binning_2', '150')
|
||||
|
||||
# Serial number = 0031
|
||||
config.set('bin', 'start_column_binning_1', '12')
|
||||
config.set('bin', 'end_column_binning_1', '1376')
|
||||
config.set('bin', 'start_row_binning_1', '1')
|
||||
config.set('bin', 'end_row_binning_1', '301')
|
||||
|
||||
config.set('bin', 'start_column_binning_2', '13')
|
||||
config.set('bin', 'end_column_binning_2', '695')
|
||||
config.set('bin', 'start_row_binning_2', '1')
|
||||
config.set('bin', 'end_row_binning_2', '151')
|
||||
|
||||
# # Serial number = 0099
|
||||
# config.set('bin', 'start_column_binning_1', '12')
|
||||
# config.set('bin', 'end_column_binning_1', '1376')
|
||||
# config.set('bin', 'start_row_binning_1', '1')
|
||||
# config.set('bin', 'end_row_binning_1', '301')
|
||||
#
|
||||
# config.set('bin', 'start_column_binning_2', '13')
|
||||
# config.set('bin', 'end_column_binning_2', '695')
|
||||
# config.set('bin', 'start_row_binning_2', '1')
|
||||
# config.set('bin', 'end_row_binning_2', '151')
|
||||
|
||||
|
||||
|
||||
config.add_section('effective_window')
|
||||
config.set('effective_window', 'width_binning_1', '1392')
|
||||
config.set('effective_window', 'offsetX_binning_1', '272')
|
||||
config.set('effective_window', 'height_binning_1', '302')
|
||||
config.set('effective_window', 'offsetY_binning_1', '364')
|
||||
|
||||
config.set('effective_window', 'width_binning_2', '696')
|
||||
config.set('effective_window', 'offsetX_binning_2', '128')
|
||||
config.set('effective_window', 'height_binning_2', '151')
|
||||
config.set('effective_window', 'offsetY_binning_2', '182')
|
||||
|
||||
config.add_section('calibration_file')
|
||||
config.set('calibration_file', 'cal_file_name_image_bining_1', 'lens_bin1_gain_SN0073')
|
||||
config.set('calibration_file', 'cal_file_name_image_bining_2', 'lens_bin2_gain_SN0073')
|
||||
|
||||
config.set('calibration_file', 'cal_file_it_image_bining_1', '6969')
|
||||
config.set('calibration_file', 'cal_file_it_image_bining_2', '1628')
|
||||
|
||||
config.set('calibration_file', 'cal_file_name_spectral_bining_1', 'optical_fiber_bin1_gain_SN0073')
|
||||
config.set('calibration_file', 'cal_file_it_spectrl_bining_1', '42300')
|
||||
|
||||
|
||||
|
||||
|
||||
config.add_section('wavelength_file_name')
|
||||
config.set('wavelength_file_name', 'file_name', 'wavelength0073.txt')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
config.add_section('image_record_param')
|
||||
config.set('image_record_param', 'image_dir', self.base_dir + '/image')
|
||||
config.set('image_record_param', 'default_image_name', 'testimage')
|
||||
config.set('image_record_param', 'framerate', '20')
|
||||
config.set('image_record_param', 'exposure_time', '500')
|
||||
config.set('image_record_param', 'gain', '0')
|
||||
config.set('image_record_param', 'frame_number', '20')
|
||||
config.set('image_record_param', 'arcus_speed', '1000')
|
||||
|
||||
config.add_section('spectral_record_param')
|
||||
config.set('spectral_record_param', 'spectral_dir', self.base_dir + '/spectral')
|
||||
config.set('spectral_record_param', 'default_spectral_name', 'testspectral')
|
||||
config.set('spectral_record_param', 'spectral_number', '10')
|
||||
config.set('spectral_record_param', 'framenumber_average', '10')
|
||||
config.set('spectral_record_param', 'exposure_time_spectral', '1000')
|
||||
# config.set('spectral_record_param', 'start_column_binning_1', '12')
|
||||
|
||||
with open(self.corning_config_file, mode='w') as f:
|
||||
config.write(f)# 如果没有配置文件,就手动创建配置变量
|
||||
print('创建配置文件成功!')
|
||||
|
||||
|
||||
|
||||
# 读取配置文件中的参数
|
||||
self.binning = int(config.get('bin', 'binning'))
|
||||
print('读取配置文件中参数:', self.binning)
|
||||
|
||||
if self.binning == 1:
|
||||
self.effective_window_width = int(config.get('effective_window', 'width_binning_1'))
|
||||
self.effective_window_offsetx = int(config.get('effective_window', 'offsetx_binning_1'))
|
||||
self.effective_window_height = int(config.get('effective_window', 'height_binning_1'))
|
||||
self.effective_window_offsety = int(config.get('effective_window', 'offsety_binning_1'))
|
||||
|
||||
self.start_column = int(config.get('bin', 'start_column_binning_1'))
|
||||
self.end_column = int(config.get('bin', 'end_column_binning_1'))
|
||||
self.start_row = int(config.get('bin', 'start_row_binning_1'))
|
||||
self.end_row = int(config.get('bin', 'end_row_binning_1'))
|
||||
|
||||
self.calibration_file_name_image=config.get('calibration_file', 'cal_file_name_image_bining_1')
|
||||
self.calibration_file_it_image = int(config.get('calibration_file', 'cal_file_it_image_bining_1'))
|
||||
self.calibration_file_name_spectral = config.get('calibration_file', 'cal_file_name_spectral_bining_1')
|
||||
self.calibration_file_it_spectral = int(config.get('calibration_file', 'cal_file_it_spectrl_bining_1'))
|
||||
elif self.binning == 2:
|
||||
self.effective_window_width = int(config.get('effective_window', 'width_binning_2'))
|
||||
self.effective_window_offsetx = int(config.get('effective_window', 'offsetx_binning_2'))
|
||||
self.effective_window_height = int(config.get('effective_window', 'height_binning_2'))
|
||||
self.effective_window_offsety = int(config.get('effective_window', 'offsety_binning_2'))
|
||||
|
||||
self.start_column = int(config.get('bin', 'start_column_binning_2'))
|
||||
self.end_column = int(config.get('bin', 'end_column_binning_2'))
|
||||
self.start_row = int(config.get('bin', 'start_row_binning_2'))
|
||||
self.end_row = int(config.get('bin', 'end_row_binning_2'))
|
||||
|
||||
self.calibration_file_name_image = config.get('calibration_file', 'cal_file_name_image_bining_2')
|
||||
self.calibration_file_it_image = int(config.get('calibration_file', 'cal_file_it_image_bining_2'))
|
||||
|
||||
self.wavelength_file_name = config.get('wavelength_file_name', 'file_name')
|
||||
|
||||
self.image_dir = config.get('image_record_param', 'image_dir')
|
||||
self.create_directory(self.image_dir)
|
||||
self.default_image_name = config.get('image_record_param', 'default_image_name')
|
||||
self.framerate = int(float(config.get('image_record_param', 'framerate')))
|
||||
self.exposure_time = int(float(config.get('image_record_param', 'exposure_time')))
|
||||
self.gain = int(float(config.get('image_record_param', 'gain')))
|
||||
self.frame_number = int(float(config.get('image_record_param', 'frame_number')))
|
||||
self.arcus_speed = int(float(config.get('image_record_param', 'arcus_speed')))
|
||||
|
||||
self.spectral_dir = config.get('spectral_record_param', 'spectral_dir')
|
||||
self.create_directory(self.spectral_dir)
|
||||
self.default_spectral_name = config.get('spectral_record_param', 'default_spectral_name')
|
||||
self.spectral_number = int(float(config.get('spectral_record_param', 'spectral_number')))
|
||||
self.framenumber_average = int(float(config.get('spectral_record_param', 'framenumber_average')))
|
||||
self.exposure_time_spectral = int(float(config.get('spectral_record_param', 'exposure_time_spectral')))
|
||||
|
||||
# self.start_column = 12
|
||||
# self.end_column = 1376
|
||||
# self.start_row = 1
|
||||
# self.end_row = 300
|
||||
|
||||
def image_record_param_changed(self, dictionary):
|
||||
'''
|
||||
:param dictionary: {'image_dir':值, 'image_record_param': 值}
|
||||
:return:
|
||||
'''
|
||||
try:
|
||||
# print('接收的参数个数:', len(dictionary.keys()))
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.corning_config_file)
|
||||
|
||||
for key in dictionary.keys():
|
||||
# self.key = dictionary[key]
|
||||
# config.set('image_record_param', key, dictionary[key])
|
||||
|
||||
if key == 'image_dir':
|
||||
self.image_dir = dictionary[key]
|
||||
config.set('image_record_param', key, dictionary[key])
|
||||
if key == 'default_image_name':
|
||||
self.default_image_name = dictionary[key]
|
||||
config.set('image_record_param', key, dictionary[key])
|
||||
if key == 'framerate':
|
||||
self.framerate = dictionary[key]
|
||||
config.set('image_record_param', key, str(dictionary[key]))
|
||||
if key == 'exposure_time':
|
||||
self.exposure_time = dictionary[key]
|
||||
config.set('image_record_param', key, str(dictionary[key]))
|
||||
if key == 'gain':
|
||||
self.gain = dictionary[key]
|
||||
config.set('image_record_param', key, str(dictionary[key]))
|
||||
if key == 'frame_number':
|
||||
self.frame_number = dictionary[key]
|
||||
config.set('image_record_param', key, str(dictionary[key]))
|
||||
if key == 'arcus_speed':
|
||||
self.arcus_speed = dictionary[key]
|
||||
config.set('image_record_param', key, str(dictionary[key]))
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
with open(self.corning_config_file, 'w') as f:
|
||||
config.write(f)
|
||||
|
||||
def spectral_record_param_changed(self, dictionary):
|
||||
'''
|
||||
:param dictionary: {'image_dir':值, 'image_record_param': 值}
|
||||
:return:
|
||||
'''
|
||||
print(len(dictionary.keys()))
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.corning_config_file)
|
||||
|
||||
try:
|
||||
for key in dictionary.keys():
|
||||
if key == 'spectral_dir':
|
||||
self.spectral_dir = dictionary[key]
|
||||
config.set('spectral_record_param', key, dictionary[key])
|
||||
if key == 'default_spectral_name':
|
||||
self.default_spectral_name = dictionary[key]
|
||||
config.set('spectral_record_param', key, dictionary[key])
|
||||
if key == 'spectral_number':
|
||||
self.spectral_number = dictionary[key]
|
||||
config.set('spectral_record_param', key, str(dictionary[key]))
|
||||
if key == 'framenumber_average':
|
||||
self.framenumber_average = dictionary[key]
|
||||
config.set('spectral_record_param', key, str(dictionary[key]))
|
||||
if key == 'exposure_time_spectral':
|
||||
self.exposure_time_spectral = dictionary[key]
|
||||
config.set('spectral_record_param', key, str(dictionary[key]))
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
with open(self.corning_config_file, 'w') as f:
|
||||
config.write(f)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
x = ConfigFile()
|
29
library/dir_manager.py
Normal file
29
library/dir_manager.py
Normal file
@ -0,0 +1,29 @@
|
||||
import os
|
||||
from library.functions import get_path
|
||||
|
||||
|
||||
class DirManager():
|
||||
def __init__(self):
|
||||
self.base_dir = get_path()
|
||||
self.log_dir = self.base_dir + '//log'
|
||||
|
||||
self.create_directory(self.log_dir)
|
||||
print(self.log_dir)
|
||||
|
||||
|
||||
# 查看是否存在保存光谱和影像文件的目录,如果没有就创建
|
||||
def create_directory(self, directory):
|
||||
'''
|
||||
:param directory: 需要创建的文件夹绝对路径,不能将参数directory省略而在此函数内部使用self.log_dir,
|
||||
因为本类的继承类也需要使用此函数
|
||||
:return:
|
||||
'''
|
||||
if not os.path.exists(directory):
|
||||
print('创建文件夹:', directory)
|
||||
os.makedirs(directory)
|
||||
# else:
|
||||
# print('文件夹存在:%s' % self.log_dir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
x = DirManager()
|
144
library/functions.py
Normal file
144
library/functions.py
Normal file
@ -0,0 +1,144 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
'''
|
||||
本模块是各种工具函数
|
||||
'''
|
||||
|
||||
import sys, os
|
||||
import numpy as np
|
||||
|
||||
def get_path():
|
||||
'''
|
||||
本函数说明:https://pythonhosted.org/PyInstaller/runtime-information.html#using-sys-executable-and-sys-argv-0
|
||||
:return: 返回运行程序的绝对路径
|
||||
'''
|
||||
frozen = 'not'
|
||||
if getattr(sys, 'frozen', False):
|
||||
# we are running in a bundle
|
||||
bundle_dir = sys._MEIPASS
|
||||
|
||||
# print('we are running in a bundle(pyinstaller打包程序)!')
|
||||
else:
|
||||
# we are running in a normal Python environment
|
||||
# bundle_dir = os.path.dirname(os.path.abspath(__file__)) # 此行代码返回的是本文件的路径,而不是本文件所导入的文件的路径
|
||||
bundle_dir = os.getcwd()
|
||||
# print('we are running in a normal Python environment(非pyinstaller打包程序)!')
|
||||
|
||||
return bundle_dir
|
||||
|
||||
|
||||
def get_resource_path(relative_path):
|
||||
'''
|
||||
本函数说明:https://www.zacoding.com/en/post/python-selenium-to-exe/
|
||||
:param relative_path:
|
||||
:return:
|
||||
'''
|
||||
try:
|
||||
base_path = sys._MEIPASS
|
||||
except Exception:
|
||||
base_path = os.getcwd()
|
||||
return os.path.join(base_path, relative_path)
|
||||
|
||||
|
||||
def percentile_stretching(img, lowPercentile=0, highPercentile=100, minout=0, maxout=255):
|
||||
'''
|
||||
本程序用于拉伸影像
|
||||
:param img:
|
||||
:param lowPercentile:
|
||||
:param highPercentile:
|
||||
:param minout:
|
||||
:param maxout:
|
||||
:return:
|
||||
'''
|
||||
if len(img.shape) == 2:
|
||||
low = np.percentile(img, lowPercentile)
|
||||
up = np.percentile(img, highPercentile)
|
||||
|
||||
img_new = ((img - low) / (up - low)) * (maxout - minout) + minout
|
||||
img_new[img_new < minout] = minout
|
||||
img_new[img_new > maxout] = maxout
|
||||
img_out = np.uint8(img_new)
|
||||
return img_out
|
||||
else: # 对于彩色照片,需要先单独对每个波段拉伸
|
||||
img_new = np.empty(img.shape)
|
||||
for i in range(img.shape[2]):
|
||||
low = np.percentile(img[:, :, i], lowPercentile)
|
||||
up = np.percentile(img[:, :, i], highPercentile)
|
||||
|
||||
img_new[:, :, i] = minout + ((img[:, :, i] - low) / (up - low)) * (maxout - minout)
|
||||
img_new[:, :, i][img_new[:, :, i] < minout] = minout
|
||||
img_new[:, :, i][img_new[:, :, i] > maxout] = maxout
|
||||
img_out = np.uint8(img_new)
|
||||
return img_out
|
||||
|
||||
|
||||
def return_file_path(out, filepath, filename, model='image'):
|
||||
'''
|
||||
本程序功能:在filepath中寻找所有包含filename所有文件(filename1、filename2),然后返回一个filename3
|
||||
:param out: 永远传入一个空list:[];用于存储所有递归调用
|
||||
:param filepath:
|
||||
:param filename:
|
||||
:param model: 有两个模式:image 和 spectral
|
||||
:return:
|
||||
'''
|
||||
|
||||
# 出现此处代码的原因是:当次函数定义执行后,函数定义就包含了out参数的引用,
|
||||
# 而out参数是可变参数,每一次调用次函数都会改变out的值,所有不能保证每次调用此函数时out==[]。
|
||||
# 当第二次调用此方程时
|
||||
# if out != []:
|
||||
# if filename not in os.path.splitext(out[-1]):
|
||||
# out = []
|
||||
|
||||
if model == 'image':
|
||||
files = os.listdir(filepath)
|
||||
for s in files:
|
||||
abspath = os.path.join(filepath, s)
|
||||
if os.path.isfile(abspath):
|
||||
tmp = os.path.splitext(os.path.split(abspath)[1])[0]
|
||||
if tmp not in out: # 防止重复记录
|
||||
if filename in tmp:
|
||||
out.append(tmp)
|
||||
else:
|
||||
pass
|
||||
# print('没有进来')
|
||||
elif os.path.isdir(abspath):
|
||||
return_file_path(out, abspath, filename)
|
||||
out.sort(key=lambda x: int(x.replace(filename, '')))
|
||||
|
||||
if out == []:
|
||||
x = filename + str(0)
|
||||
return os.path.join(filepath, x), 0
|
||||
if out != []:
|
||||
number = int(out[-1].replace(filename, '')) + 1
|
||||
x = filename + str(number)
|
||||
return os.path.join(filepath, x), number
|
||||
elif model == 'spectral':
|
||||
files = os.listdir(filepath)
|
||||
for s in files:
|
||||
abspath = os.path.join(filepath, s)
|
||||
if os.path.isfile(abspath) and os.path.splitext(s)[1] == '.txt':
|
||||
tmp = os.path.splitext(os.path.split(abspath)[1])[0]
|
||||
if tmp not in out: # 防止重复记录
|
||||
if filename in tmp:
|
||||
out.append(tmp)
|
||||
elif os.path.isdir(abspath):
|
||||
return_file_path(out, abspath, filename)
|
||||
out.sort(key=lambda x: int(x.replace(filename, '')))
|
||||
|
||||
if out == []:
|
||||
x = filename + str(0) + '.txt'
|
||||
return os.path.join(filepath, x), 0
|
||||
if out != []:
|
||||
number = int(out[-1].replace(filename, '')) + 1 # 现存最大文件号 + 1
|
||||
x = filename + str(number) + '.txt'
|
||||
return os.path.join(filepath, x), number
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# print(get_path())
|
||||
|
||||
x = return_file_path([], r'D:\delete', 'sss', model='spectral')
|
||||
print(x)
|
||||
|
||||
# y = return_file_path([], r'D:\delete', 'rr')
|
||||
# print(y)
|
40
library/image_reader_writer.py
Normal file
40
library/image_reader_writer.py
Normal file
@ -0,0 +1,40 @@
|
||||
import sys, traceback
|
||||
from osgeo import gdal
|
||||
|
||||
# 读写影像类
|
||||
class ImageReaderWriter(object):
|
||||
|
||||
#读图像文件
|
||||
@classmethod
|
||||
def read_img(cls, filename, xoff=0, yoff=0, im_width=None, im_height=None):
|
||||
try:
|
||||
dataset = gdal.Open(filename) # 打开文件
|
||||
if im_width == None:
|
||||
im_width = dataset.RasterXSize # 栅格矩阵的列数
|
||||
if im_height == None:
|
||||
im_height = dataset.RasterYSize # 栅格矩阵的行数
|
||||
num_bands = dataset.RasterCount # 栅格矩阵的波段数
|
||||
im_geotrans = dataset.GetGeoTransform() # 仿射矩阵
|
||||
im_proj = dataset.GetProjection() # 地图投影信息
|
||||
im_data = dataset.ReadAsArray(xoff, yoff, im_width, im_height) # 将数据写成数组,对应栅格矩阵
|
||||
del dataset
|
||||
return im_proj, im_geotrans, im_data
|
||||
except AttributeError:
|
||||
print('gdal打开影像:没有文件!')
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
pass
|
||||
|
||||
#写文件,以写成tif为例
|
||||
@classmethod
|
||||
def write_img(cls, dst_filename, data):
|
||||
format = "ENVI"
|
||||
driver = gdal.GetDriverByName(format)
|
||||
RasterXSize = data.shape[2] # 遥感影像的sample(列数)
|
||||
RasterYSize = data.shape[1] # 遥感影像的line(行数)
|
||||
band = data.shape[0]
|
||||
# driver.Create()函数中RasterXSize代表影像的sample(列数),RasterYSize代表影像的line(行数)
|
||||
dst_ds = driver.Create(dst_filename, RasterXSize, RasterYSize, band, gdal.GDT_Float32)
|
||||
for i in range(band):
|
||||
dst_ds.GetRasterBand(i + 1).WriteArray(data[i, :, :]) # gdal的band从1开始,所以dst_ds.GetRasterBand(i+1)
|
||||
dst_ds = None
|
50
library/log.py
Normal file
50
library/log.py
Normal file
@ -0,0 +1,50 @@
|
||||
# 标准库
|
||||
import traceback, os, logging
|
||||
|
||||
# 三方库
|
||||
import configparser
|
||||
|
||||
# 自己写的库
|
||||
from library.dir_manager import DirManager
|
||||
|
||||
|
||||
class Log(DirManager):
|
||||
def __init__(self):
|
||||
super(Log, self).__init__()
|
||||
|
||||
self.log()
|
||||
|
||||
def log(self):
|
||||
# 判断是否存在log文件,如果不存在就创建
|
||||
if not os.path.exists(self.log_dir + '//all_operate.log'):
|
||||
with open(self.log_dir + '//all_operate.log', 'w') as f:
|
||||
pass
|
||||
if not os.path.exists(self.log_dir + '//error.log'):
|
||||
with open(self.log_dir + '//error.log', 'w') as f:
|
||||
pass
|
||||
|
||||
# 初始化log
|
||||
root_logger = logging.getLogger('root')
|
||||
root_logger.setLevel(level=logging.DEBUG) # logger级别设置为低级别,代表这个logger可以处理很多级别的日志,更灵活的处理放在logger中的各种handler中
|
||||
|
||||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
|
||||
all_operate_file_handler = logging.FileHandler(self.log_dir + '//all_operate.log') # 输出到文件
|
||||
all_operate_file_handler.setLevel(logging.INFO)
|
||||
all_operate_file_handler.setFormatter(formatter)
|
||||
|
||||
error_file_handler = logging.FileHandler(self.log_dir + '//error.log') # 输出到文件
|
||||
error_file_handler.setLevel(logging.ERROR)
|
||||
error_file_handler.setFormatter(formatter)
|
||||
|
||||
stream_handler = logging.StreamHandler() # 输出到控制台
|
||||
stream_handler.setLevel(logging.INFO)
|
||||
stream_handler.setFormatter(formatter)
|
||||
|
||||
root_logger.addHandler(all_operate_file_handler)
|
||||
root_logger.addHandler(error_file_handler)
|
||||
root_logger.addHandler(stream_handler)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
x = Log()
|
25
library/log/corning_config.ini
Normal file
25
library/log/corning_config.ini
Normal file
@ -0,0 +1,25 @@
|
||||
[bin]
|
||||
binning = 1
|
||||
start_column_binning_1 = 12
|
||||
end_column_binning_1 = 1376
|
||||
start_row_binning_1 = 1
|
||||
end_row_binning_1 = 301
|
||||
start_column_binning_2 = 13
|
||||
end_column_binning_2 = 695
|
||||
start_row_binning_2 = 1
|
||||
end_row_binning_2 = 150
|
||||
|
||||
[image_record_param]
|
||||
image_dir = D:\py_program\corning410\library/image
|
||||
default_image_name = test_image
|
||||
framerate = 20
|
||||
exposure_time = 500
|
||||
gain = 0
|
||||
frame_number = 20
|
||||
|
||||
[spectral_record_param]
|
||||
spectral_dir = D:\py_program\corning410\library/spectral
|
||||
default_spectral_name = test_spectral
|
||||
spectral_number = 10
|
||||
framenumber_average = 10
|
||||
|
161
library/matplotlib_display_image_spectral.py
Normal file
161
library/matplotlib_display_image_spectral.py
Normal file
@ -0,0 +1,161 @@
|
||||
import matplotlib
|
||||
matplotlib.use("Qt5Agg") # 声明使用QT5
|
||||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.figure import Figure
|
||||
import traceback
|
||||
import time, sys
|
||||
from functions import percentile_stretching
|
||||
|
||||
from PyQt5 import QtWidgets, QtCore, uic
|
||||
import pyqtgraph as pg
|
||||
from random import randint
|
||||
|
||||
|
||||
class ArgsError(Exception):
|
||||
pass
|
||||
|
||||
# 画图类,用于:画出采集到的光谱;调焦(影响模式调焦)
|
||||
class MatplotlibSpectralViewer(FigureCanvas):
|
||||
def __init__(self, xlabel=None, ylabel=None, width=5, height=4, dpi=100):
|
||||
# 第一步:创建一个创建Figure
|
||||
self.fig = Figure(figsize=(width, height), dpi=dpi)
|
||||
|
||||
# 第二步:在父类中激活Figure窗口
|
||||
# this is the Canvas Widget that displays the `figure`
|
||||
# it takes the `figure` instance as a parameter to __init__
|
||||
super(MatplotlibSpectralViewer, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
|
||||
|
||||
# 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
|
||||
self.axes = self.fig.add_subplot(1, 1, 1)
|
||||
self.axes.set_xlabel('Wavelength (nm)')
|
||||
self.axes.set_ylabel('reflectance')
|
||||
|
||||
self.xlabel = xlabel
|
||||
self.ylabel = ylabel
|
||||
|
||||
self._plotref = None # 这里代表曲线
|
||||
|
||||
self.axes.set_ylim(0, 1.2)
|
||||
|
||||
# 第四步:就是画图,【可以在此类中画,也可以在其它类中画】
|
||||
def plot_wrap(self, *args):
|
||||
if self.xlabel is not None:
|
||||
self.axes.set_xlabel(self.xlabel)
|
||||
if self.ylabel is not None:
|
||||
self.axes.set_ylabel(self.ylabel)
|
||||
|
||||
try:
|
||||
if self._plotref == None:
|
||||
if len(args) == 0:
|
||||
raise ArgsError('传入了0个参数,本函数只能传入1/2个参数!')
|
||||
elif len(args) == 1:
|
||||
self.axes.cla()
|
||||
|
||||
# self.axes.set_ylim(0, 1.2)
|
||||
|
||||
self._plotref = self.axes.plot(list(range(len(args[0]))), args[0])[0]
|
||||
self.draw()
|
||||
elif len(args) == 2:
|
||||
self.axes.cla()
|
||||
|
||||
# self.axes.set_ylim(0, 1.2)
|
||||
|
||||
self._plotref = self.axes.plot(args[0], args[1])[0]
|
||||
self.draw()
|
||||
elif len(args) > 2:
|
||||
raise ArgsError('传入了大于2个参数,本函数只能传入1/2个参数!')
|
||||
elif self._plotref is not None:
|
||||
if len(args) == 0:
|
||||
raise ArgsError('传入了0个参数,本函数只能传入1/2个参数!')
|
||||
elif len(args) == 1:
|
||||
self._plotref.set_data(list(range(len(args[0]))), args[0])
|
||||
|
||||
# 更新显示区域
|
||||
self.axes.set_xlim(min(list(range(len(args[0])))), max(list(range(len(args[0])))))
|
||||
self.axes.set_ylim(min(args[0]), max(args[0]))
|
||||
|
||||
# self.axes.set_ylim(0, 1.2)
|
||||
|
||||
# 绘制图像
|
||||
self.draw()
|
||||
elif len(args) == 2:
|
||||
self._plotref.set_data(args[0], args[1])
|
||||
|
||||
# 更新显示区域
|
||||
self.axes.set_xlim(min(args[0]), max(args[0]))
|
||||
self.axes.set_ylim(min(args[1]), max(args[1]))
|
||||
|
||||
# self.axes.set_ylim(0, 1.2)
|
||||
|
||||
# 绘制图像
|
||||
self.draw()
|
||||
elif len(args) > 2:
|
||||
raise ArgsError('传入了大于2个参数,本函数只能传入1/2个参数!')
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
# 画图类,用于:画出采集到的图像;显示帧流(光谱模式对准光纤)
|
||||
class MatplotlibImageViewer(FigureCanvas):
|
||||
def __init__(self, width=5, height=4, dpi=100):
|
||||
# 第一步:创建一个创建Figure
|
||||
self.fig = Figure(figsize=(width, height), dpi=dpi)
|
||||
# 第二步:在父类中激活Figure窗口
|
||||
# this is the Canvas Widget that displays the `figure`
|
||||
# it takes the `figure` instance as a parameter to __init__
|
||||
super(MatplotlibImageViewer, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
|
||||
# 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
|
||||
self.axes = self.fig.add_subplot(1, 1, 1)
|
||||
|
||||
self._plotref = None # 这里代表图像
|
||||
|
||||
# 第四步:就是画图,【可以在此类中画,也可以在其它类中画】
|
||||
def setImage(self, image, lowPercentile=0, highPercentile=100):
|
||||
self.axes.set_xticks([])
|
||||
self.axes.set_yticks([])
|
||||
|
||||
if self._plotref == None:
|
||||
self._plotref = self.axes.imshow(image)
|
||||
self.draw()
|
||||
elif self._plotref is not None:
|
||||
self._plotref.set_data(percentile_stretching(image, lowPercentile, highPercentile))
|
||||
self.draw()
|
||||
|
||||
|
||||
class MainWindow(QtWidgets.QMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MainWindow, self).__init__(*args, **kwargs)
|
||||
|
||||
# self.graphWidget = QtSpectralViewer()
|
||||
self.graphWidget = MatplotlibSpectralViewer(xlabel='Wavelength (nm)', ylabel='reflectance')
|
||||
self.setCentralWidget(self.graphWidget)
|
||||
|
||||
self.x = list(range(100)) # 100 time points
|
||||
self.y = [randint(0, 100) for _ in range(100)] # 100 data points
|
||||
|
||||
# self.graphWidget.setBackground('w')
|
||||
|
||||
pen = pg.mkPen(color=(255, 0, 0))
|
||||
self.graphWidget.plot_wrap(self.x, self.y)
|
||||
|
||||
self.timer = QtCore.QTimer()
|
||||
self.timer.timeout.connect(self.update_plot_data)
|
||||
self.timer.start(10)
|
||||
|
||||
def update_plot_data(self):
|
||||
self.x = self.x[1:] # Remove the first y element.
|
||||
self.x.append(self.x[-1] + 1) # Add a new value 1 higher than the last.
|
||||
|
||||
self.y = self.y[1:] # Remove the first
|
||||
self.y.append(randint(0, 100)) # Add a new random value.
|
||||
|
||||
# self.data_line.setData(self.x, self.y) # Update the data.
|
||||
|
||||
self.graphWidget.plot_wrap(self.x, self.y)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
w = MainWindow()
|
||||
w.show()
|
||||
sys.exit(app.exec_())
|
53
library/message_box.py
Normal file
53
library/message_box.py
Normal file
@ -0,0 +1,53 @@
|
||||
from PyQt5.QtWidgets import QApplication, QDialog
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
import sys
|
||||
|
||||
from library.message_box_ui import *
|
||||
|
||||
|
||||
class MessageBox(QDialog, Ui_message_box_ui):
|
||||
def __init__(self, txt, parent=None):
|
||||
'''
|
||||
The super().__init__() method invokes the base class constructor from the MyForm class,
|
||||
that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
|
||||
QDialog is displayed through this class iss a top-level window.
|
||||
'''
|
||||
super(MessageBox, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
# self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
|
||||
self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:只能在关闭此窗口之后才能操作后面的窗口,但是不会阻塞调用此窗口的进程的代码;此行代码必须放在show()函数之前
|
||||
# self.setWindowModality(Qt.WindowModal)
|
||||
|
||||
# 无边框
|
||||
# self.setWindowFlags(Qt.FramelessWindowHint)
|
||||
|
||||
self.txt = txt
|
||||
|
||||
self.info()
|
||||
|
||||
self.confirm_bt.clicked.connect(self.shutdown)
|
||||
|
||||
# 禁止调整大小
|
||||
# self.setFixedSize(self.width(), self.height())
|
||||
|
||||
def info(self):
|
||||
self.info_label.setText(self.txt)
|
||||
|
||||
# self.exec() # 阻塞调用此窗口后的进程的代码,只有此窗口返回后才能执行此窗口外的代码
|
||||
|
||||
# self.show() # 只是显示,不会阻塞任何代码
|
||||
|
||||
def shutdown(self):
|
||||
self.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
x = MessageBox('请先曝光和采集暗电流!')
|
||||
|
||||
# x.show()
|
||||
|
||||
sys.exit(app.exec_())
|
90
library/message_box_ui.py
Normal file
90
library/message_box_ui.py
Normal file
@ -0,0 +1,90 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'message_box_ui.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.13.0
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_message_box_ui(object):
|
||||
def setupUi(self, message_box_ui):
|
||||
message_box_ui.setObjectName("message_box_ui")
|
||||
message_box_ui.resize(487, 385)
|
||||
self.gridLayout = QtWidgets.QGridLayout(message_box_ui)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.info_label = QtWidgets.QLabel(message_box_ui)
|
||||
self.info_label.setStyleSheet("QLabel\n"
|
||||
"{\n"
|
||||
" /*字体为微软雅黑*/\n"
|
||||
" font-family:Microsoft Yahei;\n"
|
||||
" /*字体大小为20点*/\n"
|
||||
" font-size:30pt;\n"
|
||||
" /*字体颜色为白色*/\n"
|
||||
" /*color:white;*/\n"
|
||||
" /*背景颜色*/\n"
|
||||
" /*background-color:rgb(14 , 150 , 254);*/\n"
|
||||
" /*边框圆角半径为8像素*/\n"
|
||||
" /*border-radius:8px;*/\n"
|
||||
"}")
|
||||
self.info_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.info_label.setObjectName("info_label")
|
||||
self.gridLayout.addWidget(self.info_label, 0, 0, 1, 1)
|
||||
self.confirm_bt = QtWidgets.QPushButton(message_box_ui)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.confirm_bt.sizePolicy().hasHeightForWidth())
|
||||
self.confirm_bt.setSizePolicy(sizePolicy)
|
||||
self.confirm_bt.setMinimumSize(QtCore.QSize(0, 130))
|
||||
self.confirm_bt.setAcceptDrops(False)
|
||||
self.confirm_bt.setStyleSheet("/*按钮普通态*/\n"
|
||||
"QPushButton\n"
|
||||
"{\n"
|
||||
" /*字体为微软雅黑*/\n"
|
||||
" font-family:Microsoft Yahei;\n"
|
||||
" /*字体大小为20点*/\n"
|
||||
" font-size:25pt;\n"
|
||||
" /*字体颜色为白色*/ \n"
|
||||
" /*color:white;*/\n"
|
||||
" /*背景颜色*/ \n"
|
||||
" background-color:rgb(225 , 225 , 225);\n"
|
||||
" /*边框圆角半径为8像素*/ \n"
|
||||
" border-radius:20px;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"/*按钮停留态*/\n"
|
||||
"QPushButton:hover\n"
|
||||
"{\n"
|
||||
" /*背景颜色*/ \n"
|
||||
" background-color:rgb(44 , 137 , 255);\n"
|
||||
" /*边框圆角半径为8像素*/\n"
|
||||
" /*border-radius:20px;*/\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"/*按钮按下态*/\n"
|
||||
"QPushButton:pressed\n"
|
||||
"{\n"
|
||||
" /*背景颜色*/ \n"
|
||||
" background-color:rgb(255 , 0 , 0);\n"
|
||||
"\n"
|
||||
" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
|
||||
" padding-left:3px;\n"
|
||||
"\n"
|
||||
" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
|
||||
" padding-top:3px;\n"
|
||||
"}")
|
||||
self.confirm_bt.setObjectName("confirm_bt")
|
||||
self.gridLayout.addWidget(self.confirm_bt, 1, 0, 1, 1)
|
||||
|
||||
self.retranslateUi(message_box_ui)
|
||||
QtCore.QMetaObject.connectSlotsByName(message_box_ui)
|
||||
|
||||
def retranslateUi(self, message_box_ui):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
message_box_ui.setWindowTitle(_translate("message_box_ui", "提示"))
|
||||
self.info_label.setText(_translate("message_box_ui", "提示信息"))
|
||||
self.confirm_bt.setText(_translate("message_box_ui", "确定"))
|
106
library/message_box_ui.ui
Normal file
106
library/message_box_ui.ui
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>message_box_ui</class>
|
||||
<widget class="QDialog" name="message_box_ui">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>487</width>
|
||||
<height>385</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>提示</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="info_label">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel
|
||||
{
|
||||
/*字体为微软雅黑*/
|
||||
font-family:Microsoft Yahei;
|
||||
/*字体大小为20点*/
|
||||
font-size:30pt;
|
||||
/*字体颜色为白色*/
|
||||
/*color:white;*/
|
||||
/*背景颜色*/
|
||||
/*background-color:rgb(14 , 150 , 254);*/
|
||||
/*边框圆角半径为8像素*/
|
||||
/*border-radius:8px;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>提示信息</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="confirm_bt">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>130</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">/*按钮普通态*/
|
||||
QPushButton
|
||||
{
|
||||
/*字体为微软雅黑*/
|
||||
font-family:Microsoft Yahei;
|
||||
/*字体大小为20点*/
|
||||
font-size:25pt;
|
||||
/*字体颜色为白色*/
|
||||
/*color:white;*/
|
||||
/*背景颜色*/
|
||||
background-color:rgb(225 , 225 , 225);
|
||||
/*边框圆角半径为8像素*/
|
||||
border-radius:20px;
|
||||
}
|
||||
|
||||
/*按钮停留态*/
|
||||
QPushButton:hover
|
||||
{
|
||||
/*背景颜色*/
|
||||
background-color:rgb(44 , 137 , 255);
|
||||
/*边框圆角半径为8像素*/
|
||||
/*border-radius:20px;*/
|
||||
}
|
||||
|
||||
/*按钮按下态*/
|
||||
QPushButton:pressed
|
||||
{
|
||||
/*背景颜色*/
|
||||
background-color:rgb(255 , 0 , 0);
|
||||
|
||||
/*左内边距为3像素,让按下时字向右移动3像素*/
|
||||
padding-left:3px;
|
||||
|
||||
/*上内边距为3像素,让按下时字向下移动3像素*/
|
||||
padding-top:3px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>确定</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
81
library/multithread.py
Normal file
81
library/multithread.py
Normal file
@ -0,0 +1,81 @@
|
||||
import sys, traceback
|
||||
from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, pyqtSlot
|
||||
|
||||
class WorkerSignals(QObject):
|
||||
'''
|
||||
Defines the signals available from a running worker thread.
|
||||
|
||||
Supported signals are:
|
||||
|
||||
finished
|
||||
No data
|
||||
|
||||
error
|
||||
`tuple` (exctype, value, traceback.format_exc() )
|
||||
|
||||
result
|
||||
`object` data returned from processing, anything
|
||||
|
||||
progress
|
||||
`int` indicating % progress
|
||||
|
||||
# 信号必须定义为类属性,不能放在__init__方法里
|
||||
'''
|
||||
finished = pyqtSignal()
|
||||
error = pyqtSignal(tuple)
|
||||
result = pyqtSignal(object)
|
||||
progress = pyqtSignal(int) # 可以用作进度条
|
||||
|
||||
serial = pyqtSignal(object) # 2record_system_v26的此信号移动到类SerialPort中了
|
||||
|
||||
image_signal = pyqtSignal(dict) # 只用在2record_system_v25中
|
||||
spectral_signal = pyqtSignal(dict) # 只用在2record_system_v25中
|
||||
|
||||
openinfo = pyqtSignal(int) # 只用在2record_system_v25中
|
||||
plotsignal = pyqtSignal() # 2record_system_v26的此信号移动到类ImageWindowPhone中了
|
||||
|
||||
# https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
|
||||
# 用于qt多线程:运行long-time task
|
||||
class Worker(QRunnable):
|
||||
'''
|
||||
Worker thread
|
||||
|
||||
Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
|
||||
|
||||
:param callback: The function callback to run on this worker thread. Supplied args and
|
||||
kwargs will be passed through to the runner.
|
||||
:type callback: function
|
||||
:param args: Arguments to pass to the callback function
|
||||
:param kwargs: Keywords to pass to the callback function
|
||||
|
||||
'''
|
||||
|
||||
def __init__(self, fn, *args, **kwargs):
|
||||
super(Worker, self).__init__()
|
||||
|
||||
# Store constructor arguments (re-used for processing)
|
||||
self.fn = fn
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.signals = WorkerSignals()
|
||||
|
||||
# Add the callback to our kwargs
|
||||
# self.kwargs['progress_callback'] = self.signals.progress
|
||||
|
||||
@pyqtSlot()
|
||||
def run(self):
|
||||
'''
|
||||
Initialise the runner function with passed args, kwargs.
|
||||
'''
|
||||
try: # 如果有错,就捕捉错误
|
||||
result = self.fn(*self.args, **self.kwargs)
|
||||
except Exception: # 根据错误进行处理
|
||||
traceback.print_exc()
|
||||
exctype, value = sys.exc_info()[:2]
|
||||
|
||||
self.signals.error.emit((exctype, value, traceback.format_exc()))
|
||||
else: # 如果没有错误执行下面代码
|
||||
self.signals.finished.emit() # Done
|
||||
self.signals.result.emit(result) # Return the result of the processing
|
||||
finally: # 不管有错无错,都要执行下面代码
|
||||
pass
|
Reference in New Issue
Block a user