craft-software/Legacy/TF_Control/Result_window_control.py
2025-07-04 15:52:40 +02:00

536 lines
29 KiB
Python

from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
import multiprocessing
import multiprocessing.managers
import time
import traceback,sys,os
import numpy as np
import pyqtgraph as pg
from scripts import import_txt
import random
from scipy.optimize import curve_fit
# Get the current script's directory
current_dir = os.path.dirname(os.path.abspath(__file__))
# Get the parent directory by going one level up
parent_dir = os.path.dirname(current_dir)
# Add the parent directory to sys.path
sys.path.append(parent_dir)
from design_files.Result_window_design import Ui_MainWindow
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
'''
finished = pyqtSignal()
error = pyqtSignal(tuple)
result = pyqtSignal(object)
progress = pyqtSignal(list)
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.
'''
# Retrieve args/kwargs here; and fire processing using them
try:
result = self.fn(*self.args, **self.kwargs)
except:
traceback.print_exc()
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
else:
self.signals.result.emit(result) # Return the result of the processing
finally:
self.signals.finished.emit() # Done
def get_float(Qline,default = 0): #gets value from QLineEdit and converts it to float. If text is empty or cannot be converted, it returns "default" which is 0, if not specified
try:
out = float(Qline.text())
except:
out = default
return(out)
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
# Get the current script's directory
self.current_dir = os.path.dirname(os.path.abspath(__file__))
# Get the parent directory by going one level up
self.parent_dir = os.path.dirname(current_dir)
#import Gui from QT designer file
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
#setup plot
self.graphWidget_B.setBackground('w')
self.graphWidget_B.setTitle("Trapped flux vs. B-field")
self.graphWidget_B.setLabel('bottom', 'Absolute magnetic field |B| (µT)')
self.graphWidget_B.setLabel('left', 'Trapped flux (µT)')
self.graphWidget_Gradient.setBackground('w')
self.graphWidget_Gradient.setTitle("Trapped flux vs. temperature gradient")
self.graphWidget_Gradient.setLabel('bottom', 'Temperature gradient (K/cm)')
self.graphWidget_Gradient.setLabel('left', 'Trapped flux (µT)')
self.graphWidget_CooldownSpeed.setBackground('w')
self.graphWidget_CooldownSpeed.setTitle("Trapped flux vs. cooldown speed (K/s)")
self.graphWidget_CooldownSpeed.setLabel('bottom', 'Cooldown speed (K/s)')
self.graphWidget_CooldownSpeed.setLabel('left', 'Trapped flux (µT)')
self.graphWidget_TransitionTime.setBackground('w')
self.graphWidget_TransitionTime.setTitle("Trapped flux vs. transition time (K/s)")
self.graphWidget_TransitionTime.setLabel('bottom', 'Tansition time (s)')
self.graphWidget_TransitionTime.setLabel('left', 'Trapped flux (µT)')
pen1 = pg.mkPen(color=(255, 255, 255), width=2)
self.plot_B = self.graphWidget_B.plot([1,0],[1,0],pen = pen1, name = 'B', symbol ='x', symbolPen ='r', symbolBrush = 0.2)
self.plot_Gradient = self.graphWidget_Gradient.plot([1,0],[1,0],pen = pen1, name = 'B', symbol ='x', symbolPen ='r', symbolBrush = 0.2)
self.plot_CooldownSpeed = self.graphWidget_CooldownSpeed.plot([1,0],[1,0],pen = pen1, name = 'B', symbol ='x', symbolPen ='r', symbolBrush = 0.2)
self.plot_trans_time = self.graphWidget_TransitionTime.plot([1,0],[1,0],pen = pen1, name = 'B', symbol ='x', symbolPen ='r', symbolBrush = 0.2)
# self.graphWidget_B.addLegend()
#set up pyQT threadpool
self.threadpool = QThreadPool()
#define signals and slots
self.actionSet_default.triggered.connect(self.set_default)
self.actionReset_default.triggered.connect(self.read_default)
self.button_refresh.clicked.connect(self.import_data)
self.listWidget_files.itemSelectionChanged.connect(self.list_changed)
self.button_select_all.clicked.connect(self.select_all)
self.comboBox_plot_settings.currentIndexChanged.connect(self.set_plot_settings)
self.comboBox_select_sensor.currentIndexChanged.connect(self.update_plots)
self.line_Plot_B_Field.editingFinished.connect(self.update_plots)
self.line_Plot_T_Gradients.editingFinished.connect(self.update_plots)
self.line_Plot_B_Field.editingFinished.connect(self.update_plots)
self.dSB_Plot_B_Field_Tolerance.valueChanged.connect(self.set_Tolerances)
self.dSB_Plot_Cooldown_Speed_Tolerance.valueChanged.connect(self.set_Tolerances)
self.dSB_Plot_T_Gradients_Tolerance.valueChanged.connect(self.set_Tolerances)
self.dSB_Plot_Transition_Time_Tolerance.valueChanged.connect(self.set_Tolerances)
# self.actionSet_default.triggered.connect(self.set_default)
# self.actionReset_default.triggered.connect(self.read_default)
#define constants
self.Npoints = 200 #number of point to plot
self.files_selected = []
self.file_path = 0 #File path for loading calibration
self.running = True #true while app is running
self.disable_plot = False #constant to disable plot to improve performance. Is changed by checkbox checkBox_disableplots
self.select_mean_single = 0 #Select if mean value of all absolute AMR-B-fields or a single sensor should be selected. (0: Mean of abs., 1: Abs. of single sensor, 2: Single sensor direction)
self.B_Tolerance = 0 #Tolerance when searching for specific B-fields
self.Gradient_Tolerance = 0 #Tolerance when searching for specific T-Gradients
self.Cooldown_Speed_Tolerance = 0 #Tolerance when searching for specific Cooldown-Speeds
self.row_length = 96 #Standard row-length (#columns) of data_array. This value will be updated in import_data
self.mcol = ["#0072BD","#D95319","#EDB120","#7E2F8E","#77AC30","#4DBEEE","#A2142F","#0072BD","#D95319","#EDB120","#7E2F8E","#77AC30","#4DBEEE","#A2142F"] #define matlab colors
self.marker = ['x','o','s','t','d','+','p','arrow_up','t1','h','crosshair','t3','star','arrow_down'] #some marker styles for plotting
self.lines_config_float = []#is used for config file
self.lines_config_strings = [self.line_Plot_B_Field, self.line_Plot_T_Gradients,
self.line_Plot_Cooldown_Speed, self.line_Plot_Transition_Time,
self.line_Path]#is used for config file
self.checkboxes_config = []#is used for config file
self.combobox_config = [self.comboBox_plot_settings, self.comboBox_select_sensor]#is used for config file
self.SB_config = [self.dSB_Plot_B_Field_Tolerance,self.dSB_Plot_T_Gradients_Tolerance,
self.dSB_Plot_Cooldown_Speed_Tolerance,self.dSB_Plot_Transition_Time_Tolerance]
#read default values from config and set them in gui
self.read_default()
def import_data(self):
#imports data from folder and fills list. After it is finished it calls update_plots
path = self.line_Path.text()
try: #if path does not exists nothing is plotted
files = os.listdir(path)
except:
print('Error: Please enter valid path')
return
self.data = {}
selected = self.files_selected #store old selected items so it not overwritten when new data is set in list
self.listWidget_files.clear()
#store data from all files in data
for p in files:
[header,data_arr,times] = import_txt.read_w3dates(path+'\\'+p, '%Y-%m-%d_%H-%M-%S',delim = '\t')
self.data[f"{p}"] = [header[0],data_arr,times] #header ist list in list, therefore, header[0]
self.listWidget_files.addItem(f"{p}") #put files in list
#fill file list and check the one previously checked
for i in selected:
self.listWidget_files.setCurrentIndex(i)
if files != []:
try:
self.row_length = len(self.data[f"{files[0]}"][1][0,:]) #Update row length (# columns) of data array. Until now its value is 96
except:
print("File "+str(files[0])+" is empty.")
if selected != []: #Update plots automatically when refreshing / reloading updated measurements
self.update_plots()
def list_changed(self):
#Updates self.files_selected. It is executed when an item in list is selected.
self.files_selected = self.listWidget_files.selectedIndexes()
self.update_plots()
def select_all(self):
#activates all files refreshes.
self.listWidget_files.selectAll()
self.files_selected = self.listWidget_files.selectedIndexes()
self.import_data()
def update_plots(self):
#only use selected files:
data_all = np.empty((0,self.row_length))
for i in self.listWidget_files.selectedItems():
data_all = np.append(data_all,self.data[i.text()][1],0)
if len(data_all[:,0]) == 0: #Just in case nothing is loaded. Plotting an empty array would cause error
return
#correct:
#0: time_start
#1: time_end_ramp
#2: time_save_point
#3,4,5,6 B fluxgates, including magnitude
#7: global gradient (from top and bottom sensor)
#8: average global gradient (average of local gradients)
#9: error of average global gradient
#10: transition time
#11: average global cooldown rate
#12: error of average global cooldown rate
#13: List of local gradients
#14: List of local cooldown rates
#15,...,59: B AMR (ext. B applied, sample superconducting)
#60,...,104: B AMR (ext. B off) -> Trapped flux
#Pick out data from data_all (substract 3 from all indices compared to list
#above, since times are not included in data_all)
B_start = data_all[:,0:4]
gradient = data_all[:,5:7]
trans_time = data_all[:,7]
rate = data_all[:,8:10]
B_TF = data_all[:,57:102]
#calculate Magnitude of B_TF of all cooldowns
B_TF_mag = np.empty((len(B_TF),15))
for i in range(len(B_TF)):
B_TF_mag[i,:] = [np.sqrt(x**2+y**2+z**2) for x,y,z in zip(B_TF[i,0:15],B_TF[i,15:30],B_TF[i,30:45])]
#Select trapped flux
if self.select_mean_single == 0: #Mean of all absolute values (all sensors)
B_TF = np.mean(B_TF_mag, axis = 1)
elif self.select_mean_single == 1: ##Absolute value of one sensor
B_TF = B_TF_mag[:,self.comboBox_select_sensor.currentIndex()]
elif self.select_mean_single == 2: #Value of single sensor in one direction
B_TF = B_TF[:,self.comboBox_select_sensor.currentIndex()]
#sort the data according to the three lines and tolerances
#get lists of sorting values
B_sort = self.line_Plot_B_Field.text().split(sep=',')
T_sort = self.line_Plot_T_Gradients.text().split(sep=',')
S_sort = self.line_Plot_Cooldown_Speed.text().split(sep=',')
TT_sort = self.line_Plot_Transition_Time.text().split(sep=',')
if B_sort != ['']:
B_sort = [float(x) for x in B_sort]
if T_sort != ['']:
T_sort = [float(x) for x in T_sort]
if S_sort != ['']:
S_sort = [float(x) for x in S_sort]
if TT_sort != ['']:
TT_sort = [float(x) for x in TT_sort]
sort = [B_sort,T_sort,S_sort,TT_sort]
tolerances = [self.dSB_Plot_B_Field_Tolerance.value(),self.dSB_Plot_T_Gradients_Tolerance.value(),
self.dSB_Plot_Cooldown_Speed_Tolerance.value(),self.dSB_Plot_Transition_Time_Tolerance.value()]
#sort out data depending on how the lines are filled. If no line has more than one entry, sort out points that do not fall in the tolerances. If one line has more than one entry, create multiple plots. If more than one line has entries, return error.
ind = []
lens = I = [len(x) for x in [B_sort,T_sort,S_sort,TT_sort] if len(x) > 1]
if len(lens) == 0: #no line has more than one entry => only sort out points that do not fall in the tolerances
for i in range(len(data_all)):
skip = False #if skip is True, the index will not be appended to ind. Default is False
point_data = [B_start[i,1], gradient[i,0],
rate[i,0], trans_time[i]] #get data of the point which will be compared to the sort values.
for d,s,t in zip(point_data,sort,tolerances): #go through all sorting values, if any condition is not fullfilled the index is not appended to ind
if s != ['']: #check is the sorting value is not empty. If it is empty, the loop iteration is not skipped
if abs(d - s[0]) >= t: #check if the point is within the tolerances
skip = True #only if the point does not fall within the tolerances, skip is set to True and index will not be appended to ind
if skip == False:
ind.append(i) #append index of points that fall in the tolerances
#plot data
#create error array (systematic error = 2µT)
e_B_TF = np.full(len(B_TF[ind]),2)
#clear graph widgets and add new plots
for i,w in enumerate([self.graphWidget_B, self.graphWidget_Gradient,
self.graphWidget_CooldownSpeed,
self.graphWidget_TransitionTime
]):
w.clear()
if i == 0: #graph B
self.scatter_B = pg.ScatterPlotItem(x = B_start[ind,1], y = B_TF[ind], pen=pg.mkPen(color = self.mcol[0]), brush = pg.mkBrush(color = self.mcol[0]), symbol ='x', hoverable = True, size = 10)
err = pg.ErrorBarItem(x = B_start[ind,1], y = B_TF[ind], top = e_B_TF, bottom = e_B_TF, pen=pg.mkPen(color = self.mcol[0], width = 2))
w.addItem(self.scatter_B)
w.addItem(err)
elif i == 1: #graph gradient
self.scatter_Gradient = pg.ScatterPlotItem(x = gradient[ind,0],y = B_TF[ind], pen=pg.mkPen(color = self.mcol[0]), brush = pg.mkBrush(color = self.mcol[0]), symbol ='x', hoverable = True, size = 10)
err = pg.ErrorBarItem(x = gradient[ind,0], y = B_TF[ind], left = gradient[ind,1], right = gradient[ind,1], top = e_B_TF, bottom = e_B_TF, pen=pg.mkPen(color = self.mcol[0], width = 2))
w.addItem(self.scatter_Gradient)
w.addItem(err)
elif i == 2: #graph cooldown speed
self.scatter_CooldownSpeed = pg.ScatterPlotItem(x = rate[ind,0], y = B_TF[ind], pen=pg.mkPen(color = self.mcol[0]), brush = pg.mkBrush(color = self.mcol[0]), symbol ='x', hoverable = True, size = 10)
# err = pg.ErrorBarItem(x = rate[ind,0], y = B_TF[ind], left = rate[ind,1], right = rate[ind,1], top = e_B_TF, bottom = e_B_TF, pen=pg.mkPen(color = self.mcol[0], width = 2))
w.addItem(self.scatter_CooldownSpeed)
elif i == 3: #graph transition time
self.scatter_transitionTime = pg.ScatterPlotItem(x = trans_time[ind], y = B_TF[ind], pen=pg.mkPen(color = self.mcol[0]), brush = pg.mkBrush(color = self.mcol[0]), symbol ='x', hoverable = True, size = 10)
err = pg.ErrorBarItem(x = trans_time[ind], y = B_TF[ind], top = e_B_TF, bottom = e_B_TF, pen=pg.mkPen(color = self.mcol[0], width = 2))
w.addItem(self.scatter_transitionTime)
elif len(lens) == 1: #one line has more than one entry. So a set of plots should be generated from this line
ind_dict = {} #dictionary in which the sorted data will be saved
labels = [] #list in which labels of plots will be saved
#find sorting list with more than one entry
I = [i for i,x in enumerate(sort) if len(x) > 1]
I = I[0]
if len(B_sort) > 1:
for B in B_sort: #Find indices of data points where B = value in B_sort
ind = [i for i,x in enumerate(B_start[:,1]) if abs(x-B)<tolerances[0]]
ind_dict[str(B)] = ind
labels.append(f"B = {B} µT")
elif len(T_sort) > 1:
for T in T_sort: #Find indices of data points where Gradient = value in T_sort
ind = [i for i,x in enumerate(gradient[:,0]) if abs(x-T)<tolerances[1]]
ind_dict[str(T)] = ind
labels.append(f"nabla T = {T} K/cm")
elif len(S_sort) > 1:
for S in S_sort: #Find indices of data points where cooldownrate = value in S_sort
ind = [i for i,x in enumerate(rate[:,0]) if abs(x-S)<tolerances[2]]
ind_dict[str(S)] = ind
labels.append(f"rate = {S} K/s")
elif len(TT_sort) > 1:
for TT in TT_sort: #Find indices of data points where TransitionTime = value in TT_sort
ind = [i for i,x in enumerate(trans_time[:,0]) if abs(x-TT)<tolerances[3]]
ind_dict[str(TT)] = ind
labels.append(f"Transition time = {TT} s")
#kick out any points that do not fall in the tolerances of the other lines
sort.pop(I) #pop out the sorting list with more than one entry wich is already used for sorting
tolerances.pop(I)
for key in ind_dict.keys(): #go through all points in ind_dict
pop=[] #list of indices to be popped out because to do not fit the tolerances
for i,ind in enumerate(ind_dict[key]):
point_data = [B_start[ind,1], gradient[ind,0], rate[ind,0], trans_time[ind]]
point_data.pop(I) #pop out data of sorting list which is already used
for d,s,t in zip(point_data,sort,tolerances): #go through all sorting values, if any condition is not fullfilled index is removed from the dictionary
if s != ['']: #check is the sorting value is not empty. If it is empty, the loop iteration is not skipped
if abs(d - s[0]) >= t: #check if the point outside the tolerance
pop.append(i)
break #get out of loop so no more indices are deleted
#delete indices that are in pop
ind_dict[key] = [x for i,x in enumerate(ind_dict[key]) if i not in pop]
#create error array (systematic error = 2µT)
e_B_TF = np.full(len(data_all),2)
#clear all graph widgets, add a legend and add new scatter plots
for i,w in enumerate([self.graphWidget_B, self.graphWidget_Gradient,
self.graphWidget_CooldownSpeed,
self.graphWidget_TransitionTime
]):
w.clear()
w.addLegend()
#add new scatter and errorbars to plots
for n,key in enumerate(ind_dict.keys()):
if i == 0: #graph B
scatter = pg.ScatterPlotItem(x = B_start[ind_dict[key],1], y = B_TF[ind_dict[key]], pen=pg.mkPen(color = self.mcol[n]), brush = pg.mkBrush(color = self.mcol[n]), symbol =self.marker[n], hoverable = True, size = 10, name = labels[n])
err = pg.ErrorBarItem(x = B_start[ind_dict[key],1], y = B_TF[ind_dict[key]], top = e_B_TF[:len(ind_dict[key])], bottom = e_B_TF[:len(ind_dict[key])], pen=pg.mkPen(color = self.mcol[n], width = 2))
self.graphWidget_B.addItem(scatter)
self.graphWidget_B.addItem(err)
if i == 1: #graph gradient
scatter = pg.ScatterPlotItem(x = gradient[ind_dict[key],0], y = B_TF[ind_dict[key]], pen=pg.mkPen(color = self.mcol[n]), brush = pg.mkBrush(color = self.mcol[n]), symbol =self.marker[n], hoverable = True, size = 10, name = labels[n])
err = pg.ErrorBarItem(x = gradient[ind_dict[key],0], y = B_TF[ind_dict[key]], top = e_B_TF[:len(ind_dict[key])], bottom = e_B_TF[:len(ind_dict[key])], left = gradient[ind_dict[key],1], right = gradient[ind_dict[key],1], pen=pg.mkPen(color = self.mcol[n], width = 2))
self.graphWidget_Gradient.addItem(scatter)
self.graphWidget_Gradient.addItem(err)
if i == 2: #graph cooldown rate
scatter = pg.ScatterPlotItem(x = rate[ind_dict[key],0], y = B_TF[ind_dict[key]], pen=pg.mkPen(color = self.mcol[n]), brush = pg.mkBrush(color = self.mcol[n]), symbol =self.marker[n], hoverable = True, size = 10, name = labels[n])
# err = pg.ErrorBarItem(x = rate[ind_dict[key],0], y = B_TF[ind_dict[key]], top = e_B_TF[:len(ind_dict[key])], bottom = e_B_TF[:len(ind_dict[key])], left = rate[ind_dict[key],1], right = rate[ind_dict[key],1], pen=pg.mkPen(color = self.mcol[n], width = 2))
self.graphWidget_CooldownSpeed.addItem(scatter)
# self.graphWidget_CooldownSpeed.addItem(err)
if i == 3: #graph transition time
scatter = pg.ScatterPlotItem(x = trans_time[ind_dict[key]], y = B_TF[ind_dict[key]], pen=pg.mkPen(color = self.mcol[n]), brush = pg.mkBrush(color = self.mcol[n]), symbol =self.marker[n], hoverable = True, size = 10, name = labels[n])
err = pg.ErrorBarItem(x = trans_time[ind_dict[key]], y = B_TF[ind_dict[key]], top = e_B_TF[:len(ind_dict[key])], bottom = e_B_TF[:len(ind_dict[key])], pen=pg.mkPen(color = self.mcol[n], width = 2))
self.graphWidget_TransitionTime.addItem(scatter)
self.graphWidget_TransitionTime.addItem(err)
elif len(lens) > 1:
print('ERROR: more than one sorting line has more than one entry. Please select only one line with more than one entry. Aborting...')
return
def set_Tolerances(self):
#Set tolerance values for filtering
self.B_Tolerance = self.dSB_Plot_B_Field_Tolerance.value()
self.Gradient_Tolerance = self.dSB_Plot_T_Gradients_Tolerance.value()
self.Cooldown_Speed_Tolerance = self.dSB_Plot_Cooldown_Speed_Tolerance.value()
self.Transition_Time_Tolerance = self.dSB_Plot_Transition_Time_Tolerance.value()
self.update_plots()
def set_plot_settings(self, value):
#Set plot settings (mean B-value of all AMR-sensors / absolute value of single sensor / single sensor direction)
self.select_mean_single = value
#set the right entries in qComboBox_select_sensor
if self.select_mean_single == 0: #Mean of all absolute values (all sensors)
self.comboBox_select_sensor.setEnabled(False)
self.comboBox_select_sensor.clear()
elif self.select_mean_single == 1: #Absolute value of one sensor
self.comboBox_select_sensor.setEnabled(True)
self.comboBox_select_sensor.clear()
for i in range(1,16): #Add 15 values
self.comboBox_select_sensor.addItem("Sensor "+str(i))
elif self.select_mean_single == 2: #Value of single sensor in one direction
self.comboBox_select_sensor.setEnabled(True)
self.comboBox_select_sensor.clear()
#Add 45 values
for i in range(1,16):
for direction in ["x", "y", "z"]:
self.comboBox_select_sensor.addItem("Sensor "+str(i) +" "+str(direction))
self.update_plots()
def nearest_value_in_array(self, array, value): #Returns index of closest entry in array compared to value
index = (np.abs(array - value)).argmin()
return(index)
def set_default(self):
#saves current set values to txt file in subdirectory configs. All entries that are saved are defined in self.lines_config
#Overwrites old values in config file.
current_dir = os.path.dirname(os.path.abspath(__file__))
path = current_dir+'\\configs\\result_window_config.txt' #To make shure the config file is at the right place, independent from where the program is started the location of the file is retrieved
file = open(path,'w')
for l in self.lines_config_float:
temp = f"{get_float(l)}"
file.write(temp+'\t')
for l in self.lines_config_strings:
file.write(l.text()+'\t')
for c in self.checkboxes_config:
file.write(str(c.isChecked())+'\t')
for c in self.combobox_config:
file.write(str(c.currentIndex())+'\t')
for SB in self.SB_config:
temp = f"{SB.value()}"
file.write(temp+'\t')
file.write('\n')
file.close
def read_default(self):
#reads default values from config file in subdirectory config and sets the values in gui. Then self.change is set to true so values are send
#to device. (If no config file exists, it does nothing.)
current_dir = os.path.dirname(os.path.abspath(__file__))
path = current_dir+'\\configs\\result_window_config.txt' #To make shure the config file is read from the right place, independent from where the program is started the location of the file is retrieved
try: #exit function if config file does not exist
vals = import_txt.read_raw(path)
except:
print('no config file found on')
print(path)
return
formats = ['.2f', '.2f', '.2f','.2f','.2f','.0f']
for l,v,f in zip(self.lines_config_float,vals[0],formats):
v = float(v) #convert string in txt to float, so number can be formatted according to "formats" when it's set
l.setText(format(v,f))
for l,v in zip(self.lines_config_strings,vals[0][len(self.lines_config_float):]):
l.setText(v)
for c,v in zip(self.checkboxes_config,vals[0][len(self.lines_config_float)+
len(self.lines_config_strings):]):
c.setChecked(v == 'True')
for c,v in zip(self.combobox_config,vals[0][len(self.lines_config_float)+
len(self.lines_config_strings)+
len(self.checkboxes_config):]):
c.setCurrentIndex(int(v))
for SB,v in zip(self.SB_config,vals[0][len(self.lines_config_float)+
len(self.lines_config_strings)+
len(self.checkboxes_config)+
len(self.combobox_config):]):
v = float(v)
SB.setValue(v)
self.change = True
def closeEvent(self,event): #when window is closed self.running is set to False, so all threads stop
self.running = False
time.sleep(1)
event.accept()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()