Ejemplo n.º 1
0
class MyView(QWidget):
    def __init__(self, windowTitle, posX, posY, sizeX, sizeY):
        self.app = QApplication(sys.argv)
        super().__init__()
        print("MyView::__init__(windowTitle, posX, posY, sizeX, sizeY)")
        self.setGeometry(posX, posY, sizeX, sizeY)
        self.setWindowTitle(windowTitle)
	#setting up the Vertical Layout
        self.control_layout = QVBoxLayout()
        self.setLayout(self.control_layout)
	#setting up the button widget
        self.button = QPushButton()
        self.button.setFixedSize(40, 40)
        self.button.setText("+")
        self.button.clicked.connect(self.buttonClicked)
	#setting up the Counter widget 
        self.timer = QLCDNumber()
        self.timer.setNumDigits(4)
        self.timer.setStyleSheet("QLCDNumber {color: pink;}")
        self.timer.setFixedWidth(400)
        #self.timer.display(self.getVal())
        self.control_layout.addWidget(self.timer)
        self.control_layout.addWidget(self.button)
        self.show()
    def getVal(self,val):
        self.timer.display(val)
    def keyPressEvent(self, e):
        if e.key():
            print("Key +1")
            return "a"
    def buttonClicked(self):
        print("Button +1")
        return True
    def run(self):
        sys.exit(self.app.exec_())
Ejemplo n.º 2
0
class TimeSettingWidget(QWidget):
    def __init__(self, parent=None):
        super(TimeSettingWidget, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.lcd = QLCDNumber(self)
        self.lcd.setNumDigits(2)
        self.lcd.setMinimumHeight(80)
        self.lcd.setStyleSheet("QLCDNumber{ color: black;}")
        self.sld = QSlider(Qt.Horizontal, self)
        self.sld.setMinimum(1)
        self.sld.setMaximum(90)

        self.vbox = QVBoxLayout()
        self.vbox.addWidget(self.lcd)
        self.vbox.addWidget(self.sld)

        self.setLayout(self.vbox)
        self.sld.valueChanged.connect(self.lcd.display)

    def setTime(self, t):
        self.sld.setValue(t)

    def setDisplayTime(self, t):
        self.lcd.display(t)

    def setActiveStyle(self):
        self.lcd.setStyleSheet("QLCDNumber{ color: green;}")

    def setInactiveStyle(self):
        self.lcd.setStyleSheet("QLCDNumber{ color: black;}")

    def setSliderEnable(self, bool):
        self.sld.setEnabled(bool)

    def freshDisplayTime(self):
        self.lcd.display(self.sld.value())

    def getTime(self):
        return self.sld.value()
Ejemplo n.º 3
0
class ClassMain(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.dong_ho = QLCDNumber(self)
        self.dong_ho.setNumDigits(8)
        self.dong_ho.setGeometry(10, 10, 280, 80)

        dem_gio = QTimer(self)
        dem_gio.timeout.connect(self.hien_gio)
        dem_gio.start(1000)

        self.setWindowTitle('Vsmart CARPARKING SYSTEM V.1.01')
        self.setWindowIcon(QIcon('clock.png'))
        self.resize(300, 100)  #setFixedSize(300,100)
        self.show()

    def hien_gio(self):
        self.dong_ho.display(strftime("%H" + ":" + "%M" + ":" + "%S"))
Ejemplo n.º 4
0
class Trigan_Result_Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        global COUNT_TRUES_EQUATIONS, begin
        global COUNT_TRIES_EQUATIONS

        self.f_r = open("info", mode='r')
        self.frm = QFrame(self)
        self.frm.setStyleSheet("QWidget { background-color: %s }" %
                               self.f_r.read(7))
        self.frm.setGeometry(0, 0, 2000, 1000)

        self.setGeometry(500, 300, 400, 200)
        self.setWindowTitle('Результаты работы')

        self.lcdNumber = QLCDNumber(self)
        self.lcdNumber.setGeometry(QtCore.QRect(0, 0, 80, 35))
        self.lcdNumber.move(300, 10)
        self.lcdNumber.setNumDigits(5)
        self.str1 = "{:0>2d}:{:0>2d}".format(begin // 60, begin % 60)
        self.lcdNumber.display(self.str1)

        self.result_label = QLabel(self)
        self.result_label.setText(
            f"Ваш результат: {COUNT_TRUES_EQUATIONS} из {COUNT_TRIES_EQUATIONS}"
        )
        self.result_label.setFont(
            QtGui.QFont("Currently only TrueType fonts", 14))
        self.result_label.resize(300, 50)
        self.result_label.move(70, 70)
        self.f_r.seek(14)
        self.result_label.setStyleSheet("QLabel {color: %s;}" %
                                        self.f_r.read(7))
        COUNT_TRIES_EQUATIONS = 0
        COUNT_TRUES_EQUATIONS = 0

        begin = 0

        self.back_btn = QPushButton('← Меню', self)
        self.back_btn.resize(90, 30)
        self.back_btn.move(10, 160)
        self.f_r.seek(7)
        self.back_btn.setStyleSheet(
            "QPushButton { background-color: %s; border: %s; color: %s}" %
            (self.f_r.read(7), None, self.f_r.read(7)))

        self.qu_btn = QPushButton('↺ Заново', self)
        self.qu_btn.resize(90, 30)
        self.qu_btn.move(110, 160)
        self.f_r.seek(7)
        self.qu_btn.setStyleSheet(
            "QPushButton { background-color: %s; border: %s; color: %s}" %
            (self.f_r.read(7), None, self.f_r.read(7)))
        self.f_r.close()

        self.back_btn.clicked.connect(self.back)
        self.qu_btn.clicked.connect(self.ques)

    def back(self):
        self.back_form = MainMenu()
        self.back_form.show()
        self.close()

    def ques(self):
        self.ques_form = Trigan_Window()
        self.ques_form.show()
        self.close()
Ejemplo n.º 5
0
class Trigan_Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        global TIMER, COUNT_ARRAY
        global TIME_COUNT, array

        TIMER = 1

        self.f_r = open("info", mode='r')
        self.frm = QFrame(self)
        self.frm.setStyleSheet("QWidget { background-color: %s }" %
                               self.f_r.read(7))
        self.frm.setGeometry(0, 0, 2000, 1000)

        self.setGeometry(400, 200, 500, 450)
        self.setWindowTitle('Формулы приведения')

        con = sqlite3.connect("name_users.db")
        cur = con.cursor()

        self.answer_name_label = QLabel(self)
        self.answer_name_label.setText("Введите ваш ответ: ")
        self.answer_name_label.resize(250, 50)
        self.answer_name_label.move(0, 380)
        self.f_r.seek(14)
        self.answer_name_label.setStyleSheet("QLabel {color: %s;}" %
                                             self.f_r.read(7))

        self.rec_btn = QPushButton('Следующий', self)
        self.rec_btn.resize(480, 170)
        self.rec_btn.move(10, 200)
        self.f_r.seek(7)
        self.rec_btn.setStyleSheet(
            "QPushButton { background-color: %s; border: %s; color: %s}" %
            (self.f_r.read(7), None, self.f_r.read(7)))
        self.f_r.close()

        font = QtGui.QFont()
        font.setPointSize(17)
        self.rec_btn.setFont(font)

        self.rec_btn.clicked.connect(self.recursion)

        result = cur.execute("""SELECT * FROM Trigonometry
                                                            WHERE Way like '%'"""
                             )
        if COUNT_ARRAY == 0:
            array = list(result)
            random.shuffle(array)

        self.true_answers = []
        self.player_answers = []

        self.way = array[COUNT_ARRAY]
        self.true_answers.append(self.way[1])

        self.pixmap = QPixmap(self.way[0])
        self.image = QLabel(self)
        self.image.move(85, 10)
        self.image.resize(330, 160)
        self.image.setPixmap(self.pixmap)

        self.answer_input = QLineEdit(self)
        self.answer_input.resize(150, 30)
        self.answer_input.move(160, 390)

        self.player_answers.append(self.answer_input.text())

        self.lcdNumber = QLCDNumber(self)
        self.lcdNumber.setGeometry(QtCore.QRect(0, 0, 80, 35))
        self.lcdNumber.move(400, 390)
        self.lcdNumber.setNumDigits(5)
        self.str1 = "{:0>2d}:{:0>2d}".format(begin // 60, begin % 60)
        self.lcdNumber.display(self.str1)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.showTime)
        self.timer.start(1000)

        con.commit()
        con.close()

    def recursion(self):
        global COUNT_TRIES_EQUATIONS, begin
        global COUNT_TRUES_EQUATIONS, COUNT_ARRAY

        self.timer.stop()

        if str(self.answer_input.text()) == str(self.true_answers[-1]):
            COUNT_TRUES_EQUATIONS += 1

        COUNT_TRIES_EQUATIONS += 1
        COUNT_ARRAY += 1

        if COUNT_TRIES_EQUATIONS < 32:
            self.rec_form = Trigan_Window()
            self.rec_form.show()
            self.close()
        else:
            COUNT_ARRAY = 0
            self.res_form = Trigan_Result_Window()
            self.res_form.show()
            self.close()

    def showTime(self):
        global begin
        begin = begin + 1
        self.str1 = "{:0>2d}:{:0>2d}:{:0>2d}".format(begin // 3600,
                                                     (begin % 3600) // 60,
                                                     begin % 60)
        self.lcdNumber.display(self.str1)
Ejemplo n.º 6
0
class EnglishWordRelay(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.word = Word('words.txt')

        mainLayout = QGridLayout()

        # timer 관련 위젯 생성
        lcdlbl = QLabel("Timer")
        lcdlbl.setAlignment(Qt.AlignRight)

        mainLayout.addWidget(lcdlbl, 0, 0)
        self.timeLcd = QLCDNumber()
        mainLayout.addWidget(self.timeLcd, 0, 1)
        self.timeLcd.setNumDigits(2)
        self.timeLcd.display('10')

        # score 관련 위젯 생성
        scorelbl = QLabel("Score")
        mainLayout.addWidget(scorelbl, 0, 2)
        scorelbl.setAlignment(Qt.AlignRight)

        self.scoreLcd = QLineEdit()
        self.scoreLcd.setReadOnly(True)
        self.scoreLcd.setAlignment(Qt.AlignRight)
        font = self.scoreLcd.font()
        font.setPointSize(font.pointSize() + 15)
        self.scoreLcd.setFont(font)
        self.scoreLcd.setFixedWidth(100)
        mainLayout.addWidget(self.scoreLcd, 0, 3)

        # 단어 message 위젯 설정
        self.message = QLineEdit()
        self.message.setReadOnly(True)
        self.message.setAlignment(Qt.AlignCenter)
        font = self.message.font()
        font.setPointSize(font.pointSize() + 8)
        self.message.setFont(font)
        self.message.setMaxLength(52)
        mainLayout.addWidget(self.message, 1, 0, 1, 4)

        # Input 위젯 설정
        self.Input = QLineEdit()
        font = self.Input.font()
        font.setPointSize(font.pointSize() + 8)
        self.Input.setFont(font)
        self.Input.setMaxLength(20)
        # 게임에서 send 버튼의 클릭 기능을 엔터키로도 할 수 있게 기능 추가
        self.Input.returnPressed.connect(self.sendClicked)
        mainLayout.addWidget(self.Input, 2, 0, 1, 3)

        # sendButton 위젯 설정
        self.sendButton = QToolButton()
        self.sendButton.setText('Send')
        self.sendButton.clicked.connect(self.sendClicked)

        mainLayout.addWidget(self.sendButton, 2, 3)

        # newGameButton 위젯 설
        newGameButton = QToolButton()
        newGameButton.setText('New Game')
        newGameButton.clicked.connect(self.startGame)
        mainLayout.addWidget(newGameButton, 3, 0)

        self.setLayout(mainLayout)

        self.setWindowTitle('English Word Relay Game')
        self.setFixedSize(400, 300)
        self.move(750, 300)

        # 게임 시작
        self.startGame()

    def startGame(self):

        # 게임을 시작할 때마다 Timer, Score 클래스를 호출하여 제한 시간 10초, 점수 0점으로 초기화
        self.timer = Timer(self.timeLcd, self.message, self.scoreLcd,
                           self.sendButton, self.Input)
        self.scoreValue = Score()

        self.message.clear()
        self.Input.clear()
        self.message.setText(self.word.startRandFromDB())
        self.scoreLcd.setText(str(self.scoreValue.score))

        self.sendButton.setDisabled(False)
        self.Input.setReadOnly(False)

    def sendClicked(self):
        answer = self.Input.text()
        self.Input.clear()

        # 입력된 단어의 유효성 검사
        if self.word.testWord(answer):
            # 사용자의 입력의 마지막 글자로 시작하는 다음 단어 출력
            firstChar = answer.strip()[-1]
            self.message.setText(self.word.relayRandomFromDB(firstChar))
            # 점수 추가 & 점수 출력
            self.scoreValue.increaseScore(answer)
            self.scoreLcd.setText(str(self.scoreValue.score))
            # 시간 초기화
            if self.timer.gameTime > 0:
                self.timer.gameTime = 10
Ejemplo n.º 7
0
class Run_gui(QMainWindow):
    def __init__(self):
        super().__init__()

        self.cwd = os.getcwd()
        self.load_()

        # Enable antialiasing for prettier plots
        self.initUI()

    def initUI(self):

        ################### MENU BARS START ##################
        MyBar = QMenuBar(self)

        fileMenu = MyBar.addMenu("File")

        self.fileSave = fileMenu.addAction("Save thinfilm config")
        self.fileSave.triggered.connect(self.save_)
        self.fileSave.setShortcut('Ctrl+S')

        self.fileLoadAs = fileMenu.addAction("Load config section")
        self.fileLoadAs.triggered.connect(self.load_config_dialog)

        fileClose = fileMenu.addAction("Close")
        fileClose.triggered.connect(self.close)  # triggers closeEvent()
        fileClose.setShortcut('Ctrl+X')

        self.loadMenu = MyBar.addMenu("Load data")
        loadSubOlis = self.loadMenu.addAction("OLIS sub")
        loadSubFilmOlis = self.loadMenu.addAction("OLIS sub + thin film")
        loadSubFTIR = self.loadMenu.addAction("FTIR sub")
        loadSubFilmFTIR = self.loadMenu.addAction("FTIR sub + thin film")

        loadSubOlis.triggered.connect(self.loadSubOlisDialog)
        loadSubFilmOlis.triggered.connect(self.loadSubFilmOlisDialog)
        loadSubFTIR.triggered.connect(self.loadSubFTIRDialog)
        loadSubFilmFTIR.triggered.connect(self.loadSubFilmFTIRDialog)

        self.emailMenu = MyBar.addMenu("E-mail")
        self.emailSettings = self.emailMenu.addAction("E-mail settings")
        self.emailSettings.triggered.connect(self.email_set_dialog)
        self.emailData = self.emailMenu.addAction("E-mail data")
        self.emailData.triggered.connect(self.email_data_dialog)

        helpMenu = MyBar.addMenu("Help")
        helpParam = helpMenu.addAction("Instructions")
        helpParam.triggered.connect(self.helpParamDialog)
        contact = helpMenu.addAction("Contact")
        contact.triggered.connect(self.contactDialog)

        ################### MENU BARS END ##################

        # status info which button has been pressed
        Start_lbl = QLabel("PLOTS and analysis steps", self)
        Start_lbl.setStyleSheet("color: blue")

        self.Step0_Button = QPushButton("Raw data", self)
        self.Step0_Button.setToolTip("STEP 0. Plot raw data for OLIS and FTIR")
        self.button_style(self.Step0_Button, 'black')

        self.Step1_Button = QPushButton("Tmin and Tmax", self)
        self.Step1_Button.setToolTip(
            "STEP 1. Find all the minima and maxima positions using Gaussian filter"
        )
        self.button_style(self.Step1_Button, 'black')

        self.Step2_Button = QPushButton("Std.Dev. in d", self)
        self.Step2_Button.setToolTip(
            "STEP 2. Minimize standard deviation in the film thickness d")
        self.button_style(self.Step2_Button, 'black')

        self.Step3_Button = QPushButton("Index n", self)
        self.Step3_Button.setToolTip(
            "STEP 3. Plot refractive indicies n1 and n2")
        self.button_style(self.Step3_Button, 'black')

        self.Step4_Button = QPushButton("Absorption alpha", self)
        self.Step4_Button.setToolTip(
            "STEP 4. Plot abosorption alpha based on n2")
        self.button_style(self.Step4_Button, 'black')

        self.Step5_Button = QPushButton("Wavenumber k", self)
        self.Step5_Button.setToolTip("STEP 5. Plot wavenumber k based on n2")
        self.button_style(self.Step5_Button, 'black')

        ####################################################

        # status info which button has been pressed
        self.NewFiles = QLabel('No files created yet!', self)
        self.NewFiles.setStyleSheet("color: blue")

        newfont = QFont("Times", 10, QFont.Normal)
        self.NewFiles.setFont(newfont)
        '''
		self.NewFiles = numpy.zeros(5,dtype=object)
		for i in range(4):
			self.NewFiles[i] = QLabel(''.join([str(i+1),': ']), self)
			self.NewFiles[i].setStyleSheet("color: magenta")
		'''

        ####################################################
        loads_lbl = QLabel("RAW data files", self)
        loads_lbl.setStyleSheet("color: blue")

        configFile_lbl = QLabel("Current thinfilm", self)
        self.config_file_lbl = QLabel("", self)
        self.config_file_lbl.setStyleSheet("color: green")

        loadSubOlis_lbl = QLabel("OLIS sub", self)
        self.loadSubOlisFile_lbl = QLabel("", self)
        self.loadSubOlisFile_lbl.setStyleSheet("color: magenta")

        loadSubFilmOlis_lbl = QLabel("OLIS sub + thin film", self)
        self.loadSubFilmOlisFile_lbl = QLabel("", self)
        self.loadSubFilmOlisFile_lbl.setStyleSheet("color: magenta")

        loadSubFTIR_lbl = QLabel("FTIR sub", self)
        self.loadSubFTIRFile_lbl = QLabel("", self)
        self.loadSubFTIRFile_lbl.setStyleSheet("color: magenta")

        loadSubFilmFTIR_lbl = QLabel("FTIR sub + thin film", self)
        self.loadSubFilmFTIRFile_lbl = QLabel("", self)
        self.loadSubFilmFTIRFile_lbl.setStyleSheet("color: magenta")

        self.cb_sub_olis = QCheckBox('', self)
        self.cb_sub_olis.toggle()
        self.cb_subfilm_olis = QCheckBox('', self)
        self.cb_subfilm_olis.toggle()
        self.cb_sub_ftir = QCheckBox('', self)
        self.cb_sub_ftir.toggle()
        self.cb_subfilm_ftir = QCheckBox('', self)
        self.cb_subfilm_ftir.toggle()

        plot_X_lbl = QLabel("Plot X axis in", self)
        self.combo2 = QComboBox(self)
        self.mylist2 = ["eV", "nm"]
        self.combo2.addItems(self.mylist2)
        self.combo2.setFixedWidth(70)

        ####################################################

        lbl1 = QLabel("GAUSSIAN filter settings", self)
        lbl1.setStyleSheet("color: blue")

        interpol_lbl = QLabel("Interpolation method", self)
        self.combo4 = QComboBox(self)
        self.mylist4 = ["spline", "linear"]
        self.combo4.setToolTip(
            "Interpolation method for local minima Tmin and local maxima Tmax can only be linear or spline."
        )
        self.combo4.addItems(self.mylist4)
        self.combo4.setFixedWidth(70)

        factors_lbl = QLabel("Gaussian factors", self)
        self.factorsEdit = QLineEdit("", self)
        self.factorsEdit.setToolTip(
            "HIGH gaussian factor = broadband noise filtering.\nLOW gaussian factor = narrowband noise filtering.\nHigh gauissian factors (>2) will result in relatively large deviation from the raw data.\nGauissian factors of zero or near zero (<0.5) will closely follow trend of the raw data."
        )
        self.factorsEdit.setFixedWidth(200)

        borders_lbl = QLabel("Gaussian borders [eV]", self)
        self.bordersEdit = QLineEdit("", self)
        self.bordersEdit.setToolTip(
            "Gaussian borders should be typed in ascending order and the number of\nborders is always one more compared with the number of Gaussian factors."
        )
        self.bordersEdit.setFixedWidth(200)

        ##############################################

        lbl2 = QLabel("ABSORPTION alpha and n1 and n2", self)
        lbl2.setStyleSheet("color: blue")

        poly_lbl = QLabel("Polyfit order", self)
        self.combo1 = QComboBox(self)
        self.mylist1 = ["1", "2", "3", "4", "5"]
        self.combo1.addItems(self.mylist1)
        self.combo1.setFixedWidth(70)

        polybord_lbl = QLabel("Polyfit range(s) [eV]", self)
        self.poly_bordersEdit = QLineEdit("", self)
        self.poly_bordersEdit.setFixedWidth(140)

        self.cb_polybord = QCheckBox('', self)
        self.cb_polybord.toggle()

        ignore_data_lbl = QLabel("No. of ignored points", self)
        self.ignore_data_ptsEdit = QLineEdit("", self)
        self.ignore_data_ptsEdit.setFixedWidth(140)

        corr_slit_lbl = QLabel("Correction slit width [nm]", self)
        self.corr_slitEdit = QLineEdit("", self)
        self.corr_slitEdit.setToolTip(
            "Finite spectrometer bandwidth (slit width) in the transmission spectrum."
        )
        self.corr_slitEdit.setFixedWidth(140)

        ##############################################

        lbl4 = QLabel("STORAGE location (folder/file)", self)
        lbl4.setStyleSheet("color: blue")
        self.filenameEdit = QLineEdit("", self)
        #self.filenameEdit.setFixedWidth(180)

        self.cb_save_figs = QCheckBox('Save figs', self)
        self.cb_save_figs.toggle()

        ##############################################

        self.lcd = QLCDNumber(self)
        self.lcd.setStyleSheet("color: red")
        self.lcd.setFixedHeight(60)
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        self.lcd.setToolTip("Timetrace for saving files")
        self.lcd.setNumDigits(11)

        ##############################################

        self.initUI_()

        ##############################################

        # Add all widgets
        g1_0 = QGridLayout()
        g1_0.addWidget(MyBar, 0, 0)
        g1_1 = QGridLayout()
        g1_1.addWidget(loads_lbl, 0, 0)
        g1_1.addWidget(configFile_lbl, 1, 0)
        g1_1.addWidget(self.config_file_lbl, 1, 1)
        g1_1.addWidget(loadSubOlis_lbl, 2, 0)
        g1_1.addWidget(self.loadSubOlisFile_lbl, 2, 1)
        g1_1.addWidget(self.cb_sub_olis, 2, 2)
        g1_1.addWidget(loadSubFilmOlis_lbl, 3, 0)
        g1_1.addWidget(self.loadSubFilmOlisFile_lbl, 3, 1)
        g1_1.addWidget(self.cb_subfilm_olis, 3, 2)
        g1_1.addWidget(loadSubFTIR_lbl, 4, 0)
        g1_1.addWidget(self.loadSubFTIRFile_lbl, 4, 1)
        g1_1.addWidget(self.cb_sub_ftir, 4, 2)
        g1_1.addWidget(loadSubFilmFTIR_lbl, 5, 0)
        g1_1.addWidget(self.loadSubFilmFTIRFile_lbl, 5, 1)
        g1_1.addWidget(self.cb_subfilm_ftir, 5, 2)
        g1_1.addWidget(plot_X_lbl, 6, 0)
        g1_1.addWidget(self.combo2, 6, 1)

        g1_2 = QGridLayout()
        g1_2.addWidget(lbl1, 0, 0)
        g1_3 = QGridLayout()
        g1_3.addWidget(interpol_lbl, 0, 0)
        g1_3.addWidget(self.combo4, 0, 1)
        g1_3.addWidget(factors_lbl, 1, 0)
        g1_3.addWidget(self.factorsEdit, 1, 1)
        g1_3.addWidget(borders_lbl, 2, 0)
        g1_3.addWidget(self.bordersEdit, 2, 1)

        g1_4 = QGridLayout()
        g1_4.addWidget(lbl2, 0, 0)
        g1_5 = QGridLayout()
        g1_5.addWidget(poly_lbl, 0, 0)
        g1_5.addWidget(self.combo1, 0, 1)
        g1_5.addWidget(polybord_lbl, 1, 0)
        g1_5.addWidget(self.poly_bordersEdit, 1, 1)
        g1_5.addWidget(self.cb_polybord, 1, 2)
        g1_5.addWidget(ignore_data_lbl, 2, 0)
        g1_5.addWidget(self.ignore_data_ptsEdit, 2, 1)
        g1_5.addWidget(corr_slit_lbl, 3, 0)
        g1_5.addWidget(self.corr_slitEdit, 3, 1)

        g4_0 = QGridLayout()
        g4_0.addWidget(lbl4, 0, 0)
        g4_0.addWidget(self.cb_save_figs, 0, 1)
        g4_1 = QGridLayout()
        g4_1.addWidget(self.filenameEdit, 0, 0)

        v1 = QVBoxLayout()
        v1.addLayout(g1_0)
        v1.addLayout(g1_1)
        v1.addLayout(g1_2)
        v1.addLayout(g1_3)
        v1.addLayout(g1_4)
        v1.addLayout(g1_5)
        v1.addLayout(g4_0)
        v1.addLayout(g4_1)

        ###################################################

        g1_6 = QGridLayout()
        g1_6.addWidget(Start_lbl, 0, 0)
        g1_7 = QGridLayout()
        g1_7.addWidget(self.Step0_Button, 0, 0)
        g1_7.addWidget(self.Step1_Button, 1, 0)
        g1_7.addWidget(self.Step2_Button, 2, 0)
        g1_7.addWidget(self.Step3_Button, 3, 0)
        g1_7.addWidget(self.Step4_Button, 4, 0)
        g1_7.addWidget(self.Step5_Button, 5, 0)

        g1_8 = QGridLayout()
        g1_8.addWidget(self.NewFiles, 0, 0)
        g1_8.addWidget(self.lcd, 1, 0)

        v0 = QVBoxLayout()
        v0.addLayout(g1_6)
        v0.addLayout(g1_7)
        v0.addLayout(g1_8)

        # SET ALL VERTICAL COLUMNS TOGETHER
        hbox = QHBoxLayout()
        hbox.addLayout(v1)
        hbox.addLayout(v0)

        ###############################################################################

        # reacts to choises picked in the menu
        self.combo1.activated[str].connect(self.onActivated1)
        self.combo2.activated[str].connect(self.onActivated2)
        self.combo4.activated[str].connect(self.onActivated4)

        # reacts to choises picked in the menu
        self.Step0_Button.clicked.connect(self.set_run)
        self.Step1_Button.clicked.connect(self.set_run)
        self.Step2_Button.clicked.connect(self.set_run)
        self.Step3_Button.clicked.connect(self.set_run)
        self.Step4_Button.clicked.connect(self.set_run)
        self.Step5_Button.clicked.connect(self.set_run)

        # reacts to choises picked in the checkbox
        self.cb_sub_olis.stateChanged.connect(self.sub_olis_check)
        self.cb_subfilm_olis.stateChanged.connect(self.subfilm_olis_check)
        self.cb_sub_ftir.stateChanged.connect(self.sub_ftir_check)
        self.cb_subfilm_ftir.stateChanged.connect(self.subfilm_ftir_check)
        self.cb_save_figs.stateChanged.connect(self.save_figs_check)
        self.cb_polybord.stateChanged.connect(self.polybord_check)

        self.threadpool = QThreadPool()
        print("Multithreading in TEST_gui_v1 with maximum %d threads" %
              self.threadpool.maxThreadCount())
        self.isRunning = False

        self.move(0, 0)
        #self.setGeometry(50, 50, 800, 500)
        hbox.setSizeConstraint(hbox.SetFixedSize)
        self.setWindowTitle("Swanepoel method for thin film analysis")

        w = QWidget()
        w.setLayout(hbox)
        self.setCentralWidget(w)
        self.show()

    def bool_(self, txt):

        if txt == "True":
            return True
        elif txt == "False":
            return False

    def initUI_(self):

        self.config_file_lbl.setText(self.last_used_scan)

        self.loadSubOlisFile_lbl.setText(self.loadSubOlis_str)

        self.loadSubFilmOlisFile_lbl.setText(self.loadSubFilmOlis_str)

        self.loadSubFTIRFile_lbl.setText(self.loadSubFTIR_str)

        self.loadSubFilmFTIRFile_lbl.setText(self.loadSubFilmFTIR_str)

        ##############################################

        self.sub_olis_check(self.loadSubOlis_check)
        self.cb_sub_olis.setChecked(self.loadSubOlis_check)

        self.subfilm_olis_check(self.loadSubFilmOlis_check)
        self.cb_subfilm_olis.setChecked(self.loadSubFilmOlis_check)

        self.sub_ftir_check(self.loadSubFTIR_check)
        self.cb_sub_ftir.setChecked(self.loadSubFTIR_check)

        self.subfilm_ftir_check(self.loadSubFilmFTIR_check)
        self.cb_subfilm_ftir.setChecked(self.loadSubFilmFTIR_check)

        self.save_figs_check(self.save_figs)
        self.cb_save_figs.setChecked(self.save_figs)
        self.filenameEdit.setText(self.filename_str)

        ##############################################

        if len(self.fit_poly_ranges) == 0:
            self.fit_poly_ranges_check = False
            self.polybord_check(self.fit_poly_ranges_check)
            self.cb_polybord.setChecked(self.fit_poly_ranges_check)
        else:
            self.polybord_check(self.fit_poly_ranges_check)
            self.cb_polybord.setChecked(self.fit_poly_ranges_check)

        ##############################################

        self.factorsEdit.setText(self.gaussian_factors)
        self.bordersEdit.setText(self.gaussian_borders)

        ##############################################

        self.combo1.setCurrentIndex(self.mylist1.index(self.fit_poly_order))
        self.combo2.setCurrentIndex(self.mylist2.index(self.plot_X))
        self.combo4.setCurrentIndex(self.mylist4.index(self.fit_linear_spline))

        ##############################################

        self.poly_bordersEdit.setText(self.fit_poly_ranges)
        self.ignore_data_ptsEdit.setText(self.ignore_data_pts)
        self.corr_slitEdit.setText(self.corr_slit)

        ##############################################

        self.NewFiles.setToolTip(''.join([
            "Display newly created and saved files in ", os.sep,
            self.filename_str, os.sep
        ]))
        self.lcd.display(self.timetrace)

    def button_style(self, button, color):

        button.setStyleSheet(''.join([
            'QPushButton {background-color: lightblue; font-size: 18pt; color: ',
            color, '}'
        ]))
        button.setFixedWidth(260)
        button.setFixedHeight(65)

    def loadSubOlisDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "Open files",
            ''.join(['data', os.sep]),
            "All Files (*);;Dat Files (*.dat);;Text Files (*.txt)",
            options=options)
        for afile in files:
            head, tail = os.path.split(str(afile))
            self.loadSubOlis_str = tail
            self.loadSubOlisFile_lbl.setText(tail)
            self.cb_sub_olis.setEnabled(True)

            self.loadSubOlis_check = True
            self.cb_sub_olis(self.loadSubOlis_check)

    def loadSubFilmOlisDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "Open files",
            ''.join(['data', os.sep]),
            "All Files (*);;Dat Files (*.dat);;Text Files (*.txt)",
            options=options)
        for afile in files:
            head, tail = os.path.split(str(afile))
            self.loadSubFilmOlis_str = tail
            self.loadSubFilmOlisFile_lbl.setText(tail)
            self.cb_subfilm_olis.setEnabled(True)

            self.loadSubFilmOlis_check = True
            self.cb_subfilm_olis(self.loadSubFilmOlis_check)

    def loadSubFTIRDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "Open files",
            ''.join(['data', os.sep]),
            "All Files (*);;Dat Files (*.dat);;Text Files (*.txt)",
            options=options)
        for afile in files:
            head, tail = os.path.split(str(afile))
            self.loadSubFTIR_str = tail
            self.loadSubFTIRFile_lbl.setText(tail)
            self.cb_sub_ftir.setEnabled(True)

            self.loadSubFTIR_check = True
            self.cb_sub_ftir(self.loadSubFTIR_check)

    def loadSubFilmFTIRDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "Open files",
            ''.join(['data', os.sep]),
            "All Files (*);;Dat Files (*.dat);;Text Files (*.txt)",
            options=options)
        for afile in files:
            head, tail = os.path.split(str(afile))
            self.loadSubFilmFTIR_str = tail
            self.loadSubFilmFTIRFile_lbl.setText(tail)
            self.cb_subfilm_ftir.setEnabled(True)

            self.loadSubFilmFTIR_check = True
            self.cb_subfilm_ftir.setChecked(self.loadSubFilmFTIR_check)

    def load_config_dialog(self):

        self.Load_config_dialog = Load_config_dialog.Load_config_dialog(
            self, self.config, self.load_, self.initUI_, self.cwd)
        self.Load_config_dialog.exec()

    def email_data_dialog(self):

        self.Send_email_dialog = Send_email_dialog.Send_email_dialog(
            self, self.cwd)
        self.Send_email_dialog.exec()

    def email_set_dialog(self):

        self.Email_dialog = Email_settings_dialog.Email_dialog(
            self, self.lcd, self.cwd)
        self.Email_dialog.exec()

    def helpParamDialog(self):

        helpfile = ''
        with open('config_Swanepoel_forklaringer.py', 'r') as f:
            for line in f:
                helpfile = helpfile + line

        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        msg.setText(
            "Apply the Swanepoel method using the following analysis steps:")
        msg.setInformativeText(helpfile)
        msg.setWindowTitle("Help")
        #msg.setDetailedText(helpfile)
        msg.setStandardButtons(QMessageBox.Ok)
        #msg.setGeometry(1000, 0, 1000+250, 350)

        msg.exec_()

    def contactDialog(self):

        QMessageBox.information(
            self, "Contact information",
            "Suggestions, comments or bugs can be reported to [email protected]"
        )

    def onActivated1(self, text):

        self.fit_poly_order = int(text)

    def onActivated2(self, text):

        self.plot_X = str(text)

    def onActivated4(self, text):

        self.fit_linear_spline = str(text)

    def save_figs_check(self, state):

        if state in [Qt.Checked, True]:
            self.save_figs = True
        else:
            self.save_figs = False

    def sub_olis_check(self, state):

        if state in [Qt.Checked, True]:
            self.loadSubOlis_check = True
            self.loadSubOlisFile_lbl.setStyleSheet("color: magenta")
            self.cb_sub_olis.setText('incl')
        else:
            self.loadSubOlis_check = False
            self.loadSubOlisFile_lbl.setStyleSheet("color: grey")
            self.cb_sub_olis.setText('exc')

    def subfilm_olis_check(self, state):

        if state in [Qt.Checked, True]:
            self.loadSubFilmOlis_check = True
            self.loadSubFilmOlisFile_lbl.setStyleSheet("color: magenta")
            self.cb_subfilm_olis.setText('incl')
        else:
            self.loadSubFilmOlis_check = False
            self.loadSubFilmOlisFile_lbl.setStyleSheet("color: grey")
            self.cb_subfilm_olis.setText('exc')

    def sub_ftir_check(self, state):

        if state in [Qt.Checked, True]:
            self.loadSubFTIR_check = True
            self.loadSubFTIRFile_lbl.setStyleSheet("color: magenta")
            self.cb_sub_ftir.setText('incl')
        else:
            self.loadSubFTIR_check = False
            self.loadSubFTIRFile_lbl.setStyleSheet("color: grey")
            self.cb_sub_ftir.setText('exc')

    def subfilm_ftir_check(self, state):

        if state in [Qt.Checked, True]:
            self.loadSubFilmFTIR_check = True
            self.loadSubFilmFTIRFile_lbl.setStyleSheet("color: magenta")
            self.cb_subfilm_ftir.setText('incl')
        else:
            self.loadSubFilmFTIR_check = False
            self.loadSubFilmFTIRFile_lbl.setStyleSheet("color: grey")
            self.cb_subfilm_ftir.setText('exc')

    def polybord_check(self, state):

        if state in [Qt.Checked, True]:
            self.fit_poly_ranges_check = True
            self.poly_bordersEdit.setEnabled(True)
            self.cb_polybord.setText('incl')
        else:
            self.fit_poly_ranges_check = False
            self.poly_bordersEdit.setEnabled(False)
            self.cb_polybord.setText('exc')

    ############################################################

    # Check input if a number, ie. digits or fractions such as 3.141
    # Source: http://www.pythoncentral.io/how-to-check-if-a-string-is-a-number-in-python-including-unicode/
    def is_int(self, s):
        try:
            int(s)
            return True
        except ValueError:
            return False

    def is_number(self, s):
        try:
            float(s)
            return True
        except ValueError:
            pass

        try:
            import unicodedata
            unicodedata.numeric(s)
            return True
        except (TypeError, ValueError):
            pass

        return False

    def create_file(self, mystr):

        head, ext = os.path.splitext(mystr)

        totalpath = ''.join([self.cwd, os.sep, head, '_', self.timetrace])

        my_dir = os.path.dirname(totalpath)
        if not os.path.isdir(my_dir):
            QMessageBox.warning(
                self, "Message",
                "".join(["Folder(s) named ", my_dir, " will be created!"]))

        try:
            os.makedirs(my_dir, exist_ok=True)
        except Exception as e:
            QMessageBox.critical(
                self, "Message",
                "".join(["Folder named ", head, " not valid!\n\n",
                         str(e)]))
            return ""

        return totalpath

    def set_run(self):

        # Save all the currently changed varaibles
        self.save_()
        # Register the sender of the command (a button or similar)
        sender = self.sender()

        ## gaussian_borders and gaussian_factors warnings and errors
        gaus_bord = str(self.bordersEdit.text()).split(',')
        for tal in gaus_bord:
            if not self.is_number(tal):
                QMessageBox.critical(self, 'Message',
                                     "Gaussian borders must be real numbers!")
                return
            elif float(tal) < 0.0:
                QMessageBox.critical(
                    self, 'Message',
                    "Gaussian borders must be positive or zero!")
                return

        if len(gaus_bord) < 2:
            QMessageBox.critical(
                self, 'Message', "You must enter at least 2 gaussian borders!")
            return

        if not numpy.array_equal([numpy.float(i) for i in gaus_bord],
                                 numpy.sort(
                                     [numpy.float(i) for i in gaus_bord])):
            QMessageBox.critical(
                self, 'Message',
                "The gaussian borders must be entered in the ascending order!")
            return

        gaus_fact = str(self.factorsEdit.text()).split(',')
        for tal in gaus_fact:
            if not self.is_number(tal):
                QMessageBox.critical(self, 'Message',
                                     "Gaussian factors must be real numbers!")
                return
            elif float(tal) < 0.0:
                QMessageBox.critical(
                    self, 'Message',
                    "Gaussian factors must be positive or zero!")
                return

        if len(gaus_fact) < 1:
            QMessageBox.critical(self, 'Message',
                                 "You must enter at least 1 gaussian factor!")
            return

        if len(gaus_bord) != len(gaus_fact) + 1:
            QMessageBox.critical(
                self, 'Message',
                "The number of gaussian factors is exactly one less than the number of gaussian borders!"
            )
            return

        ## ignored data points warnings and errors
        ign_pts = str(self.ignore_data_ptsEdit.text())
        if not self.is_int(ign_pts):
            QMessageBox.critical(
                self, 'Message', "The number of ignored points is an integer!")
            return
        elif int(ign_pts) < 0:
            QMessageBox.critical(
                self, 'Message',
                "The number of ignored points is a positive integer!")
            return

        ## correction slit width warnings and errors
        corr_pts = str(self.corr_slitEdit.text())
        if not self.is_number(corr_pts):
            QMessageBox.critical(
                self, 'Message', "The correction slit width is a real number!")
            return
        elif float(corr_pts) < 0:
            QMessageBox.critical(
                self, 'Message',
                "The correction slit width is a positive number!")
            return

        ## fit_poly_ranges warnings and errors
        if self.fit_poly_ranges_check == True:
            polyfit_bord = str(self.poly_bordersEdit.text()).split(',')
            for tal in polyfit_bord:
                if not self.is_number(tal):
                    QMessageBox.critical(
                        self, 'Message',
                        "The polyfit range enteries must be real numbers!")
                    return
                elif float(tal) < 0.0:
                    QMessageBox.critical(
                        self, 'Message',
                        "The polyfit range enteries must be positive or zero!")
                    return

            if len(polyfit_bord) < 2 or len(polyfit_bord) % 2 != 0:
                QMessageBox.critical(
                    self, 'Message',
                    "The polyfit range list accepts minimum 2 or even number of enteries!"
                )
                return

            if not numpy.array_equal(
                [numpy.float(i) for i in polyfit_bord],
                    numpy.sort([numpy.float(i) for i in polyfit_bord])):
                QMessageBox.critical(
                    self, 'Message',
                    "The polyfit range list must be entered in ascending order!"
                )
                return

        # When all user defined enteries are approved save the data
        self.create_file(str(self.filenameEdit.text()))

        if sender.text() != 'Raw data':

            ## raw data files warnings and errors
            if not self.loadSubOlis_check and not self.loadSubFilmOlis_check:
                pass
            elif self.loadSubOlis_check and self.loadSubFilmOlis_check:
                pass
            else:
                QMessageBox.critical(
                    self, 'Message',
                    "Select both OLIS data files subfilmRAW and subRAW!")
                return

            if not self.loadSubFTIR_check and not self.loadSubFilmFTIR_check:
                pass
            elif self.loadSubFTIR_check and self.loadSubFilmFTIR_check:
                pass
            else:
                QMessageBox.critical(
                    self, 'Message',
                    "Select both FTIR data files subfilmRAW and subRAW!")
                return

            if not self.loadSubOlis_check and not self.loadSubFilmOlis_check and not self.loadSubFTIR_check and not self.loadSubFilmFTIR_check:
                QMessageBox.critical(self, 'Message',
                                     "No data files selected!")
                return

        if sender.text() == 'Raw data':

            if not self.loadSubOlis_check and not self.loadSubFilmOlis_check and not self.loadSubFTIR_check and not self.loadSubFilmFTIR_check:
                QMessageBox.critical(self, 'Message',
                                     "No raw data files selected!")
                return

            self.button_style(self.Step0_Button, 'red')
            self.button_style(self.Step1_Button, 'grey')
            self.button_style(self.Step2_Button, 'grey')
            self.button_style(self.Step3_Button, 'grey')
            self.button_style(self.Step4_Button, 'grey')
            self.button_style(self.Step5_Button, 'grey')

        elif sender.text() == 'Tmin and Tmax':

            self.button_style(self.Step1_Button, 'red')
            self.button_style(self.Step0_Button, 'grey')
            self.button_style(self.Step2_Button, 'grey')
            self.button_style(self.Step3_Button, 'grey')
            self.button_style(self.Step4_Button, 'grey')
            self.button_style(self.Step5_Button, 'grey')

        elif sender.text() == 'Std.Dev. in d':

            self.button_style(self.Step2_Button, 'red')
            self.button_style(self.Step0_Button, 'grey')
            self.button_style(self.Step1_Button, 'grey')
            self.button_style(self.Step3_Button, 'grey')
            self.button_style(self.Step4_Button, 'grey')
            self.button_style(self.Step5_Button, 'grey')

        elif sender.text() == 'Index n':

            self.button_style(self.Step3_Button, 'red')
            self.button_style(self.Step0_Button, 'grey')
            self.button_style(self.Step1_Button, 'grey')
            self.button_style(self.Step2_Button, 'grey')
            self.button_style(self.Step4_Button, 'grey')
            self.button_style(self.Step5_Button, 'grey')

        elif sender.text() == 'Absorption alpha':

            self.button_style(self.Step4_Button, 'red')
            self.button_style(self.Step0_Button, 'grey')
            self.button_style(self.Step1_Button, 'grey')
            self.button_style(self.Step2_Button, 'grey')
            self.button_style(self.Step3_Button, 'grey')
            self.button_style(self.Step5_Button, 'grey')

        elif sender.text() == 'Wavenumber k':

            self.button_style(self.Step5_Button, 'red')
            self.button_style(self.Step0_Button, 'grey')
            self.button_style(self.Step1_Button, 'grey')
            self.button_style(self.Step2_Button, 'grey')
            self.button_style(self.Step3_Button, 'grey')
            self.button_style(self.Step4_Button, 'grey')

        else:
            return

        worker = Worker(sender.text(), self.cwd)

        worker.signals.pass_plots.connect(self.pass_plots)
        worker.signals.critical.connect(self.critical)
        worker.signals.finished.connect(self.finished)

        # Execute
        self.threadpool.start(worker)
        self.isRunning = True

    def pass_plots(self, obj):

        self.my_plots, sender = obj

        my_str = 'Data files:\n'
        try:
            self.datafiles = self.my_plots.make_plots()
            for i, ii in zip(self.datafiles, range(len(self.datafiles))):
                head, tail = os.path.split(i)
                my_str += ''.join([str(ii + 1), ': ', tail, '\n'])

            self.NewFiles.setText(my_str)
            self.my_plots.show_plots()

        except Exception as inst:
            QMessageBox.critical(self, 'Message', str(inst))

    def load_(self):

        # Initial read of the config file
        self.config = configparser.ConfigParser()

        try:
            self.config.read(''.join([self.cwd, os.sep, "config.ini"]))
            self.last_used_scan = self.config.get('LastScan', 'last_used_scan')

            self.loadSubOlis_str = self.config.get(
                self.last_used_scan, "loadsubolis").strip().split(':')[0]
            self.loadSubOlis_check = self.bool_(
                self.config.get(self.last_used_scan,
                                'loadsubolis').strip().split(':')[1])
            self.loadSubFilmOlis_str = self.config.get(
                self.last_used_scan, 'loadsubfilmolis').strip().split(':')[0]
            self.loadSubFilmOlis_check = self.bool_(
                self.config.get(self.last_used_scan,
                                'loadsubfilmolis').strip().split(':')[1])
            self.loadSubFTIR_str = self.config.get(
                self.last_used_scan, 'loadsubftir').strip().split(':')[0]
            self.loadSubFTIR_check = self.bool_(
                self.config.get(self.last_used_scan,
                                'loadsubftir').strip().split(':')[1])
            self.loadSubFilmFTIR_str = self.config.get(
                self.last_used_scan, 'loadsubfilmftir').strip().split(':')[0]
            self.loadSubFilmFTIR_check = self.bool_(
                self.config.get(self.last_used_scan,
                                'loadsubfilmftir').strip().split(':')[1])
            self.fit_linear_spline = self.config.get(self.last_used_scan,
                                                     'fit_linear_spline')
            self.gaussian_factors = self.config.get(self.last_used_scan,
                                                    'gaussian_factors')
            self.gaussian_borders = self.config.get(self.last_used_scan,
                                                    'gaussian_borders')
            self.ignore_data_pts = self.config.get(self.last_used_scan,
                                                   'ignore_data_pts')
            self.corr_slit = self.config.get(self.last_used_scan, 'corr_slit')
            self.fit_poly_order = self.config.get(self.last_used_scan,
                                                  'fit_poly_order')
            self.fit_poly_ranges = self.config.get(
                self.last_used_scan, 'fit_poly_ranges').strip().split(':')[0]
            self.fit_poly_ranges_check = self.bool_(
                self.config.get(self.last_used_scan,
                                'fit_poly_ranges').strip().split(':')[1])
            self.filename_str = self.config.get(self.last_used_scan,
                                                'filename')
            self.timetrace = self.config.get(self.last_used_scan, 'timetrace')
            self.save_figs = self.bool_(
                self.config.get(self.last_used_scan, 'save_figs'))
            self.plot_X = self.config.get(self.last_used_scan, 'plot_x')
            self.emailset_str = self.config.get(self.last_used_scan,
                                                'emailset').strip().split(',')
            self.emailrec_str = self.config.get(self.last_used_scan,
                                                'emailrec').strip().split(',')

        except configparser.NoOptionError as nov:
            QMessageBox.critical(
                self, 'Message', ''.join([
                    "Main FAULT while reading the config.ini file\n",
                    str(nov)
                ]))
            raise

    def save_(self):

        self.timetrace = time.strftime("%y%m%d-%H%M")
        self.lcd.display(self.timetrace)

        self.config.read(''.join([self.cwd, os.sep, "config.ini"]))
        self.config.set('LastScan', "last_used_scan", self.last_used_scan)
        self.config.set(
            self.last_used_scan, "loadSubOlis",
            ':'.join([self.loadSubOlis_str,
                      str(self.loadSubOlis_check)]))
        self.config.set(
            self.last_used_scan, "loadSubFilmOlis", ':'.join(
                [self.loadSubFilmOlis_str,
                 str(self.loadSubFilmOlis_check)]))
        self.config.set(
            self.last_used_scan, "loadSubFTIR",
            ':'.join([self.loadSubFTIR_str,
                      str(self.loadSubFTIR_check)]))
        self.config.set(
            self.last_used_scan, "loadSubFilmFTIR", ':'.join(
                [self.loadSubFilmFTIR_str,
                 str(self.loadSubFilmFTIR_check)]))
        self.config.set(self.last_used_scan, "fit_linear_spline",
                        self.fit_linear_spline)
        self.config.set(self.last_used_scan, "gaussian_factors",
                        str(self.factorsEdit.text()))
        self.config.set(self.last_used_scan, "gaussian_borders",
                        str(self.bordersEdit.text()))
        self.config.set(self.last_used_scan, "ignore_data_pts",
                        str(self.ignore_data_ptsEdit.text()))
        self.config.set(self.last_used_scan, "corr_slit",
                        str(self.corr_slitEdit.text()))
        self.config.set(self.last_used_scan, "fit_poly_order",
                        str(self.fit_poly_order))
        self.config.set(
            self.last_used_scan, "fit_poly_ranges", ':'.join([
                str(self.poly_bordersEdit.text()),
                str(self.fit_poly_ranges_check)
            ]))
        self.config.set(self.last_used_scan, "filename",
                        str(self.filenameEdit.text()))
        self.config.set(self.last_used_scan, "timetrace", self.timetrace)
        self.config.set(self.last_used_scan, "save_figs", str(self.save_figs))
        self.config.set(self.last_used_scan, "plot_x", self.plot_X)

        with open(''.join([self.cwd, os.sep, "config.ini"]),
                  "w") as configfile:
            self.config.write(configfile)

    def finished(self):

        self.my_plots.close_plots()

        self.load_()

        if self.emailset_str[1] == "yes":
            self.send_notif()
        if self.emailset_str[2] == "yes":
            self.send_data()

        self.button_style(self.Step0_Button, 'black')
        self.button_style(self.Step1_Button, 'black')
        self.button_style(self.Step2_Button, 'black')
        self.button_style(self.Step3_Button, 'black')
        self.button_style(self.Step4_Button, 'black')
        self.button_style(self.Step5_Button, 'black')

        self.isRunning = False

    def allButtons_torf(self, trueorfalse, *argv):

        if argv[0] == 'allfalse':
            self.cb_sub_olis.setEnabled(False)
            self.cb_subfilm_olis.setEnabled(False)
            self.cb_sub_ftir.setEnabled(False)
            self.cb_subfilm_ftir.setEnabled(False)

            self.poly_bordersEdit.setEnabled(False)

        self.fileSave.setEnabled(trueorfalse)
        self.loadMenu.setEnabled(trueorfalse)
        self.emailMenu.setEnabled(trueorfalse)

        self.cb_save_figs.setEnabled(trueorfalse)
        self.cb_polybord.setEnabled(trueorfalse)

        self.Step0_Button.setEnabled(trueorfalse)
        self.Step1_Button.setEnabled(trueorfalse)
        self.Step2_Button.setEnabled(trueorfalse)
        self.Step3_Button.setEnabled(trueorfalse)
        self.Step4_Button.setEnabled(trueorfalse)
        self.Step5_Button.setEnabled(trueorfalse)

        self.combo1.setEnabled(trueorfalse)
        self.combo2.setEnabled(trueorfalse)
        self.combo4.setEnabled(trueorfalse)

        self.factorsEdit.setEnabled(trueorfalse)
        self.bordersEdit.setEnabled(trueorfalse)
        self.ignore_data_ptsEdit.setEnabled(trueorfalse)
        self.corr_slitEdit.setEnabled(trueorfalse)

        self.filenameEdit.setEnabled(trueorfalse)

    def warning(self, mystr):

        QMessageBox.warning(self, "Message", mystr)

    def send_notif(self):

        contents = [
            "The scan is done. Please visit the experiment site and make sure that all light sources are switched off."
        ]
        subject = "The scan is done"

        obj = type(
            "obj", (object, ), {
                "subject": subject,
                "contents": contents,
                "settings": self.emailset_str,
                "receivers": self.emailrec_str
            })

        worker = Send_Email_Worker(obj)
        worker.signals.critical.connect(self.critical)
        worker.signals.warning.connect(self.warning)
        worker.signals.finished.connect(self.finished1)

        # Execute
        self.md = Indicator_dialog.Indicator_dialog(
            self, "...sending notification...",
            "indicators/ajax-loader-ball.gif")
        self.threadpool.start(worker)
        self.isRunning = True

    def send_data(self):

        contents = [
            "The scan is  done and the logged data is attached to this email. Please visit the experiment site and make sure that all light sources are switched off."
        ]
        contents.extend(self.datafiles)
        subject = "The scan data from the latest scan!"

        obj = type(
            "obj", (object, ), {
                "subject": subject,
                "contents": contents,
                "settings": self.emailset_str,
                "receivers": self.emailrec_str
            })

        worker = Send_Email_Worker(obj)
        worker.signals.critical.connect(self.critical)
        worker.signals.warning.connect(self.warning)
        worker.signals.finished.connect(self.finished1)

        # Execute
        self.md = Indicator_dialog.Indicator_dialog(
            self, "...sending files...", "indicators/ajax-loader-ball.gif")
        self.threadpool.start(worker)
        self.isRunning = True

    def finished1(self):

        self.isRunning = False
        self.md.close_()

    def critical(self, mystr):

        QMessageBox.critical(self, 'Message', mystr)

    def closeEvent(self, event):

        reply = QMessageBox.question(self, 'Message', "Quit now?",
                                     QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            if self.isRunning:
                QMessageBox.warning(
                    self, 'Message',
                    "Analysis in progress. Wait the analysis to finish and then quit!"
                )
                event.ignore()
            else:
                event.accept()
        elif reply == QMessageBox.No:
            event.ignore()
Ejemplo n.º 8
0
class TabMatch(QWidget):
    def __init__(self):
        super(TabMatch, self).__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.LCD = QLCDNumber()
        self.LCD.setNumDigits(4)
        self.LCD.display("0:00")

        layout.addWidget(self.LCD)

        #sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        #sizePolicy.setHorizontalStretch(0)
        #sizePolicy.setVerticalStretch(0)
        #self.LCD.setSizePolicy(sizePolicy)

        hbox = QHBoxLayout()
        self.cmbTeam1 = QComboBox()
        self.empty = QLabel()
        self.versus = QLabel()
        self.cmbTeam2 = QComboBox()

        img = QPixmap('./gui/res/vs.png')
        self.versus.setPixmap(img)

        img = QPixmap('./gui/res/null.png')
        self.empty.setPixmap(img)

        #hbox.addWidget(self.cmbTeam1)
        #hbox.addWidget(self.versus)
        #hbox.addWidget(self.cmbTeam2)

        #layout.addLayout(hbox)

        aux = QHBoxLayout()
        aux.addStretch(0)
        aux.addWidget(self.versus)
        aux.addStretch(0)

        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        self.versus.setSizePolicy(sizePolicy)

        layout.addWidget(self.cmbTeam1)
        layout.addLayout(aux)
        layout.addWidget(self.cmbTeam2)

        hbox = QHBoxLayout()

        self.btnPlay = QPushButton()
        icon = QIcon('./gui/res/play_icon.png')
        self.btnPlay.setIcon(icon)

        self.btnStop = QPushButton()
        icon = QIcon('./gui/res/stop_icon.png')
        self.btnStop.setIcon(icon)

        hbox.addWidget(self.btnPlay)
        hbox.addWidget(self.btnStop)

        layout.addLayout(hbox)
        self.show()
Ejemplo n.º 9
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.backlogMgr = BacklogMgr()

        self.initUI()

    def initUI(self):

        self.setWindowTitle("TurboClock")

        self.resize(400, 300)
        self.setWindowIcon(QIcon('Images//clock.png'))

        self.icon = QSystemTrayIcon(self)
        self.icon.setIcon(QIcon('Images//clock.png'))
        self.icon.setVisible(True)

        self.lcdNumber = QLCDNumber()
        self.lcdNumber.setNumDigits(8)

        self.btnStartPause = QPushButton('', self)
        self.btnStartPause.setIcon(QIcon('Images//play_icon.png'))
        self.btnStartPause.clicked.connect(self.manageStartPauseClickedEvent)

        self.btnDutyDetails = QPushButton('Duty details...')
        self.btnDutyDetails.clicked.connect(self.manageDutyDetailsClickedEvent)

        self.btnAddTfsTask = QPushButton('', self)
        self.btnAddTfsTask.setIcon(QIcon('Images//plus_icon.png'))
        self.btnAddTfsTask.clicked.connect(self.manageEditTasksOptions)

        self.progressBar = QProgressBar()
        self.progressBar.setValue(0)

        self.dutyTimeCompLbl = QLabel()

        self.currTaskItemRow = 0
        self.taskTFSCb = QComboBox(self)
        self.initTFSTaskCombobox()

        mainLayout = QVBoxLayout(self)

        layoutTimer = QVBoxLayout()
        layoutTimer.addWidget(self.lcdNumber)

        fieldsInputLayout = QHBoxLayout()

        layoutInputCodes = QVBoxLayout()
        layoutInputCodes.addWidget(self.taskTFSCb)

        layoutAddBtn = QVBoxLayout()
        layoutAddBtn.addWidget(self.btnAddTfsTask)

        fieldsInputLayout.addLayout(layoutInputCodes)
        fieldsInputLayout.addLayout(layoutAddBtn)

        layoutDutyStat = QHBoxLayout()
        layoutDutyStat.addWidget(self.dutyTimeCompLbl)

        layoutProgressBar = QHBoxLayout()
        layoutProgressBar.addWidget(self.progressBar)

        mainLayout.addLayout(layoutTimer)
        mainLayout.addLayout(fieldsInputLayout)
        mainLayout.addWidget(self.btnStartPause)
        mainLayout.addWidget(self.btnDutyDetails)
        mainLayout.addWidget(self.progressBar)
        mainLayout.addLayout(layoutDutyStat)

        self.timer = QTimer(self)
        self.deltaTimer = 0
        self.currTimeLCD = QTime(0, 0, 0)
        self.currTimeDuty = QTime(0, 0, 0)

        self.timer.timeout.connect(self.incrementTimer)

        self.updateTimeLCD()
        self.updateDutyTimeDisp()
        self.updateProgressBarDisplay()

        self.startTime = 0
        self.stopTime = 0

        self.editTasksGUI = EditTasksOptionsGUI(self, self.backlogMgr)

    def initTFSTaskCombobox(self):

        self.updateTaskCombobox()

        self.taskTFSCb.currentIndexChanged.connect(self.manageCbTFSIndexChange)

    def updateProgressBarDisplay(self):

        estimatedTime = self.backlogMgr.backlogData.currTask.estimatedTime

        if estimatedTime == 0:
            return

        ratioFromTimer = (self.deltaTimer / estimatedTime) * 100

        totalCompletionRatio = self.backlogMgr.getCompletionRatio(
            self.backlogMgr.backlogData.currTaskIndex) + ratioFromTimer

        if totalCompletionRatio <= 100:
            self.progressBar.setValue(totalCompletionRatio)
        else:
            self.progressBar.setValue(100)

    def updateTaskCombobox(self):

        currTaskIndex = self.currTaskItemRow

        self.taskTFSCb.clear()

        taskList = self.backlogMgr.getTasksFromGUI()

        for currTask in taskList:

            taskDesc = currTask.title + ' (' + currTask.prjCode + ')'

            self.taskTFSCb.addItem(taskDesc)

        self.taskTFSCb.setCurrentIndex(currTaskIndex)

        self.backlogMgr.setCurrentTaskFromGUI(currTaskIndex)

    def manageCbTFSIndexChange(self):

        self.currTaskItemRow = self.taskTFSCb.currentIndex()

        if self.currTaskItemRow >= 0:
            self.backlogMgr.manageTaskChangeFromGUI(self.currTaskItemRow)

        self.updateTimeLCD()

        self.deltaTimer = 0
        self.updateProgressBarDisplay()

    def updateTimeLCD(self):

        currTaskTime_split = self.backlogMgr.getCompletedTimeCurrTaskFromGUI(
        ).split(':')

        h = int(currTaskTime_split[0])
        m = int(currTaskTime_split[1])
        s = int(currTaskTime_split[2])

        self.currTimeLCD = QTime(h, m, s)
        self.lcdNumber.display(self.currTimeLCD.toString('hh:mm:ss'))

    def updateDutyTimeDisp(self):

        currTaskTime_split = self.backlogMgr.getCurrDutyTimeCompletedFromGUI(
        ).split(':')

        h = int(currTaskTime_split[0])
        m = int(currTaskTime_split[1])
        s = int(currTaskTime_split[2])

        self.currTimeDuty = QTime(h, m, s)
        self.dutyTimeCompLbl.setText('Daily time completed: ' +
                                     self.currTimeDuty.toString('hh:mm:ss'))

    def incrementTimer(self):

        self.currTimeLCD = self.currTimeLCD.addSecs(1)
        self.lcdNumber.display(self.currTimeLCD.toString('hh:mm:ss'))

        self.currTimeDuty = self.currTimeDuty.addSecs(1)
        self.dutyTimeCompLbl.setText('Daily time completed: ' +
                                     self.currTimeDuty.toString('hh:mm:ss'))

        self.deltaTimer += 1

        self.updateProgressBarDisplay()

    def manageStartPauseClickedEvent(self):

        self.backlogMgr.manageClickButtonFromGUI()
        self.deltaTimer = 0

        if self.timer.isActive():
            self.timer.stop()
            self.btnStartPause.setIcon(QIcon('Images//play_icon.png'))
        else:
            self.timer.start(1000)
            self.btnStartPause.setIcon(QIcon('Images//pause_icon.png'))

    def manageDutyDetailsClickedEvent(self):

        ex = DutyDetailsWindow(self, self.backlogMgr.backlogData)
        ex.show()

    def manageEditTasksOptions(self):

        self.editTasksGUI.exec_()

        self.updateTaskCombobox()

    def closeEvent(self, event):

        event.accept()
Ejemplo n.º 10
0
class MainWindow(QMainWindow):
    """
    Mainwindow class operates the pyqt5 window and all of its widgets.
    It also hosts most of the basic methods connected to the widgets.
    There are start and stop methods, and a waiter thread that keeps an
    eye on the finite measurement. Settings typed by the user get stored
    in a dictionary class and get updated before each measurement call.
    Mainwindow launches all of the subprocesses connecting to the daqmx cards.
    Communication between threads and mainwindow is established via
    pyqtSignals, between mainwindow and subprocesses via multiprocessing queue.
    The main control variable for measurements is a multiprocessing event variable.
    """
    def __init__(self):
        super(MainWindow, self).__init__()
        """
        Init hosts all the variables and UI related functionality. The following classes
        can not be initializes in here, because they inherit from multiprocessing.Process:
        libs.Counter, libs.Laser and libs.dataProcesser. Arguments have to be passed by
        inheritance, later there's no possibility, due to their separation from the main
        loop. libs.Animation also gets instanciated later, due to the window launching
        functionality in its init method.
        """
        self._dict = libs.UIsettings.UIsettings()
        self._files = libs.SaveFiles.SaveFiles()
        self._changeRA = libs.ChangeReadArray.ChangeReadArray()
        self._timetrace = libs.Timetraces.Timetrace()
        self._r = libs.Refresh.Refresh()
        self._readArraySize = int(1e3)

        # Queues, Semaphores and Events all derived from the multiprocessing library
        self._dataQ1 = mpQueue()
        self._dataQ2 = mpQueue()
        self._animDataQ1 = mpQueue()
        self._animDataQ2 = mpQueue()
        self._running = mpEvent()
        self._semaphore = Semaphore(3)

        # pyqtSignals
        self.signal = Communicate()
        self.signal.stopMeasurement.connect(self.stopBtn)
        self.signal.measurementProgress.connect(lambda x: self.setProgressBar(x))
        self.signal.warning.connect(self.warnPopUp)
        self.signal.displayRates.connect(lambda x: self.displayRatesOnLCD(x))
        self.signal.convertDone.connect(lambda: self.statusBar.showMessage('Conversion done!'))
        self.signal.alreadyConverted.connect(lambda: self.statusBar.showMessage('Already converted!'))
        self.signal.noData.connect(lambda: self.statusBar.showMessage('No data files in this directory!'))

        # ################## #
        # Window and widgets #
        # ################## #

        self.setGeometry(500, 300, 500, 200)    # x, y, width, height
        self.setWindowTitle('ALEX')

        # ## Statusbar
        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)
        self.statusBar.showMessage("idle")

        # ## file menue
        # load app, loads laser settings from file
        self.loadApp = QAction('Load settings', self)
        self.loadApp.setShortcut('Ctrl+l')
        self.loadApp.triggered.connect(self.loadDict)

        # save app, saves measurement settings to file
        self.saveApp = QAction('Save settings', self)
        self.saveApp.setShortcut('Ctrl+s')
        self.saveApp.triggered.connect(lambda: self._files.saveSetsDict(self._dict._a, self.getDirectory(),
                                                                        'Measurement_settings'))

        # convert data to photon-hdf5
        self.convertData = QAction('Convert raw data to photon-hdf5', self)
        self.convertData.setShortcut('Ctrl+c')
        self.convertData.triggered.connect(lambda: self._files.convertToPhotonHDF5(self.getDirectory(), self.signal))

        # change ReadArray size
        self.setArraySize = QAction('Read arrays size', self)
        self.setArraySize.setShortcut('Ctrl+a')
        self.setArraySize.triggered.connect(self.changeArraySize)

        # close the app
        self.closeApp = QAction('Close', self)
        self.closeApp.setShortcut('Ctrl+q')
        self.closeApp.triggered.connect(self.closeApplication)

        self.menueLayout()

        # ## GroupBox Directory:
        # Group contains:
        # - Location display QLineEdit
        # - Browse directories QPushButton

        filesGroup = QGroupBox('Directory')
        hbox12 = QHBoxLayout()
        filesGroup.setLayout(hbox12)

        self._location = QLineEdit()
        self._location.setToolTip("Please select a directory. If you do not, the data will not be saved!")
        self._location.setMaxLength(100)
        self._location.setReadOnly(True)
        hbox12.addWidget(self._location)
        hbox12.setSpacing(10)

        self._browseButton = QPushButton('Browse', self)
        self._browseButton.clicked.connect(self.getFileLocation)
        hbox12.addWidget(self._browseButton)

        # ## label for different widgets
        self.label1 = QLabel("Laserpower green")
        self.label2 = QLabel("Laserpower red")
        self.label3 = QLabel("Ratio of illumination\ngreen/red")
        self.label4 = QLabel("ALEX\nfrequency [Hz]")
        self.label5 = QLabel("Measurement\nduration [s]")
        self.label6 = QLabel("Measurement mode")
        self.label7 = QLabel("Counts in green channel")
        self.label8 = QLabel("Counts in red channel")
        self.label9 = QLabel("% Green")
        self.label10 = QLabel("% Red")

        # ## GroupBox Laser:
        # Group contains:
        # - Laser power red slider
        # - Laser power red spinbox
        # - Laser power green slider
        # - Laser power green spinbox
        # - Laser period percentage slider
        # - Laser period percentage red spinbox
        # - Laser period percentage green spinbox

        laserGroup = QGroupBox("Laser settings")
        hbox1 = QHBoxLayout()
        hbox1.setSpacing(30)
        hbox2 = QHBoxLayout()
        hbox2.setSpacing(30)
        hbox9 = QHBoxLayout()
        hbox11 = QHBoxLayout()
        hbox11.setSpacing(30)
        hbox10 = QHBoxLayout()
        hbox10.setSpacing(30)
        vbox1 = QVBoxLayout()
        vbox1.addWidget(self.label2)
        vbox1.addLayout(hbox1)
        vbox1.addStretch(1)
        vbox1.addWidget(self.label1)
        vbox1.addLayout(hbox2)
        vbox1.addStretch(1)
        vbox1.addWidget(self.label3)
        vbox1.addLayout(hbox9)
        vbox1.addStretch(1)
        vbox1.addLayout(hbox11)
        vbox1.addStretch(1)
        vbox1.addLayout(hbox10)
        vbox1.addStretch(1)
        laserGroup.setLayout(vbox1)

        hbox11.addWidget(self.label9)
        hbox11.addWidget(self.label10)

        # Laserpower slider red
        self.sld_red = QSlider(Qt.Horizontal, self)
        self.sld_red.setFocusPolicy(Qt.NoFocus)
        self.sld_red.setGeometry(80, 20, 50, 10)
        self.sld_red.setMinimum(0)
        self.sld_red.setMaximum(100)
        self.sld_red.setValue(50)
        self.sld_red.setTickPosition(QSlider.TicksBelow)
        self.sld_red.setTickInterval(20)
        self.sld_red.valueChanged.connect(lambda: self.refreshUI(0, 'sld_red', self.sld_red.value()))
        hbox1.addWidget(self.sld_red)

        # Laserpower QSpinBox red
        self.sb_red = QSpinBox(self)
        self.sb_red.setMinimum(0)
        self.sb_red.setMaximum(100)
        self.sb_red.setValue(50)
        self.sb_red.valueChanged.connect(lambda: self.refreshUI(1, 'sb_red', self.sb_red.value()))
        hbox1.addWidget(self.sb_red)

        # Laserpower slider green
        self.sld_green = QSlider(Qt.Horizontal, self)
        self.sld_green.setFocusPolicy(Qt.NoFocus)
        self.sld_green.setGeometry(160, 40, 100, 30)
        self.sld_green.setMinimum(0)
        self.sld_green.setMaximum(100)
        self.sld_green.setValue(50)
        self.sld_green.setTickPosition(QSlider.TicksBelow)
        self.sld_green.setTickInterval(20)
        self.sld_green.valueChanged.connect(lambda: self.refreshUI(0, 'sld_green', self.sld_green.value()))
        hbox2.addWidget(self.sld_green)

        # Laserpower QSpinBox green
        self.sb_green = QSpinBox(self)
        self.sb_green.setMinimum(0)
        self.sb_green.setMaximum(100)
        self.sb_green.setValue(50)
        self.sb_green.valueChanged.connect(lambda: self.refreshUI(1, 'sb_green', self.sb_green.value()))
        hbox2.addWidget(self.sb_green)

        # Illumination percentage slider
        self.sld_percentage = QSlider(Qt.Horizontal, self)
        self.sld_percentage.setFocusPolicy(Qt.NoFocus)
        self.sld_percentage.setGeometry(160, 40, 100, 30)
        self.sld_percentage.setMinimum(0)
        self.sld_percentage.setMaximum(100)
        self.sld_percentage.setTickPosition(QSlider.TicksBelow)
        self.sld_percentage.setTickInterval(10)
        self.sld_percentage.setValue(50)
        self.sld_percentage.valueChanged.connect(lambda: self.refreshUI(0, 'sld_percentage', self.sld_percentage.value()))
        hbox9.addWidget(self.sld_percentage)

        # Illumination percentage QSpinBox green
        self.sb_percentG = QSpinBox(self)
        self.sb_percentG.setMinimum(0)
        self.sb_percentG.setMaximum(100)
        self.sb_percentG.setValue(50)
        self.sb_percentG.valueChanged.connect(lambda: self.refreshUI(1, 'sb_percentG', self.sb_percentG.value()))
        hbox10.addWidget(self.sb_percentG)

        # Illumination QSpinBox red
        self.sb_percentR = QSpinBox(self)
        self.sb_percentR.setMinimum(0)
        self.sb_percentR.setMaximum(100)
        self.sb_percentR.setValue(50)
        self.sb_percentR.valueChanged.connect(lambda: self.refreshUI(1, 'sb_percentR', self.sb_percentR.value()))
        hbox10.addWidget(self.sb_percentR)

        # ## APD GroupBox
        # Group contains:
        # - Laser alternation frequency spinbox
        # - Measurement mode continuous radiobutton
        # - Measurement mode finite radiobutton
        # - Measurement duration spinbox

        apdGroup = QGroupBox("Measurement")
        hbox3 = QHBoxLayout()
        hbox3.setSpacing(30)
        hbox4 = QHBoxLayout()
        hbox4.setSpacing(30)
        hbox5 = QHBoxLayout()
        hbox5.setSpacing(30)
        vbox2 = QVBoxLayout()
        vbox2.addLayout(hbox3)
        vbox2.addStretch(1)
        vbox2.addLayout(hbox4)
        vbox2.addStretch(1)
        vbox2.addWidget(self.label6)
        vbox2.addLayout(hbox5)
        apdGroup.setLayout(vbox2)

        hbox3.addWidget(self.label4)
        hbox3.addWidget(self.label5)

        # Sample frequence QSpinBox
        self.sb_sampFreq = QSpinBox(self)
        self.sb_sampFreq.setMinimum(100)
        self.sb_sampFreq.setMaximum(100000)
        self.sb_sampFreq.setValue(10000)
        self.sb_sampFreq.valueChanged.connect(lambda: self.refreshUI(1, 'sb_sampFreq', self.sb_sampFreq.value()))
        hbox4.addWidget(self.sb_sampFreq)

        # Radiobutton Continuous Measurement
        self.rb_cont = QRadioButton("Continuous")
        self.rb_cont.setChecked(True)
        self.rb_cont.toggled.connect(lambda: self.refreshUI(2, self.rb_cont, self.rb_finite))
        hbox5.addWidget(self.rb_cont)

        # Radiobutton Finite Measurement
        self.rb_finite = QRadioButton("Finite")
        self.rb_finite.toggled.connect(lambda: self.refreshUI(2, self.rb_finite, self.rb_cont))
        hbox5.addWidget(self.rb_finite)

        # Measurement duration QSpinBox
        self.duration = QSpinBox(self)
        self.duration.setMinimum(0)
        self.duration.setMaximum(600)
        self.duration.setValue(300.0)
        self.duration.valueChanged.connect(lambda: self.refreshUI(1, 'duration', self.duration.value()))
        hbox4.addWidget(self.duration)

        # ## Button GroupBox:
        # Group contains:
        # - Start button
        # - Stop button
        # - ProgressBar

        buttonGroup = QGroupBox("Control")
        hbox6 = QHBoxLayout()
        hbox11 = QHBoxLayout()
        vbox3 = QVBoxLayout()
        vbox3.addLayout(hbox6)
        vbox3.addStretch(1)
        vbox3.addLayout(hbox11)
        vbox3.addStretch(1)
        buttonGroup.setLayout(vbox3)

        # Start button
        self.startButton = QPushButton("Start", self)
        self.startButton.clicked.connect(self.startBtn)
        hbox6.addWidget(self.startButton)

        # Stop button
        self.stopButton = QPushButton("Stop", self)
        self.stopButton.clicked.connect(self.stopBtn)
        hbox6.addWidget(self.stopButton)

        # Progress Bar
        self.progress = QProgressBar(self)
        self.progress.setAlignment(Qt.AlignHCenter)
        self.progress.setRange(0, 100)
        hbox11.addWidget(self.progress)

        # ## LCD display group:
        # Group contains widgets:
        # - LCD display green
        # - LCD display red

        lcdGroup = QGroupBox("Count rates")
        hbox7 = QHBoxLayout()
        hbox8 = QHBoxLayout()
        vbox4 = QVBoxLayout()
        vbox4.addLayout(hbox7)
        vbox4.addLayout(hbox8)
        lcdGroup.setLayout(vbox4)

        hbox7.addWidget(self.label7)
        hbox7.addWidget(self.label8)

        # Green channel count rate
        self.green_lcd = QLCDNumber(self)
        self.green_lcd.setNumDigits(12)
        hbox8.addWidget(self.green_lcd)

        # Red channel count rate
        self.red_lcd = QLCDNumber(self)
        self.red_lcd.setNumDigits(12)
        hbox8.addWidget(self.red_lcd)

        # ## General Layout settings:
        self.centralBox = QGroupBox("Settings")
        self.setCentralWidget(self.centralBox)
        # self.centralWidget.setStyleSheet("QMainWindow {background: 'yellow';}");

        # Arrange groups in grid:
        grid = QGridLayout()
        grid.addWidget(filesGroup, 0, 0, 1, 3)
        grid.addWidget(laserGroup, 1, 0, 2, 2)
        grid.addWidget(apdGroup, 1, 2, 1, 1)
        grid.addWidget(buttonGroup, 2, 2, 1, 1)
        grid.addWidget(lcdGroup, 3, 0, 1, 3)
        self.centralBox.setLayout(grid)

    def menueLayout(self):
        """
        Here the file menue gets evoked. The actions are widgets,
        which get connected to the GetFileName method. It directs
        then to different functionality in a separate class.
        """
        menubar = self.menuBar()
        fileMenue = menubar.addMenu('&File')
        fileMenue.addAction(self.loadApp)
        fileMenue.addAction(self.saveApp)
        fileMenue.addAction(self.convertData)
        fileMenue.addAction(self.setArraySize)
        fileMenue.addAction(self.closeApp)

    def getFilename(self):
        """
        Select a file with qdialog.
        The return value of qdialog
        'getOpenFileName' is list
        containing the filter information
        and the absolute path.
        @return: path
        """
        start = 'C:/Users/Karoline2'
        path = QFileDialog.getOpenFileName(None, 'Select file', start)
        return path[0]

    def getDirectory(self):
        """
        Select a directory with qdialog.
        """
        start = 'C:/Users/Karoline2'
        path = QFileDialog.getExistingDirectory(None, 'Select directory', start, QFileDialog.ShowDirsOnly)
        return path

    def getFileLocation(self):
        path = self.getDirectory()
        self._location.setText(path)

    def loadDict(self):
        """
        Load a settings dict from a '*.p' file.
        """
        path = self.getFilename()
        new_dict = self._files.loadSetsDict(path)
        if new_dict is not None:
            self._dict._a.update(new_dict)
            self.refreshUI(3, self._dict._a, 0)
            self.statusBar.showMessage('Settings updated!')
        else:
            self.statusBar.showMessage('No valid settings dictionary in that file!')

    def closeApplication(self):
        """Close the app and animation window via file menue."""
        choice = QMessageBox.question(self, 'Quit!', 'Really quit session?', QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:
            try:
                self._anim.__del__()
            except:
                pass
            sys.exit(0)
        else:
            pass

    def closeEvent(self, event):
        """Close also the animation window when the red 'X' button is pressed."""
        try:
            self._anim.__del__()
        except:
            pass
        sys.exit(0)

    def refreshUI(self, changeType, changeKey, value):
        """
        This is the first connection to the widgets. Here the widgets identify
        by changeType (their type) and changeKey (individual key), and pass a value.
        The values can only be applied if the event variable self._running is set
        to False. Changes are processed in refresher.refreshUI method, which returns
        a whole new dictionary.
        @param changeType: str
        @param changeKey: str
        @param value: int or float
        """
        if self._running.is_set():
            self.statusBar.showMessage("Please don't change parameters during measurement. Stop and restart with new settings.")
        else:
            self._dict._a = self._r.refreshUI(changeType, changeKey, value)
            self.refreshAll()

    def refreshRadioButton(self):
        """The radio buttons need a setChecked update, hence the extra method."""
        state = self._dict._a["Radio"]
        if state == 0:
            self.rb_cont.setChecked(True)
        else:
            self.rb_finite.setChecked(True)

    def refreshAll(self):
        """All the widgets get updated with new values."""
        self.sld_red.setValue(self._dict._a["lpower red"])
        self.sld_green.setValue(self._dict._a["lpower green"])
        self.sb_red.setValue(self._dict._a["lpower red"])
        self.sb_green.setValue(self._dict._a["lpower green"])
        self.sb_sampFreq.setValue(self._dict._a["laser frequency"])
        self.duration.setValue(self._dict._a["Duration"])
        self.refreshRadioButton()
        self.sld_percentage.setValue(self._dict._a["laser percentageG"])
        self.sb_percentG.setValue(self._dict._a["laser percentageG"])
        self.sb_percentR.setValue(self._dict._a["laser percentageR"])

    def startBtn(self):
        """
        Set the flag of '_running' to True and close
        all active (additional) windows. Then start
        the processes. If users click on start while
        the measurement is already running, a message
        'Already running' is displayed.
        """
        if not self._running.is_set():
            self._running.set()
            # try to close animation and timetrace window
            # if timetrace does not close reliably, it could
            # cause problems
            try:
                plt.close('all')
            except:
                pass
            self.startProcesses()
        else:
            self.statusBar.showMessage("Already running!")

    def finalLocation(self):
        """
        Calls the hdf mask, from which the sample name gets retrieved. Combined with
        actual date and time, it creates a new folder in the 'location' directory.
        Measurements settings and hdf info get saved into that new folder as .p and
        .txt files. If the hdfmask window is not exited by 'save', the measurement
        will be canceled.
        @return: str
        """
        if self._dict._a["Radio"] == 0:
            new_folder = 'Cont'
            self.statusBar.showMessage("You are measuring in 'continuous' mode. The data will not get saved!")
        elif self._dict._a["Radio"] == 1:
            if self._location.text():
                new_folder = self._files.saveRawData(self._location.text(), self._dict._a)
                if not new_folder:
                    return 0
            else:
                self.statusBar.showMessage('Please select a file directory!')
                new_folder = 0
        return new_folder

    def startProcesses(self):
        """Get folder and start all processes and threads."""
        self._new_folder = self.finalLocation()
        if self._new_folder:
            pass
        else:
            self.statusBar.showMessage('Please select a file location with the "Browse" button or save specs.')
            self._running.clear()
            return

        # Initialize processes and waiter thread
        self._duration = self._dict._a["Duration"]
        self._counter2 = libs.Counter.Counter(self._running, self._dataQ2, self._readArraySize,
                                              self._semaphore, 2)
        self._counter1 = libs.Counter.Counter(self._running, self._dataQ1, self._readArraySize,
                                              self._semaphore, 1)
        self._laser = libs.Laser.Laser(self._running, self._dict._a, self._semaphore)
        self._anim = libs.Animation.Animation(self._animDataQ1, self._animDataQ2, self.signal)
        self._dataProcesser1 = libs.DataProcesser.DataProcesser(self._dataQ1, self._animDataQ1,
                                                                self._readArraySize, 1, self._new_folder)
        self._dataProcesser2 = libs.DataProcesser.DataProcesser(self._dataQ2, self._animDataQ2,
                                                                self._readArraySize, 2, self._new_folder)
        self.statusBar.showMessage("Started!")
        self._anim.run()
        self._u = Thread(target=self.waiter, args=(), name='iterator', daemon=True)

        # Starting all processes and threads
        self._counter2.start()
        self._counter1.start()
        self._laser.start()
        self._u.start()
        self._dataProcesser1.start()
        self._dataProcesser2.start()
        self._anim.animate()    # this command is vicious, it seems everything following
                                # it gets delayed or not executed at all. Best always called last.

    def waiter(self):
        """
        Illumination and APDs acquire the semaphore after initialization of tasks,
        the waiter waits for the semaphore to have its internal counter down to zero
        (when als tasks are ready). Only then the waiter proceeds and does actually
        nothing (mode = 0 --> continuous mode) or starts the progressBar and timing
        (mode 1 --> finite mode). In case of finite mode, the waiter stops the measurement
        after the duration elapses. In continuous mode, the measuremt  must be stopped by
        the user In case of finite mode, the waiter stops the measurement after the
        duration elapses. In continuous mode, the measuremt  must be stopped by the user.
        """
        while self._semaphore.get_value() > 0:
            pass
        if self._dict._a["Radio"] == 0:
            self.progress.setRange(0, 0)
        else:
            # duration = self._dict._a["Duration"]
            duration_iter = np.arange(self._duration)
            self.progress.setRange(0, self._duration)
            for sec in duration_iter:
                time.sleep(1)
                self.signal.measurementProgress.emit(sec)
                if not self._running.is_set():
                    break
            else:
                self.signal.stopMeasurement.emit()

    @pyqtSlot(int)
    def setProgressBar(self, i):
        """
        Setting the progressbar, it gets called
        solely by a pyqtSignal from the waiter thread.
        @param i: int
        """
        self.progress.setValue(i)

    @pyqtSlot(list)
    def displayRatesOnLCD(self, x):
        """
        Setting the lcd numbers with the count rates,
        it gets called solely by a pyqtSignal from the
        animation class.
        """
        self.red_lcd.display(x[1])
        self.green_lcd.display(x[0])

    @pyqtSlot()
    def warnPopUp(self):
        """
        Called from Animation if the count rate of one of the APDs is
        higher than 15MHz (15Mc/s). It pops up a message window,
        informing the user. Currently no stop mechanism is included,
        so the user has to stop the measurement mechanically.
        """
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        msg.setText("APD count should not exceed 15 MHz!\nStop the measurement, check APDs and sample.")
        msg.setWindowTitle("APD Warning")
        msg.exec()

    def changeArraySize(self):
        answer = self._changeRA.showDialog()
        if answer is None:
            pass
        else:
            self._readArraySize = answer
            msg = 'The read array size is now {}'.format(self._readArraySize)
            self.statusBar.showMessage(msg)
        print(answer, self._readArraySize)

    @pyqtSlot()
    def stopBtn(self):
        """
        Try to stop animation and join all the processes/threads.
        Extensive checking can be shortened.
        """
        if self._running.is_set():
            self._running.clear()
            self._anim.anim._stop()

            self.progress.setRange(0, 1)
            while not self._semaphore.get_value() == 3:
                pass

            # joining
            self.statusBar.showMessage("Stopped! Please wait while data is being processed.")
            self._laser.join(timeout=3.0)
            self._u.join(timeout=3.0)
            self._counter1.join(timeout=5.0)
            self._counter2.join(timeout=5.0)
            self._dataProcesser2.join(timeout=5.0)
            self._dataProcesser1.join(timeout=5.0)

            # extensive checking for joining
            check = 0
            if self._dataProcesser1.is_alive():
                print("DataProcesser 1 did not join.")
                del self._dataProcesser1
                check += 1
            if self._dataProcesser2.is_alive():
                print("DataProcesser 2 did not join.")
                del self._dataProcesser2
                check += 1
            if self._counter1.is_alive():
                print("Counter 1 did not join.")
                del self._counter1
                check += 1
            if self._counter2.is_alive():
                print("Counter 2 did not join.")
                del self._counter2
                check += 1
            if self._u.is_alive():
                print("Waiter thread did not join.")
                del self._u
                check += 1
            if self._laser.is_alive():
                print("Laser did not join.")
                del self._laser
                check += 1
            if not check:
                print("All workers have joined.")

            # Print the timetrace of the data, is also saved as *.png into the data folder
            if not self._new_folder == 'Cont':
                self._timetrace.doThings(self._new_folder)
                self._files.convertToPhotonHDF5(self._new_folder, self.signal)
            # Unfortunately there is no other way than deleting the queues
            # If not done so, the rest data will be shown in the next measurement
            # instead of the new data.
            del self._animDataQ1, self._animDataQ2
            self._animDataQ1 = mpQueue()
            self._animDataQ2 = mpQueue()
            self.statusBar.showMessage("Stopped and idle!")
        else:
            self.statusBar.showMessage("Already stopped or not running at all.")
class Window(QWidget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.ui()
        self.current_date()
        self.filling_in_data()

    def ui(self):
        """"
        Прописываем все необходимые видщеты.
        """
        self.setWindowTitle('Курс валюты ЦБ')
        self.setGeometry(320, 320, 200, 100)

        # Создаем два дисплея для отображения курса валют.
        self.hbox_3 = QHBoxLayout()
        self.hbox_4 = QHBoxLayout()
        self.label_usd = QLabel('USD')
        self.label_usd.setPixmap(QPixmap('usd.png'))
        self.label_eur = QLabel('EUR')
        self.label_eur.setPixmap(QPixmap('eur.png'))
        self.lcd = QLCDNumber()
        self.lcd_2 = QLCDNumber()
        self.hbox_3.addWidget(self.label_usd)
        self.hbox_3.addWidget(self.lcd)
        self.hbox_4.addWidget(self.label_eur)
        self.hbox_4.addWidget(self.lcd_2)

        self.hbox_2 = QHBoxLayout()
        self.label = QLabel('День :')
        self.label.setFont(QFont('ubuntu', 15))
        self.label_2 = QLabel('Месяц :')
        self.label_2.setFont(QFont('ubuntu', 15))
        self.label_3 = QLabel('Год :')
        self.label_3.setFont(QFont('ubuntu', 15))
        # Упаковка в горизонтальный контейнер.
        self.hbox_2.addWidget(self.label)
        self.hbox_2.addWidget(self.label_2)
        self.hbox_2.addWidget(self.label_3)
        # Создаем горизонтальный контенер для установки даты.
        self.hbox = QHBoxLayout()
        # 3 Параметра для установки даты для запроса.
        self.date_h = QComboBox()
        self.date_h.setFont(QFont('ubuntu', 12))
        self.month_h = QComboBox()
        self.month_h.setFont(QFont('ubuntu', 12))
        self.year_h = QComboBox()
        self.year_h.setFont(QFont('ubuntu', 12))
        self.btn_cal = QPushButton()
        self.btn_cal.setIcon(QIcon('cal.png'))
        self.dialog = Calendar(self)
        self.btn_cal.clicked.connect(self.dialog.exec)
        # Упаковываем ComboBox в горизонтальный контенер.
        self.hbox.addWidget(self.date_h)
        self.hbox.addWidget(self.month_h)
        self.hbox.addWidget(self.year_h)
        self.hbox.addWidget(self.btn_cal)
        # Создание кнопки.
        self.btn = QPushButton('Получить курс валюты')
        self.btn.clicked.connect(self.currency_parsing)

        # Создаем вертикальный контейнер.
        self.vbox = QVBoxLayout()
        # Упаковка вертикального контейнера.
        self.vbox.addLayout(self.hbox_3)
        self.vbox.addLayout(self.hbox_4)
        self.vbox.addLayout(self.hbox_2)
        self.vbox.addLayout(self.hbox)
        self.vbox.addWidget(self.btn)

        # Отображение контенеров.
        self.setLayout(self.vbox)
        self.show()

    def current_date(self):
        """"
        Получаем текущию дату
        и по умолчанию в параметрах устанавливаем её.
        """
        dt = datetime.now()
        self.date_h.addItem(str(dt.day))
        self.month_h.addItem(str(dt.month))
        self.year_h.addItem(str(dt.year))

    def filling_in_data(self):
        # Заполняем данными параметры через циклы.
        for i in range(1, 32):
            self.date_h.addItem(str(i))

        for i in range(1, 13):
            self.month_h.addItem(str(i))

        for i in range(2020, 1989, -1):
            self.year_h.addItem(str(i))

    def currency_parsing(self):
        """
        парсим курсы валют по API ЦБ РФ.
        Получаем дату для получения курса валют.
        Если число или месяц от 1-9 тогда мы добавляем значения '0'
        для правильного запроса формата 'dd/mm/yyyy'
        """
        d = self.date_h.currentText()
        if len(d) == 1:
            d = '0' + d
        m = self.month_h.currentText()
        if len(m) == 1:
            m = '0' + m
        y = self.year_h.currentText()

        # Делаем проверку даты,если выбраная дата больше текущей тогда выводим ошибку.
        current_date = datetime.now().strftime('%d%m%Y')
        date_comboBox = datetime(int(y), int(m), int(d)).strftime('%d%m%Y')
        if date_comboBox > current_date:
            QMessageBox.about(
                self, 'Сообщение', 'Невозможно получить курс валюты\n'
                'т.к.выбранная дата больше текущего дня.')
        else:

            # Делаем запрос на сайт,передаем ему параметр.
            url = 'http://www.cbr.ru/scripts/XML_daily.asp?'
            params = {'date_req': '{0}/{1}/{2}'.format(d, m, y)}

            try:
                try:
                    request = requests.get(url, params)
                    soup = bs(request.content, 'xml')
                    find_usd = soup.find(ID='R01235').Value.string
                    self.lcd.setDisabled(False)
                    self.lcd.setNumDigits(7)
                    self.lcd.display(find_usd[:6])
                except AttributeError:
                    self.lcd.display('0')
                    self.lcd.setDisabled(True)
                    self.gfgfg()
                try:
                    find_eur = soup.find(ID='R01239').Value.string
                    self.lcd_2.setDisabled(False)
                    self.lcd_2.setNumDigits(7)
                    self.lcd_2.display(find_eur[:6])
                except AttributeError:
                    self.lcd_2.display('0')
                    self.lcd_2.setDisabled(True)
                    self.gfgfg()
            except AttributeError:
                self.lcd.display('0')
                self.lcd_2.display('0')

    def gfgfg(self):
        QMessageBox.about(
            self, 'Соощение',
            'На данную дату мы не смогли получить курс валют\n'
            'At this date we were unable to get the exchange rate')
Ejemplo n.º 12
0
class GamePlayerWidget(QGroupBox):

    def __init__(self, nick, colour=None, parent=None):
        super(GamePlayerWidget, self).__init__(parent)
        self.player = nick
        self.pcolour = colour
        self.initUI()

    def initUI(self):
        #        self.setMinimumWidth(300)
        self.mainLayout = QHBoxLayout(self)
#         self.mainLayout.addStretch()
        self.scoreLCD = QLCDNumber(self)
        self.scoreLCD.setSegmentStyle(QLCDNumber.Flat)
        self.mainLayout.addWidget(self.scoreLCD)
        self.scoreLCD.setNumDigits(3)
        self.scoreLCD.setFixedSize(100, 60)
        self.scoreLCD.display(0)
        css = "QLCDNumber {{ color:rgb({},{},{});}}"
        self.scoreLCD.setStyleSheet(css.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))

        self.nameLabel = QLabel(self)
        self.nameLabel.setText(self.player)
        sh = ("QLabel {{ font-size: 32px; font-weight: "
              "bold; color:rgb({},{},{});}}")
        self.nameLabel.setStyleSheet(sh.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))
        self.mainLayout.addWidget(self.nameLabel)

        self.dealerPixmap = QtGui.QPixmap('icons/cards.png')
        self.nonDealerPixmap = QtGui.QPixmap()
        self.winnerPixmap = QtGui.QPixmap('icons/winner.png')

        self.iconlabel = IconLabel(self)
        self.iconlabel.setFixedSize(50, 50)
        self.iconlabel.setScaledContents(True)
        self.mainLayout.insertWidget(0, self.iconlabel)
#         self.mainLayout.addStretch()
        self.unsetDealer()

    def updateDisplay(self, points):
        if points >= 1000:
            self.scoreLCD.setNumDigits(4)
        self.scoreLCD.display(points)

    def setDealer(self): self.iconlabel.setPixmap(self.dealerPixmap)

    def unsetDealer(self): self.iconlabel.setPixmap(self.nonDealerPixmap)

    def setWinner(self): self.iconlabel.setPixmap(self.winnerPixmap)

    def setColour(self, colour):
        self.pcolour = colour
        css = "QLCDNumber {{ color:rgb({},{},{});}}"
        self.scoreLCD.setStyleSheet(css.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))
        sh = ("QLabel {{ font-size: 32px; font-weight: bold; "
              "color:rgb({},{},{});}}")
        self.nameLabel.setStyleSheet(sh.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))
Ejemplo n.º 13
0
class Run_CM110(QMainWindow):
	
	def __init__(self):
		super().__init__()
		
		self.cwd = os.getcwd()
		self.load_()
		
		# Enable antialiasing for prettier plots		
		pg.setConfigOptions(antialias=True)
		self.initUI()
		
		
	def initUI(self):
		
		################### MENU BARS START ##################
		
		MyBar = QMenuBar(self)
		fileMenu = MyBar.addMenu("File")
		fileSavePlt = fileMenu.addAction("Save plots")
		fileSavePlt.triggered.connect(self.save_plots)
		fileSavePlt.setShortcut('Ctrl+P')
		fileSaveSet = fileMenu.addAction("Save settings")        
		fileSaveSet.triggered.connect(self.save_) # triggers closeEvent()
		fileSaveSet.setShortcut('Ctrl+S')
		fileClose = fileMenu.addAction("Close")        
		fileClose.triggered.connect(self.close) # triggers closeEvent()
		fileClose.setShortcut('Ctrl+X')
		
		instMenu = MyBar.addMenu("Instruments")
		self.conMode = instMenu.addAction("Load instruments")
		self.conMode.triggered.connect(self.instrumentsDialog)
		
		################### MENU BARS END ##################
		
		#####################################################
		lbl1 = QLabel("MONOCHROMATOR CM110 settings:", self)
		lbl1.setStyleSheet("color: blue")
		intervals_lbl = QLabel("Number of intervals", self)
		self.combo4 = QComboBox(self)
		mylist4=["1","2"]
		self.combo4.addItems(mylist4)
		self.combo4.setCurrentIndex(mylist4.index(str(self.numofintervals)))
		start_lbl = QLabel("Start[nm]",self)
		stop_lbl = QLabel("Stop[nm]",self)
		step_lbl = QLabel("Step[nm]",self)
		dwelltime = QLabel("Dwell[s]",self)
		
		self.startEdit = [QLineEdit("",self) for tal in range(2)]
		self.stopEdit = [QLineEdit("",self) for tal in range(2)]
		self.stepEdit = [QLineEdit("",self) for tal in range(2)]
		self.dwelltimeEdit = [QLineEdit("",self) for tal in range(2)]
		# disable those fields that will be ignored anyway
		for tal in range(2):
			if tal<self.numofintervals:
				self.startEdit[tal].setText(str(self.start_[tal]))
				self.stopEdit[tal].setText(str(self.stop[tal]))
				self.stepEdit[tal].setText(str(self.step[tal]))
				self.dwelltimeEdit[tal].setText(str(self.dwell_time[tal]))
			else:
				self.startEdit[tal].setEnabled(False)
				self.stopEdit[tal].setEnabled(False)
				self.stepEdit[tal].setEnabled(False)
				self.dwelltimeEdit[tal].setEnabled(False)
		
		lbl3 = QLabel("NEWPORT stepper SMC100:", self)
		lbl3.setStyleSheet("color: blue")
		startst_lbl = QLabel("Start",self)
		stopst_lbl = QLabel("Stop",self)
		stepst_lbl = QLabel("Step",self)
		lcdst_lbl = QLabel("Current pos",self)
		self.startst_Edit = QLineEdit(str(self.startst),self) 
		self.stopst_Edit = QLineEdit(str(self.stopst),self) 
		self.stepst_Edit = QLineEdit(str(self.stepst),self)
		self.lcdst = QLCDNumber(self)
		self.lcdst.setStyleSheet("color: blue")
		#self.lcdst.setFixedHeight(40)
		self.lcdst.setSegmentStyle(QLCDNumber.Flat)
		self.lcdst.setNumDigits(5)
		self.lcdst.display("-----")
		
		lbl2 = QLabel("ARDUINO Mega2560 settings:", self)
		lbl2.setStyleSheet("color: blue")
		dwelltime_lbl = QLabel("Dwell time [ms]",self)
		self.dwelltimeEdit_ard = QLineEdit(str(self.dwell_time_ard),self)
		
		avgpts_lbl = QLabel("Averaging points", self)
		self.combo1 = QComboBox(self)
		mylist=["1","5","10","50","100","200"]
		self.combo1.addItems(mylist)
		self.combo1.setCurrentIndex(mylist.index(str(self.avg_pts)))
		
		lbl4 = QLabel("STORAGE filename and location settings:", self)
		lbl4.setStyleSheet("color: blue")
		filename = QLabel("folder/file",self)
		self.filenameEdit = QLineEdit(self.filename_str,self)
		
		lbl6 = QLabel("PLOT options:", self)
		lbl6.setStyleSheet("color: blue")
		mylist2=["200","400","800","1600","3200","6400"]
		
		schroll_lbl = QLabel("Schroll time after",self)
		self.combo2 = QComboBox(self)
		self.combo2.addItems(mylist2)
		self.combo2.setCurrentIndex(mylist2.index(str(self.schroll_time)))
		
		schroll2_lbl = QLabel("Schroll wavelength after",self)
		self.combo3 = QComboBox(self)
		self.combo3.addItems(mylist2)
		self.combo3.setCurrentIndex(mylist2.index(str(self.schroll_wl)))
		
		##############################################
		
		lbl5 = QLabel("RECORD data and save images:", self)
		lbl5.setStyleSheet("color: blue")
		
		#save_str = QLabel("Store settings", self)
		#self.saveButton = QPushButton("Save",self)
		#self.saveButton.setEnabled(True)
		
		run_str = QLabel("Record lock-in data", self)
		self.runButton = QPushButton("Load instruments",self)
		
		#saveplots_str = QLabel("Save plots as png", self)
		#self.saveplotsButton = QPushButton("Save plots",self)
		#self.saveplotsButton.setEnabled(True)
		'''
		elapsedtime_str = QLabel('Show voltage vs. time', self)
		self.elapsedtimeButton = QPushButton("Plot 2",self)
		self.elapsedtimeButton.setEnabled(False)
		'''
		cancel_str = QLabel("Stop current run", self)
		self.stopButton = QPushButton("STOP",self)
		self.stopButton.setEnabled(False)
		
		##############################################
		
		# status info which button has been pressed
		#self.status_str = QLabel("Edit settings and press SAVE!", self)
		#self.status_str.setStyleSheet("color: green")
		
		##############################################
		
		# status info which button has been pressed
		self.elapsedtime_str = QLabel("TIME trace for storing plots and data:", self)
		self.elapsedtime_str.setStyleSheet("color: blue")
		
		##############################################
		
		self.lcd = QLCDNumber(self)
		self.lcd.setStyleSheet("color: red")
		self.lcd.setFixedHeight(60)
		self.lcd.setSegmentStyle(QLCDNumber.Flat)
		self.lcd.setNumDigits(11)
		self.lcd.display(self.timestr)
			
		##############################################
		# Add all widgets		
		g1_0 = QGridLayout()
		g1_0.addWidget(MyBar,0,0)
		g1_0.addWidget(lbl1,1,0)
		g1_1 = QGridLayout()
		#g1_1.addWidget(cm110port,0,0)
		#g1_1.addWidget(self.cm110portEdit,0,1)
		
		g1_3 = QGridLayout()
		g1_3.addWidget(intervals_lbl,0,0)
		g1_3.addWidget(self.combo4,0,1)
		g1_2 = QGridLayout()
		g1_2.addWidget(start_lbl,0,0)
		g1_2.addWidget(stop_lbl,0,1)
		g1_2.addWidget(step_lbl,0,2)
		g1_2.addWidget(dwelltime,0,3)
		for tal in range(2):
			g1_2.addWidget(self.startEdit[tal],1+tal,0)
			g1_2.addWidget(self.stopEdit[tal],1+tal,1)
			g1_2.addWidget(self.stepEdit[tal],1+tal,2)
			g1_2.addWidget(self.dwelltimeEdit[tal],1+tal,3)
		v1 = QVBoxLayout()
		v1.addLayout(g1_0)
		v1.addLayout(g1_1)
		v1.addLayout(g1_3)
		v1.addLayout(g1_2)
		
		g9_0 = QGridLayout()
		g9_0.addWidget(lbl3,0,0)
		g9_1 = QGridLayout()
		g9_1.addWidget(startst_lbl,0,0)
		g9_1.addWidget(stopst_lbl,0,1)
		g9_1.addWidget(stepst_lbl,0,2)
		g9_1.addWidget(lcdst_lbl,0,3)
		g9_1.addWidget(self.startst_Edit,1,0)
		g9_1.addWidget(self.stopst_Edit,1,1)
		g9_1.addWidget(self.stepst_Edit,1,2)
		g9_1.addWidget(self.lcdst,1,3)
		v9 = QVBoxLayout()
		v9.addLayout(g9_0)
		v9.addLayout(g9_1)
		
		g2_0 = QGridLayout()
		g2_0.addWidget(lbl2,0,0)
		g2_1 = QGridLayout()
		#g2_1.addWidget(ardport,0,0)
		g2_1.addWidget(dwelltime_lbl,0,0)
		g2_1.addWidget(avgpts_lbl,1,0)
		#g2_1.addWidget(self.ardportEdit,0,1)
		g2_1.addWidget(self.dwelltimeEdit_ard,0,1)
		g2_1.addWidget(self.combo1,1,1)
		v2 = QVBoxLayout()
		v2.addLayout(g2_0)
		v2.addLayout(g2_1)
		
		g4_0 = QGridLayout()
		g4_0.addWidget(lbl4,0,0)
		g4_1 = QGridLayout()
		g4_1.addWidget(filename,0,0)
		g4_1.addWidget(self.filenameEdit,0,1)
		v4 = QVBoxLayout()
		v4.addLayout(g4_0)
		v4.addLayout(g4_1)
				
		g7_0 = QGridLayout()
		g7_0.addWidget(lbl6,0,0)
		g7_1 = QGridLayout()
		g7_1.addWidget(schroll2_lbl,0,0)
		g7_1.addWidget(self.combo3,0,1)
		g7_1.addWidget(schroll_lbl,1,0)
		g7_1.addWidget(self.combo2,1,1)
		v7 = QVBoxLayout()
		v7.addLayout(g7_0)
		v7.addLayout(g7_1)
		
		g5_0 = QGridLayout()
		g5_0.addWidget(lbl5,0,0)
		g5_1 = QGridLayout()
		#g5_1.addWidget(save_str,0,0)
		g5_1.addWidget(run_str,0,0)
		#g5_1.addWidget(saveplots_str,2,0)
		g5_1.addWidget(cancel_str,1,0)
		#g5_1.addWidget(self.saveButton,0,1)
		g5_1.addWidget(self.runButton,0,1)
		#g5_1.addWidget(self.saveplotsButton,2,1)
		g5_1.addWidget(self.stopButton,1,1)
		v5 = QVBoxLayout()
		v5.addLayout(g5_0)
		v5.addLayout(g5_1)
		
		g6_0 = QGridLayout()
		g6_0.addWidget(self.elapsedtime_str,0,0)
		g6_0.addWidget(self.lcd,1,0)
		v6 = QVBoxLayout()
		v6.addLayout(g6_0)
		
		# add all groups from v1 to v6 in one vertical group v7
		v8 = QVBoxLayout()
		v8.addLayout(v1)
		v8.addLayout(v9)
		v8.addLayout(v2)
		v8.addLayout(v4)
		v8.addLayout(v7)
		v8.addLayout(v5)
		v8.addLayout(v6)
	
		# set graph  and toolbar to a new vertical group vcan
		vcan = QVBoxLayout()
		self.pw1 = pg.PlotWidget(name="Plot1")  ## giving the plots names allows us to link their axes together
		vcan.addWidget(self.pw1)
		self.pw2 = pg.PlotWidget(name="Plot2")
		vcan.addWidget(self.pw2)

		# SET ALL VERTICAL COLUMNS TOGETHER
		hbox = QHBoxLayout()
		hbox.addLayout(v8,1)
		hbox.addLayout(vcan,3.75)
		
    ##############################################
    # PLOT 1 settings
		# create plot and add it to the figure canvas		
		self.p0 = self.pw1.plotItem
		self.curve1=[self.p0.plot()]
		# create plot and add it to the figure
		self.p0vb = pg.ViewBox()
		self.curve5=pg.PlotCurveItem(pen=None)
		self.p0vb.addItem(self.curve5)
		# connect respective axes to the plot 
		self.p0.showAxis('right')
		self.p0.getAxis('right').setLabel("10-bit Arduino output")
		self.p0.scene().addItem(self.p0vb)
		self.p0.getAxis('right').linkToView(self.p0vb)
		self.p0vb.setXLink(self.p0)
		# Use automatic downsampling and clipping to reduce the drawing load
		self.pw1.setDownsampling(mode='peak')
		self.pw1.setClipToView(True)
		
		# PLOT 2 settings
		# create plot and add it to the figure canvas
		self.p1 = self.pw2.plotItem
		self.curve2=self.p1.plot(pen='r')
		self.curve3=self.p1.plot()
		# create plot and add it to the figure
		self.p2 = pg.ViewBox()
		self.curve4=pg.PlotCurveItem(pen='y')
		self.curve6=pg.PlotCurveItem(pen='m')
		self.p2.addItem(self.curve4)
		self.p2.addItem(self.curve6)
		# connect respective axes to the plot 
		self.p1.showAxis('right')
		self.p1.getAxis('right').setLabel("Wavelength", units='m', color='yellow')
		self.p1.scene().addItem(self.p2)
		self.p1.getAxis('right').linkToView(self.p2)
		self.p2.setXLink(self.p1)
		# Use automatic downsampling and clipping to reduce the drawing load
		self.pw2.setDownsampling(mode='peak')
		self.pw2.setClipToView(True)
		
		# Initialize and set titles and axis names for both plots
		self.clear_vars_graphs()
		###############################################################################
		
		self.inst_list = {}
		self.colors = itertools.cycle(["r", "b", "g", "y", "m", "c", "w"])
		
		self.threadpool = QThreadPool()
		print("Multithreading in Run_COMPexPRO with maximum %d threads" % self.threadpool.maxThreadCount())
		
		# reacts to choises picked in the menu
		self.combo1.activated[str].connect(self.onActivated1)
		self.combo2.activated[str].connect(self.onActivated2)
		self.combo3.activated[str].connect(self.onActivated3)
		self.combo4.activated[str].connect(self.onActivated4)
		
		# save all paramter data in the config file
		#self.saveButton.clicked.connect(self.save_)
		#self.saveButton.clicked.connect(self.set_elapsedtime_text)
	
		# run the main script
		self.runButton.clicked.connect(self.set_run)
		
		# cancel the script run
		self.stopButton.clicked.connect(self.set_stop)
		
		self.allFields(False)
		
		##############################################
		
		self.timer = QTimer(self)
		self.timer.timeout.connect(self.set_disconnect)
		self.timer.setSingleShot(True)
		
		##############################################
		
		self.setGeometry(100, 100, 1100, 650)
		self.setWindowTitle("Monochromator CM110 Control And Data Acqusition")
		
		w = QWidget()
		w.setLayout(hbox)
		self.setCentralWidget(w)
		self.show()
		
		
	def instrumentsDialog(self):
		
		self.Inst = Instruments_dialog.Instruments_dialog(self,self.inst_list,self.cwd,self.lcdst)
		self.Inst.exec()
		
		if self.inst_list.get("CM110") or self.inst_list.get("Ard") or self.inst_list.get("SR530") or self.inst_list.get("SMC100"):
			self.allFields(True)
			self.runButton.setText("Scan")
			self.timer.start(1000*60*self.minutes)
		else:
			self.allFields(False)
			self.runButton.setText("Load instrument!")
			
			
	def allFields(self,trueorfalse):
		
		for tal in range(2):
			if tal<self.numofintervals:
				self.startEdit[tal].setEnabled(trueorfalse)
				self.stopEdit[tal].setEnabled(trueorfalse)
				self.stepEdit[tal].setEnabled(trueorfalse)
				self.dwelltimeEdit[tal].setEnabled(trueorfalse)
		
		self.startst_Edit.setEnabled(trueorfalse)
		self.stopst_Edit.setEnabled(trueorfalse)
		self.stepst_Edit.setEnabled(trueorfalse)
		
		self.dwelltimeEdit_ard.setEnabled(trueorfalse)
		
		self.combo1.setEnabled(trueorfalse)
		self.combo2.setEnabled(trueorfalse)
		self.combo3.setEnabled(trueorfalse)
		self.combo4.setEnabled(trueorfalse)
		
		self.filenameEdit.setEnabled(trueorfalse)
		self.runButton.setEnabled(trueorfalse)
		
		
	def onActivated1(self, text):
		
		self.avg_pts = str(text)
		
		
	def onActivated2(self, text):
		
		self.schroll_time=int(text)
		
		
	def onActivated3(self, text):
		
		self.schroll_wl=int(text)
		
		
	def onActivated4(self, text):
		
		self.numofintervals = int(text)
		for tal in range(2):
			if tal<self.numofintervals:
				self.startEdit[tal].setEnabled(True)
				self.stopEdit[tal].setEnabled(True)
				self.stepEdit[tal].setEnabled(True)
				self.dwelltimeEdit[tal].setEnabled(True)
			else:
				self.startEdit[tal].setEnabled(False)
				self.stopEdit[tal].setEnabled(False)
				self.stepEdit[tal].setEnabled(False)
				self.dwelltimeEdit[tal].setEnabled(False)
				
	
	# Check input if a number, ie. digits or fractions such as 3.141
	# Source: http://www.pythoncentral.io/how-to-check-if-a-string-is-a-number-in-python-including-unicode/
	def is_number(self,s):
		try:
			float(s)
			return True
		except ValueError:
			pass

		try:
			import unicodedata
			unicodedata.numeric(s)
			return True
		except (TypeError, ValueError):
			pass
		
		return False
	
	
	def create_file(self, mystr):
		
		head, ext = os.path.splitext(mystr)
		#print("head: ",head)
		#print("ext: ",ext)
		#print("filename: ",self.filenameEdit.text())
		
		totalpath = ''.join([self.cwd,os.sep,head,'_',self.timestr,ext])
		my_dir = os.path.dirname(totalpath)
		
		if not os.path.isdir(my_dir):
			QMessageBox.warning(self, "Message","".join(["Folder(s) named ",my_dir," will be created!"]))
			
		try:
			os.makedirs(my_dir, exist_ok=True)
		except Exception as e:
			QMessageBox.critical(self, "Message","".join(["Folder named ",head," not valid!\n\n",str(e)]))
			return ""
		
		return totalpath
	
	
	def set_run(self):
		
		# MINIMUM REQUIREMENTS for proper run
		if not self.inst_list.get("CM110") and not self.inst_list.get("SR530") and not self.inst_list.get("Ard") and not self.inst_list.get("SMC100"):
			QMessageBox.critical(self, 'Message',"No instruments connected. At least 1 instrument is required.")
			return
			
		########################################################
		
		if self.inst_list.get("SMC100"):
			val = self.inst_list.get("SMC100").return_ts(1)
			if val[-2:] not in ["32","33","34","35"]:
				# RESET the stepper if active
				self.Reset_dialog = Reset_dialog.Reset_dialog(self, self.inst_list)
				self.Reset_dialog.exec()
				# Checkif the stepper is ready
				val = self.inst_list.get("SMC100").return_ts(1)
				if val[-2:] not in ["32","33","34","35"]:
					return
				
		########################################################
		
		try:
			for i in range(self.numofintervals):
				arr = numpy.arange(int(self.startEdit[i].text()),int(self.stopEdit[i].text()),int(self.stepEdit[i].text()))
				if len(arr)==0:
					QMessageBox.warning(self, 'Message',''.join(["Empty array returned. Check wavelength start and stop values!"]))
					return
		except Exception as e:
			QMessageBox.warning(self, 'Message',''.join(["All wavelength scan parameters should be integers!\n\n",str(e)]))
			return
		
		try:
			arr = numpy.arange(float(self.startst_Edit.text()),float(self.stopst_Edit.text()),float(self.stepst_Edit.text()))
			if len(arr)==0:
				QMessageBox.warning(self, 'Message',''.join(["Empty array returned. Check Newport start and stop values!"]))
				return
		except Exception as e:
			QMessageBox.warning(self, 'Message',''.join(["All stepper position parameters should be real numbers!\n\n",str(e)]))
			return
		
		for i in range(self.numofintervals):
			if not self.is_number(self.dwelltimeEdit[i].text()):
				QMessageBox.warning(self, 'Message',"Dwell time scan parameter is not a real number!")
				return
		
		# For SAVING data
		if "\\" in self.filenameEdit.text():
			self.filenameEdit.setText(self.filenameEdit.text().replace("\\",os.sep))
			
		if "/" in self.filenameEdit.text():
			self.filenameEdit.setText(self.filenameEdit.text().replace("/",os.sep))
			
		if not self.filenameEdit.text():
			self.filenameEdit.setText(''.join(["data",os.sep,"data"]))
		
		if not os.sep in self.filenameEdit.text():
			self.filenameEdit.setText(''.join(["data", os.sep, self.filenameEdit.text()]))
			
		# Initial read of the config file		
		start_sc = [int(self.startEdit[i].text()) for i in range(self.numofintervals)]
		stop_sc = [int(self.stopEdit[i].text()) for i in range(self.numofintervals)]
		step_sc = [int(self.stepEdit[i].text()) for i in range(self.numofintervals)]
		start_st = float(self.startst_Edit.text())
		stop_st = float(self.stopst_Edit.text())
		step_st = float(self.stepst_Edit.text())
		dwelltime = [float(self.dwelltimeEdit[ii].text()) for ii in range(self.numofintervals)]
		dwell_ard = float(self.dwelltimeEdit_ard.text())
		file_txt = self.create_file(''.join([self.filenameEdit.text(),".txt"]))
		file_hdf5 = self.create_file(''.join([self.filenameEdit.text(),".hdf5"]))
		
		for start,stop,step,dwell in zip(start_sc,stop_sc,step_sc,dwelltime):
			
			if start<0 or start>9000:
				QMessageBox.warning(self, 'Message',"Minimum start wavelength is 0 nm and maximum 9000 nm!")
				return
			
			if stop<0 or stop>9000:
				QMessageBox.warning(self, 'Message',"Minimum stop wavelength is 0 nm and maximum 9000 nm!")
				return
			
			if step<0 or step>127:
				QMessageBox.warning(self, 'Message',"Minimum step is 0 units and maximum 127 units!")
				return
			
			if dwell<3*dwell_ard/1000 or dwell>100:
				QMessageBox.warning(self, 'Message',"Monochromator dwell time is minimum 3 times Arduino dwell time and maximum 100 s!")
				return
			
			if dwell_ard<10 or dwell_ard>dwell*1000:
				QMessageBox.warning(self, 'Message',"Arduino dwell time is minimum 10 ms and maximum CM110 dwell time!")
				return
		
		self.clear_vars_graphs()
		
		self.allFields(False)
		self.conMode.setEnabled(False)
		self.runButton.setEnabled(False)
		self.stopButton.setEnabled(True)
		self.stopButton.setText("STOP")
		self.runButton.setText("Scanning...")
		
		self.timer.stop()
		self.get_thread=Run_CM110_Thread(start_sc,stop_sc,step_sc,dwelltime,dwell_ard,self.avg_pts,file_txt,file_hdf5,self.timestr,self.analogref,self.inst_list,start_st,stop_st,step_st)
		
		self.get_thread.signals.make_update1.connect(self.make_update1)
		self.get_thread.signals.make_update2.connect(self.make_update2)
		self.get_thread.signals.make_update3.connect(self.make_update3)
		self.get_thread.signals.make_update4.connect(self.make_update4)
		self.get_thread.signals.finished.connect(self.finished)
		# Execute
		self.threadpool.start(self.get_thread)
		
		
	def make_update1(self,set_position,real_positions,endpoint_data,endpoints_times,raw_data):
		
		self.set_wl.extend([ 1e-9*set_position ])
		self.real_wl.extend([ 1e-9*real_positions ])
		self.all_volts.extend([ endpoint_data  ])	
		self.all_times.extend([ endpoints_times ])
		self.all_raw.extend([ raw_data ])
		
		if len(self.set_wl)>self.schroll_wl:
			self.plot_volts[:-1] = self.plot_volts[1:]  # shift data in the array one sample left
			self.plot_volts[-1] = endpoint_data
			self.plot_wl[:-1] = self.plot_wl[1:]  # shift data in the array one sample left
			self.plot_wl[-1] = 1e-9*set_position
			self.plot_set_wl[:-1] = self.plot_set_wl[1:]  # shift data in the array one sample left
			self.plot_set_wl[-1] = 1e-9*set_position
			self.plot_real_wl[:-1] = self.plot_real_wl[1:]  # shift data in the array one sample left
			self.plot_real_wl[-1] = 1e-9*real_positions
			self.plot_raw[:-1] = self.plot_raw[1:]  # shift data in the array one sample left
			self.plot_raw[-1] = raw_data
		else:
			self.plot_volts.extend([ float(endpoint_data)  ])
			self.plot_wl.extend([ 1e-9*set_position ])
			self.plot_set_wl.extend([ 1e-9*set_position ])
			self.plot_real_wl.extend([ 1e-9*real_positions ])
			self.plot_raw.extend([ int(raw_data)  ])
		
		self.curve1[-1].setData(self.plot_wl, self.plot_volts)
		self.curve5.setData(self.plot_set_wl, self.plot_raw)
		
		## Handle view resizing 
		def updateViews():
			## view has resized; update auxiliary views to match
			self.p0vb.setGeometry(self.p0.vb.sceneBoundingRect())
			## need to re-update linked axes since this was called
			## incorrectly while views had different shapes.
			## (probably this should be handled in ViewBox.resizeEvent)
			self.p0vb.linkedViewChanged(self.p0.vb, self.p0vb.XAxis)
		updateViews()
		self.p0.vb.sigResized.connect(updateViews)
		
		###########################################################
		# Update curve3 in different plot
		if len(self.set_wl_tr)>=self.schroll_time:
			local_times=self.all_times[-self.counter:]
			local_volts=self.all_volts[-self.counter:]
			self.curve3.setData(local_times, local_volts)
		else:
			self.curve3.setData(self.all_times, self.all_volts)
		
		
	def make_update2(self,set_position,real_positions,all_data,timelist):
		
		self.set_wl_tr.extend([ 1e-9*set_position ])
		self.real_wl_tr.extend([ 1e-9*real_positions ])
		#self.all_volts_tr.extend([ float(all_data) ])
		#self.all_time_tr.extend([ float(timelist) ])
				
		if len(self.set_wl_tr)==self.schroll_time:
			self.counter=len(self.set_wl)

		if len(self.set_wl_tr)>self.schroll_time:
			self.plot_time_tr[:-1] = self.plot_time_tr[1:]  # shift data in the array one sample left
			self.plot_time_tr[-1] = timelist
			self.plot_volts_tr[:-1] = self.plot_volts_tr[1:]  # shift data in the array one sample left
			self.plot_volts_tr[-1] = all_data
			self.plot_set_wl_tr[:-1] = self.plot_set_wl_tr[1:]  # shift data in the array one sample left
			self.plot_set_wl_tr[-1] = 1e-9*set_position
			self.plot_real_wl_tr[:-1] = self.plot_real_wl_tr[1:]  # shift data in the array one sample left
			self.plot_real_wl_tr[-1] = 1e-9*real_positions
		else:
			self.plot_set_wl_tr.extend([ 1e-9*set_position ])
			self.plot_real_wl_tr.extend([ 1e-9*real_positions ])
			self.plot_volts_tr.extend([ all_data ])
			self.plot_time_tr.extend([ timelist ])

		## Handle view resizing 
		def updateViews():
			## view has resized; update auxiliary views to match
			self.p2.setGeometry(self.p1.vb.sceneBoundingRect())
			#p3.setGeometry(p1.vb.sceneBoundingRect())

			## need to re-update linked axes since this was called
			## incorrectly while views had different shapes.
			## (probably this should be handled in ViewBox.resizeEvent)
			self.p2.linkedViewChanged(self.p1.vb, self.p2.XAxis)
			#p3.linkedViewChanged(p1.vb, p3.XAxis)
			
		updateViews()
		self.p1.vb.sigResized.connect(updateViews)
		self.curve2.setData(self.plot_time_tr, self.plot_volts_tr)
		self.curve4.setData(self.plot_time_tr, self.plot_set_wl_tr)
		self.curve6.setData(self.plot_time_tr, self.plot_real_wl_tr)
		
		
	def make_update3(self):
		
		self.plot_wl = []
		self.plot_volts = []
		
		mycol=next(self.colors)
		self.curve1.extend( [self.p0.plot(pen=pg.mkPen(mycol,width=1), symbolPen=mycol, symbolBrush=mycol, symbolSize=3)] )
		
		
	def make_update4(self,val):
		
		self.lcdst.display(str(val)[:5])
		
		
	def set_disconnect(self):
		
		##########################################
		
		if self.inst_list.get("CM110"):
			if self.inst_list.get("CM110").is_open():
				self.inst_list.get("CM110").close()
			self.inst_list.pop("CM110", None)
				
		##########################################
		
		if self.inst_list.get("Ard"):
			if self.inst_list.get("Ard").is_open():
				self.inst_list.get("Ard").close()
			self.inst_list.pop("Ard", None)
			
		##########################################
		
		if self.inst_list.get("SR530"):
			if self.inst_list.get("SR530").is_open():
				self.inst_list.get("SR530").close()
			self.inst_list.pop("SR530", None)
			
		##########################################
		
		if self.inst_list.get("SMC100"):
			if self.inst_list.get("SMC100").is_open():
				self.inst_list.get("SMC100").close()
			self.inst_list.pop("SMC100", None)
			
		##########################################
		
		print("All com ports DISCONNECTED")
		
		self.allFields(False)
		self.conMode.setEnabled(True)
		self.runButton.setText("Load instrument!")
		self.runButton.setEnabled(False)
		
		
	def set_stop(self):
		
		self.stopButton.setEnabled(False)
		self.stopButton.setText("Stopped")
		
		if hasattr(self, "get_thread"):
			self.get_thread.abort()
			
		self.stop_pressed = True
		
		
	def clear_vars_graphs(self):
		
		# PLOT 1 initial canvas settings
		self.set_wl=[]
		self.real_wl=[]
		self.all_volts=[]
		self.all_times=[]
		self.all_raw=[]
		self.plot_set_wl=[]
		self.plot_real_wl=[]
		self.plot_raw=[]
		self.plot_volts=[]
		self.plot_wl=[]
		for c in self.curve1:
			c.setData([],[])
		self.curve5.setData(self.plot_set_wl, self.plot_raw)
		self.curve3.setData([], [])
		self.pw1.enableAutoRange()
		# Labels and titels are placed here since they change dynamically
		self.pw1.setTitle(''.join(["CM110 scan as function of wavelength"]))
		self.pw1.setLabel('left', "Voltage", units='V')
		self.pw1.setLabel('bottom', "Wavelength", units='m')
		
		# PLOT 2 initial canvas settings
		self.set_wl_tr=[]
		self.real_wl_tr=[]
		self.plot_set_wl_tr=[]
		self.plot_real_wl_tr=[]
		self.plot_volts_tr=[]
		self.plot_time_tr=[]
		self.curve2.setData(self.plot_time_tr, self.plot_volts_tr)
		self.curve4.setData(self.plot_time_tr, self.plot_set_wl_tr)
		self.curve6.setData(self.plot_time_tr, self.plot_real_wl_tr)
		self.pw2.enableAutoRange()
		# Labels and titels are placed here since they change dynamically
		self.p1.setTitle(''.join(["CM110 scan as function of time"]))
		self.p1.setLabel('left', "Voltage", units='V', color='red')
		self.p1.setLabel('bottom', "Elapsed time", units='s')
		
		self.stop_pressed = False
		
		
	def load_(self):
		
		# Initial read of the config file
		self.config = configparser.ConfigParser()
		try:
			self.config.read(''.join([self.cwd,os.sep,"config.ini"]))
			self.last_used_scan = self.config.get("LastScan","last_used_scan")
			
			self.numofintervals = int(self.config.get(self.last_used_scan,"numofintervals"))
			self.start_ = [int(i) for i in self.config.get(self.last_used_scan,"start").strip().split(',')]
			self.stop = [int(i) for i in self.config.get(self.last_used_scan,"stop").strip().split(',')]
			self.step = [int(i) for i in self.config.get(self.last_used_scan,"step").strip().split(',')]
			
			self.startst = float(self.config.get(self.last_used_scan,"startst"))
			self.stopst = float(self.config.get(self.last_used_scan,"stopst"))
			self.stepst = float(self.config.get(self.last_used_scan,"stepst"))
			
			self.dwell_time = [int(i) for i in self.config.get(self.last_used_scan,"wait_time").strip().split(',')]
			self.dwell_time_ard = int(self.config.get(self.last_used_scan,"wait_time_ard"))
			self.avg_pts = int(self.config.get(self.last_used_scan,"avg_pts"))
			self.schroll_time = int(self.config.get(self.last_used_scan,"schroll_time"))
			self.schroll_wl = int(self.config.get(self.last_used_scan,"schroll_wl"))
			
			self.filename_str = self.config.get(self.last_used_scan,"filename")
			self.timestr = self.config.get(self.last_used_scan,"timestr")
			self.analogref = float(self.config.get(self.last_used_scan,"analogref"))
			self.minutes = float(self.config.get(self.last_used_scan,"timer"))
			
		except configparser.NoOptionError as nov:
			QMessageBox.critical(self, "Message","".join(["Main FAULT while reading the config.ini file\n",str(nov)]))
			raise
		
		
	def save_(self):
		
		self.timestr=time.strftime("%y%m%d-%H%M")
		self.lcd.display(self.timestr)
		
		self.config.set("LastScan","last_used_scan", self.last_used_scan )
		
		self.config.set(self.last_used_scan,"numofintervals",str(self.numofintervals) )
		self.config.set(self.last_used_scan,"start",','.join([str(self.startEdit[ii].text()) for ii in range(self.numofintervals)]) )
		self.config.set(self.last_used_scan,"stop",','.join([str(self.stopEdit[ii].text()) for ii in range(self.numofintervals)]) )
		self.config.set(self.last_used_scan,"step",','.join([str(self.stepEdit[ii].text()) for ii in range(self.numofintervals)]) )
		self.config.set(self.last_used_scan,"wait_time",','.join([str(self.dwelltimeEdit[ii].text()) for ii in range(self.numofintervals)]) )
		
		self.config.set(self.last_used_scan,"startst", str(self.startst_Edit.text()) )
		self.config.set(self.last_used_scan,"stopst", str(self.stopst_Edit.text()) )
		self.config.set(self.last_used_scan,"stepst", str(self.stepst_Edit.text()) )
		
		self.config.set(self.last_used_scan,"wait_time_ard", str(self.dwelltimeEdit_ard.text()) )
		self.config.set(self.last_used_scan,"avg_pts", str(self.avg_pts) )
		self.config.set(self.last_used_scan,"schroll_time", str(self.schroll_time) )
		self.config.set(self.last_used_scan,"schroll_wl", str(self.schroll_wl) )
		
		self.config.set(self.last_used_scan,"filename", self.filenameEdit.text() )
		self.config.set(self.last_used_scan,"timestr", str(self.timestr) )
		self.config.set(self.last_used_scan,"analogref", str(self.analogref) )
		
		with open(''.join([self.cwd,os.sep,"config.ini"]), "w") as configfile:
			self.config.write(configfile)
		
		
	def finished(self):
		
		if not self.stop_pressed:
			self.stopButton.setEnabled(False)
			if hasattr(self, "get_thread"):
				self.get_thread.abort()
			
			self.stop_pressed = True
		
		self.allFields(True)
		self.conMode.setEnabled(True)
		
		if self.inst_list.get("CM110") or self.inst_list.get("SR530") or self.inst_list.get("Ard") or self.inst_list.get("SMC100"):
			self.allFields(True)
			self.runButton.setText("Scan")
		else:
			self.allFields(False)
			self.runButton.setText("Load instrument!")
		
		self.timer.start(1000*60*self.minutes)
		
		
	def closeEvent(self, event):
		
		reply = QMessageBox.question(self, 'Message', "Quit now? Any changes that are not saved will stay unsaved!", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
		
		if reply == QMessageBox.Yes:
			
			if self.inst_list.get("CM110"):
				if not hasattr(self, "get_thread"):
					if self.inst_list.get("CM110").is_open():
						self.inst_list.get("CM110").close()
				else:
					if not self.stop_pressed:
						QMessageBox.warning(self, "Message", "Scan in progress. Stop the scan then quit!")
						event.ignore()
						return
					else:
						if self.inst_list.get("CM110").is_open():
							self.inst_list.get("CM110").close()
							
			if self.inst_list.get("SR530"):
				if not hasattr(self, "get_thread"):
					if self.inst_list.get("SR530").is_open():
						self.inst_list.get("SR530").close()
				else:
					if not self.stop_pressed:
						QMessageBox.warning(self, "Message", "Scan in progress. Stop the scan then quit!")
						event.ignore()
						return
					else:
						if self.inst_list.get("SR530").is_open():
							self.inst_list.get("SR530").close()
			
			if self.inst_list.get("SMC100"):
				if not hasattr(self, "get_thread"):
					if self.inst_list.get("SMC100").is_open():
						self.inst_list.get("SMC100").close()
				else:
					if not self.stop_pressed:
						QMessageBox.warning(self, "Message", "Scan in progress. Stop the scan then quit!")
						event.ignore()
						return
					else:
						if self.inst_list.get("SMC100").is_open():
							self.inst_list.get("SMC100").close()
							
			if self.inst_list.get("Ard"):
				if not hasattr(self, "get_thread"):
					if self.inst_list.get("Ard").is_open():
						self.inst_list.get("Ard").close()
				else:
					if not self.stop_pressed:
						QMessageBox.warning(self, "Message", "Scan in progress. Stop the scan then quit!")
						event.ignore()
						return
					else:
						if self.inst_list.get("Ard").is_open():
							self.inst_list.get("Ard").close()
							
			if hasattr(self, "timer"):
				if self.timer.isActive():
					self.timer.stop()
					
			event.accept()
		else:
		  event.ignore()
		
	##########################################
	
	def save_plots(self):
		
		# For SAVING data
		if "\\" in self.filenameEdit.text():
			self.filenameEdit.setText(self.filenameEdit.text().replace("\\",os.sep))
			
		if "/" in self.filenameEdit.text():
			self.filenameEdit.setText(self.filenameEdit.text().replace("/",os.sep))
			
		if not self.filenameEdit.text():
			self.filenameEdit.setText(''.join(["data",os.sep,"data"]))
		
		if not os.sep in self.filenameEdit.text():
			self.filenameEdit.setText(''.join(["data", os.sep, self.filenameEdit.text()]))
			
		save_plot1 = self.create_file(''.join([self.filenameEdit.text(),".png"]))
		save_plot2 = self.create_file(''.join([self.filenameEdit.text(),"_elapsedtime",".png"]))
		
		# create an exporter instance, as an argument give it
		# the item you wish to export
		exporter = pg.exporters.ImageExporter(self.pw1.plotItem)
		exporter.params.param('width').setValue(1920, blockSignal=exporter.widthChanged)
		exporter.params.param('height').setValue(1080, blockSignal=exporter.heightChanged)
		# set export parameters if needed
		#exporter.parameters()['width'] = 100   # (note this also affects height parameter)
		# save to file
		exporter.export(save_plot1)
		
		exporter = pg.exporters.ImageExporter(self.pw2.plotItem)
		exporter.params.param('width').setValue(1920, blockSignal=exporter.widthChanged)
		exporter.params.param('height').setValue(1080, blockSignal=exporter.heightChanged)
		# set export parameters if needed
		#exporter.parameters()['width'] = 100   # (note this also affects height parameter)
		# save to file
		exporter.export(save_plot2)
Ejemplo n.º 14
0
class Phase10PlayerWidget(GamePlayerWidget):

    roundWinnerSet = QtCore.pyqtSignal(str)

    def __init__(self, nick, engine, bgroup=None, parent=None):
        self.engine = engine
        self.current_phase = min(
            self.engine.getRemainingPhasesFromPlayer(nick))
        self.phases_in_order = self.engine.getPhasesInOrderFlag()
        self.bgroup = bgroup
        super(Phase10PlayerWidget, self).__init__(
            nick, PlayerColours[self.engine.getListPlayers().index(nick)],
            parent)

    def initUI(self):
        css = ("QGroupBox {{ font-size: 28px;"
               "font-weight: bold; color:rgb({},{},{});}}")
        self.setStyleSheet(css.format(self.pcolour.red(),
                                      self.pcolour.green(),
                                      self.pcolour.blue()))
        self.setTitle(self.player)
        super(Phase10PlayerWidget, self).initUI()

        trashWidget = QWidget()
        trashWidget.setLayout(self.mainLayout)

        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.addStretch()
        self.upperLayout = QHBoxLayout()
        self.mainLayout.addLayout(self.upperLayout)
        self.upperLayout.addStretch()
        self.phaseNameLabel = QLabel(self)
        self.phaseNameLabel.setStyleSheet(
            "font-weight: bold; font-size: 24px;")
        self.updatePhaseName()
        self.upperLayout.addWidget(self.phaseNameLabel)
        self.upperLayout.addStretch()
        self.lowerLayout = QHBoxLayout()
        self.mainLayout.addLayout(self.lowerLayout)
        self.mainLayout.addStretch()

        self.phaseLabelsLayout = QGridLayout()
        self.phaseLabelsLayout.setSpacing(5)

        self.checkboxLayout = QVBoxLayout()

        self.scoreLCD = QLCDNumber(self)
        self.scoreLCD.setSegmentStyle(QLCDNumber.Flat)
        self.mainLayout.addWidget(self.scoreLCD)
        self.scoreLCD.setNumDigits(3)
        self.scoreLCD.setMinimumWidth(100)
        css = "QLCDNumber {{ color:rgb({},{},{});}}"
        self.scoreLCD.setStyleSheet(css.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))

        # Left part - score
        self.lowerLayout.addWidget(self.iconlabel)
        self.lowerLayout.addWidget(self.scoreLCD)
        self.lowerLayout.addLayout(self.phaseLabelsLayout)
        self.lowerLayout.addLayout(self.checkboxLayout)

        self.iconlabel.setMinimumSize(60, 60)

#         self.scoreLCD.setMinimumWidth(100)
#         self.scoreLCD.setMaximumWidth(200)
#         self.scoreLCD.setMinimumHeight(60)
#         self.scoreLCD.setMaximumHeight(80)

        self.scoreLCD.display(self.engine.getScoreFromPlayer(self.player))

        # Middle part - Phase list
        self.phaseLabels = list()
        for phase in range(1, 11):
            label = Phase10Label(phase, self)
            if phase == self.current_phase:
                label.setCurrent()
            elif self.engine.hasPhaseCompleted(self.player, phase):
                label.setPassed()
            self.phaseLabels.append(label)
            self.phaseLabelsLayout.addWidget(
                label, (phase-1)/5, (phase-1) % 5, 1, 1)

        # Middle part - Inputs
        self.roundWinnerRadioButton = QRadioButton()
        self.bgroup.addButton(self.roundWinnerRadioButton)
        self.checkboxLayout.addWidget(self.roundWinnerRadioButton)

        self.roundPhaseClearedCheckbox = QCheckBox(self)
        self.checkboxLayout.addWidget(self.roundPhaseClearedCheckbox)

        self.roundScore = Phase10ScoreSpinBox(self)
        self.roundScore.setMaximumWidth(90)
        self.roundScore.valueChanged.connect(self.updateRoundPhaseCleared)
        self.lowerLayout.addWidget(self.roundScore)

        self.roundWinnerRadioButton.toggled.connect(
            self.roundScore.setDisabled)
        self.roundWinnerRadioButton.toggled.connect(
            self.roundPhaseClearedCheckbox.setDisabled)
        self.roundWinnerRadioButton.toggled.connect(
            self.roundPhaseClearedCheckbox.setChecked)
        self.roundWinnerRadioButton.toggled.connect(self.roundWinnerSetAction)

        self.retranslateUI()

    def retranslateUI(self):
        self.roundWinnerRadioButton.setText(
            i18n("Phase10PlayerWidget", "Winner"))
        self.roundPhaseClearedCheckbox.setText(
            i18n("Phase10PlayerWidget", "Completed"))
        self.updatePhaseName()

    def updateDisplay(self, points, completed_phases, remaining_phases):
        if len(remaining_phases) == 0:
            self.current_phase = 0
        else:
            self.current_phase = min(remaining_phases)

        self.roundWinnerRadioButton.setDown(True)
        if points >= 1000:
            self.scoreLCD.setNumDigits(4)
        self.scoreLCD.display(points)
        self.roundScore.setValue(5)
        self.roundScore.clear()
        self.roundPhaseClearedCheckbox.setChecked(False)

        for phase, label in enumerate(self.phaseLabels, start=1):
            if phase == self.current_phase and not self.engine.getWinner():
                if not label.isCurrent():
                    label.setCurrent()
            elif phase in completed_phases:
                if not label.isPassed():
                    label.setPassed()
            else:
                if not label.isRemaining():
                    label.setRemaining()
        self.updatePhaseName()

    def getScore(self):
        if self.isRoundWinner():
            return 0
        try:
            return int(self.roundScore.value())
        except Exception:
            return -1

    def switchPhasesInOrder(self, in_order):
        self.phases_in_order = in_order
        if not self.phases_in_order:
            return
        self.phaseLabels[self.current_phase-1].setRemaining()
        for label in self.phaseLabels:
            if label.isRemaining():
                label.setCurrent()
                self.current_phase = label.getNumber()
                break

    def updatePhaseSelected(self, phaselabel):
        if phaselabel.isRemaining():
            self.current_phase = phaselabel.getNumber()
            for label in self.phaseLabels:
                if label.isCurrent():
                    label.setRemaining()
            phaselabel.setCurrent()
        self.updatePhaseName()

    def updatePhaseName(self):
        phasenames = getPhaseNames(self.engine.getPhases())
        self.phaseNameLabel.setText(phasenames[self.current_phase-1])

    def updateRoundPhaseCleared(self, value):
        try:
            score = int(self.roundScore.text())
        except Exception:
            self.roundPhaseClearedCheckbox.setChecked(False)
            return

        if score < 0:
            if not self.roundWinnerRadioButton.isChecked():
                self.roundPhaseClearedCheckbox.setChecked(False)
            return

        if (score % 5 != 0):
            return

        if (score >= 50):
            self.roundWinnerRadioButton.setChecked(False)
            self.roundPhaseClearedCheckbox.setChecked(False)
        elif (score == 0):
            self.roundWinnerRadioButton.setChecked(True)
            self.roundPhaseClearedCheckbox.setChecked(True)
        else:
            self.roundWinnerRadioButton.setChecked(False)
            self.roundPhaseClearedCheckbox.setChecked(True)

    def mousePressEvent(self, event):
        child = self.childAt(event.pos())
        if child is None:
            self.roundScore.setFocus()
        elif type(child) == Phase10Label and not self.phases_in_order:
            self.updatePhaseSelected(child)
        return QGroupBox.mousePressEvent(self, event)
#

    def isRoundWinner(self): return self.roundWinnerRadioButton.isChecked()

    def getRoundPhase(self): return self.current_phase

    def isRoundCleared(self): return self.roundPhaseClearedCheckbox.isChecked()

    def roundWinnerSetAction(self, isset):
        if isset:
            self.roundWinnerSet.emit(self.player)

    def reset(self): pass

    def finish(self):
        self.roundWinnerRadioButton.toggled.disconnect(
            self.roundScore.setDisabled)
        self.roundWinnerRadioButton.toggled.disconnect(
            self.roundPhaseClearedCheckbox.setDisabled)
        self.roundWinnerRadioButton.toggled.disconnect(
            self.roundPhaseClearedCheckbox.setChecked)
        self.roundWinnerRadioButton.toggled.disconnect(
            self.roundWinnerSetAction)
        self.roundWinnerRadioButton.setDisabled(True)
        self.roundPhaseClearedCheckbox.setDisabled(True)
        self.roundScore.setDisabled(True)

    def setColour(self, colour):
        self.pcolour = colour
        css = ("QGroupBox {{ font-size: 28px; font-weight: bold;"
               "color:rgb({},{},{});}}")
        self.setStyleSheet(css.format(self.pcolour.red(),
                                      self.pcolour.green(),
                                      self.pcolour.blue()))
Ejemplo n.º 15
0
class GUV_TEST_dialog(QDialog):
    def __init__(self, parent):
        super().__init__(parent)

        # Initial read of the config file
        self.config = configparser.ConfigParser()

        try:
            self.config.read('config.ini')
            self.last_used_scan = self.config.get('LastScan', 'last_used_scan')

            #self.log_guv=self.bool_(self.config.get(self.last_used_scan,'log_guv'))
            self.schroll_pts = int(
                self.config.get(self.last_used_scan, 'schroll'))
            self.log_guv_str = self.config.get(self.last_used_scan,
                                               'log_guv').strip().split(',')[0]
            self.log_guv_check = self.bool_(
                self.config.get(self.last_used_scan,
                                'log_guv').strip().split(',')[1])

            self.guvip = self.config.get("Instruments",
                                         'guvport').strip().split(',')[0]
            self.guvport = self.config.get("Instruments",
                                           'guvport').strip().split(',')[1]
            self.guvtype_str = self.config.get("Instruments", 'guvtype')
        except configparser.NoOptionError as e:
            QMessageBox.critical(
                self, 'Message', ''.join(
                    ["Main FAULT while reading the config.ini file\n",
                     str(e)]))
            raise

        self.setupUi()

    def bool_(self, txt):

        if txt == "True":
            return True
        elif txt == "False":
            return False

    def setupUi(self):

        ipport = QLabel("TCP/IP port", self)
        self.ipportEdit = QLineEdit(self.guvip, self)

        tcpport = QLabel("TCP port", self)
        self.tcpportEdit = QLineEdit(self.guvport, self)

        guvtype_lbl = QLabel("GUV type", self)
        self.guvtype_cb = QComboBox(self)
        mylist = ["GUV-541", "GUV-2511", "GUV-3511"]
        self.guvtype_cb.addItems(mylist)
        self.guvtype_cb.setCurrentIndex(mylist.index(self.guvtype_str))

        ##############################################

        self.runstopButton = QPushButton("START", self)
        self.clearButton = QPushButton("Clear", self)

        ##############################################

        schroll_lbl = QLabel("Schroll elapsed time ", self)
        self.combo0 = QComboBox(self)
        mylist0 = ["100", "200", "400", "600", "800", "1000", "1500", "2000"]
        self.combo0.addItems(mylist0)
        self.combo0.setCurrentIndex(mylist0.index(str(self.schroll_pts)))

        ##############################################

        self.cb_logdata = QCheckBox('Log data to file', self)
        self.cb_logdata.toggle()
        self.cb_logdata.setChecked(self.log_guv_check)
        #self.cb_logdata.setLayoutDirection(Qt.RightToLeft)
        self.file_edit = QLineEdit(self.log_guv_str, self)
        self.file_edit.setStyleSheet("color: blue")
        if self.cb_logdata.isChecked():
            self.file_edit.setEnabled(True)
        else:
            self.file_edit.setEnabled(False)

        self.lcd = QLCDNumber(self)
        self.lcd.setStyleSheet("color: red")
        self.lcd.setFixedWidth(170)
        self.lcd.setFixedHeight(35)
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        self.lcd.setNumDigits(11)
        self.time_str = time.strftime("%y%m%d-%H%M")
        self.lcd.display(self.time_str)

        ##############################################

        g0_1 = QGridLayout()
        g0_1.addWidget(ipport, 0, 0)
        g0_1.addWidget(self.ipportEdit, 0, 1)
        g0_1.addWidget(tcpport, 0, 2)
        g0_1.addWidget(self.tcpportEdit, 0, 3)
        g0_1.addWidget(guvtype_lbl, 0, 4)
        g0_1.addWidget(self.guvtype_cb, 0, 5)

        g0_2 = QGridLayout()
        g0_2.addWidget(schroll_lbl, 0, 0)
        g0_2.addWidget(self.combo0, 0, 1)
        g0_2.addWidget(self.runstopButton, 0, 2)
        g0_2.addWidget(self.clearButton, 0, 3)
        g0_2.addWidget(self.cb_logdata, 1, 0)
        g0_2.addWidget(self.lcd, 1, 1)

        g0_4 = QVBoxLayout()
        g0_4.addLayout(g0_1)
        g0_4.addLayout(g0_2)
        g0_4.addWidget(self.file_edit)

        ##############################################

        # set graph  and toolbar to a new vertical group vcan
        self.pw1 = pg.PlotWidget()
        self.pw1.setFixedWidth(600)

        ##############################################

        # create table
        self.tableWidget = self.createTable()

        ##############################################

        # SET ALL VERTICAL COLUMNS TOGETHER
        vbox = QVBoxLayout()
        vbox.addLayout(g0_4)
        vbox.addWidget(self.pw1)

        hbox = QVBoxLayout()
        hbox.addLayout(vbox)
        hbox.addWidget(self.tableWidget)

        self.threadpool = QThreadPool()
        print("Multithreading in the GUV dialog with maximum %d threads" %
              self.threadpool.maxThreadCount())
        self.isRunning = False

        self.setLayout(hbox)
        self.setWindowTitle("Test GUV")

        # PLOT 2 settings
        # create plot and add it to the figure canvas
        self.p1 = self.pw1.plotItem
        self.curves = []
        colors = itertools.cycle(["r", "b", "g", "y", "m", "c", "w"])
        for i in range(20):
            mycol = next(colors)
            self.curves.append(
                self.p1.plot(pen=pg.mkPen(color=mycol),
                             symbol='s',
                             symbolPen=mycol,
                             symbolBrush=mycol,
                             symbolSize=4))
        # create plot and add it to the figure
        self.p0_1 = pg.ViewBox()
        self.curve2 = pg.PlotCurveItem(pen='r')
        self.p0_1.addItem(self.curve2)
        # connect respective axes to the plot
        #self.p1.showAxis('left')
        self.p1.getAxis('left').setLabel("Power density",
                                         units="",
                                         color='yellow')
        self.p1.showAxis('right')
        self.p1.getAxis('right').setLabel("Arb unit", units="", color='red')
        self.p1.scene().addItem(self.p0_1)
        self.p1.getAxis('right').linkToView(self.p0_1)
        self.p0_1.setXLink(self.p1)

        self.p1.getAxis('bottom').setLabel("Time passed",
                                           units="s",
                                           color='yellow')
        # Use automatic downsampling and clipping to reduce the drawing load
        self.pw1.setDownsampling(mode='peak')
        self.pw1.setClipToView(True)

        # Initialize and set titles and axis names for both plots
        self.clear_vars_graphs()
        self.combo0.activated[str].connect(self.onActivated0)
        self.guvtype_cb.activated[str].connect(self.onActivated1)
        self.cb_logdata.toggled.connect(self.logdata)

        # run or cancel the main script
        self.runstopButton.clicked.connect(self.runstop)
        self.clearButton.clicked.connect(self.set_clear)
        self.clearButton.setEnabled(False)

    def logdata(self):

        if self.cb_logdata.isChecked():
            self.time_str = time.strftime("%y%m%d-%H%M")

            head, tail = os.path.split(str(self.file_edit.text()))
            self.log_guv_str = ''.join(
                [head, '/log_', self.guvtype_str, '_', self.time_str])
            self.lcd.display(self.time_str)
            self.file_edit.setText(self.log_guv_str)
            self.file_edit.setEnabled(True)
        else:
            self.file_edit.setEnabled(False)

    def onActivated0(self, text):

        old_st = self.schroll_pts

        self.schroll_pts = int(str(text))

        if old_st > self.schroll_pts:
            self.set_clear()

    def onActivated1(self, text):

        old_guvtype = self.guvtype_str
        self.guvtype_str = str(text)

        if old_guvtype != self.guvtype_str:
            head, tail = os.path.split(str(self.file_edit.text()))
            self.log_guv_str = ''.join(
                [head, '/log_', self.guvtype_str, '_', self.time_str])
            self.file_edit.setText(self.log_guv_str)
            self.set_clear()
            '''
			self.config.set(self.last_used_scan, 'guvtype', self.guvtype_str) 
			with open('config.ini', 'w') as configfile:
				self.config.write(configfile)
			'''

    def createTable(self):

        tableWidget = QTableWidget()
        #tableWidget.setFixedWidth(175)

        # set row count
        #tableWidget.setRowCount(20)

        # set column count
        tableWidget.setColumnCount(2)

        # hide grid
        tableWidget.setShowGrid(False)

        # hide vertical header
        vh = tableWidget.verticalHeader()
        vh.setVisible(False)

        # set the font
        font = QFont("Courier New", 9)
        tableWidget.setFont(font)
        tableWidget.setStyleSheet("color: blue")

        # place content into individual table fields
        #tableWidget.setItem(0,0, QTableWidgetItem("abe"))

        tableWidget.setHorizontalHeaderLabels(
            ["Time[s]", "Channel power density"])
        #tableWidget.setVerticalHeaderLabels(["aa","bb","cc","dd"])

        # set horizontal header properties
        hh = tableWidget.horizontalHeader()
        hh.setStretchLastSection(True)

        # set column width to fit contents
        tableWidget.resizeColumnsToContents()

        # enable sorting
        #tableWidget.setSortingEnabled(True)

        return tableWidget

    def set_cancel(self):

        self.worker.abort()
        self.clearButton.setEnabled(True)
        self.runstopButton.setText("START")

    def set_clear(self):

        self.clear_vars_graphs()
        self.clearButton.setEnabled(False)
        self.clearButton.setText("Cleared")

    def runstop(self):

        sender = self.sender()
        if sender.text() == "START":
            self.set_run()
        elif sender.text() == "STOP":
            self.set_cancel()

    def set_run(self):

        if self.cb_logdata.isChecked():
            # Check if folder exists and if not create it
            head, tail = os.path.split(str(self.file_edit.text()))
            if head:
                if head[0] == '/':
                    QMessageBox.critical(
                        self, 'Message',
                        'Path name should not start with a forward slash (/)')
                    return
            else:
                QMessageBox.critical(self, 'Message',
                                     'No path to folder(s) provided!')
                return

            try:
                os.makedirs(os.path.dirname(str(self.file_edit.text())),
                            exist_ok=True)
            except Exception as e:
                QMessageBox.critical(
                    self, 'Message',
                    ''.join(["Folder named ", head, " not valid!\n",
                             str(e)]))
                return
            self.log_guv_str = str(self.file_edit.text())
            self.config.set(self.last_used_scan, 'log_guv',
                            ','.join([self.log_guv_str,
                                      str(True)]))
        else:
            self.config.set(self.last_used_scan, 'log_guv',
                            ','.join([self.log_guv_str,
                                      str(False)]))

        with open('config.ini', 'w') as configfile:
            self.config.write(configfile)

        try:
            self.GUV = GUV.GUV([
                str(self.ipportEdit.text()),
                str(self.tcpportEdit.text()), self.guvtype_str
            ], False, self.config)
        except Exception as e:
            reply = QMessageBox.critical(
                self, ''.join([self.guvtype_str, ' TEST MODE']), ''.join([
                    self.guvtype_str,
                    " could not return valid echo signal. Check the port name and check the connection.\n",
                    str(e),
                    "\n\nShould the program proceeds into the TEST MODE?"
                ]), QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.GUV = GUV.GUV([
                    str(self.ipportEdit.text()),
                    str(self.tcpportEdit.text()), self.guvtype_str
                ], True, self.config)
            else:
                return

        #self.set_clear()
        self.runstopButton.setEnabled(True)
        self.runstopButton.setText("STOP")

        self.clearButton.setEnabled(False)
        self.combo0.setEnabled(False)
        self.ipportEdit.setEnabled(False)
        self.tcpportEdit.setEnabled(False)
        self.guvtype_cb.setEnabled(False)
        self.cb_logdata.setEnabled(False)
        self.file_edit.setEnabled(False)
        self.isRunning = True

        setrun_obj = type('setscan_obj', (object, ), {'guv': self.GUV})

        self.worker = GUV_Worker(setrun_obj)
        self.worker.signals.update0.connect(self.update0)
        self.worker.signals.finished.connect(self.finished)

        # Execute
        self.threadpool.start(self.worker)

    def update0(self, times, volts):

        self.tal += 1
        times = [i + self.stoptime for i in times]

        # set row height
        self.tableWidget.setRowCount(self.tal + 1)
        self.tableWidget.setRowHeight(self.tal, 12)

        # add row elements
        self.tableWidget.setItem(self.tal, 0,
                                 QTableWidgetItem(format(times[0], '.2e')))
        self.tableWidget.setItem(
            self.tal, 1,
            QTableWidgetItem(', '.join(
                [format(float(i), '.2e') for i in volts])))

        if self.tal > self.schroll_pts:
            self.times[:-1] = self.times[
                1:]  # shift data in the array one sample left
            self.times[-1] = times
            self.plot_volts_tr[:-1] = self.plot_volts_tr[
                1:]  # shift data in the array one sample left
            self.plot_volts_tr[-1] = volts
        else:
            self.times.append(times)
            self.plot_volts_tr.append(volts)

        ## Handle view resizing
        def updateViews():
            ## view has resized; update auxiliary views to match
            self.p0_1.setGeometry(self.p1.vb.sceneBoundingRect())
            #p3.setGeometry(p1.vb.sceneBoundingRect())

            ## need to re-update linked axes since this was called
            ## incorrectly while views had different shapes.
            ## (probably this should be handled in ViewBox.resizeEvent)
            self.p0_1.linkedViewChanged(self.p1.vb, self.p0_1.XAxis)
            #p3.linkedViewChanged(p1.vb, p3.XAxis)

        updateViews()
        self.p1.vb.sigResized.connect(updateViews)

        times_ = list(map(list, zip(*self.times)))
        plot_volts_tr_ = list(map(list, zip(*self.plot_volts_tr)))

        for i in range(len(times_)):
            self.curves[i].setData(times_[i], plot_volts_tr_[i])
            #self.curve2.setData(self.times, self.plot_volts_tr)

    def finished(self):

        self.stoptime = self.times[-1][-1]
        self.isRunning = False
        self.ipportEdit.setEnabled(True)
        self.tcpportEdit.setEnabled(True)
        self.guvtype_cb.setEnabled(True)
        self.cb_logdata.setEnabled(True)
        if self.cb_logdata.isChecked():
            self.file_edit.setEnabled(True)
        else:
            self.file_edit.setEnabled(False)
        self.combo0.setEnabled(True)
        self.clearButton.setEnabled(True)
        self.clearButton.setText("Clear")

    def clear_vars_graphs(self):

        # PLOT 2 initial canvas settings
        self.stoptime = 0
        self.tal = -1
        self.times = []
        self.plot_volts_tr = []
        for i in range(20):
            self.curves[i].clear()
        self.curve2.clear()
        self.tableWidget.clearContents()

    def closeEvent(self, event):

        reply = QMessageBox.question(self, 'Message',
                                     "Quit now? Changes will not be saved!",
                                     QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:

            if hasattr(self, 'GUV'):
                if self.isRunning:
                    QMessageBox.warning(
                        self, 'Message',
                        "Run in progress. Cancel the scan then quit!")
                    event.ignore()
                    return

            event.accept()
        else:
            event.ignore()
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.backlog = Backlog()

        self.backlog.load(
            "C:\\Users\\Patrick\\Documents\\Python\\Giro\\turboClock\\Data\\tasksData.dat"
        )

        self.currTask = Task()

        self.currPiece = Piece()

        self.currDuty = Duty()

        self.currTaskItemRow = 0

        self.isTimerRunning = False

        self.editTasksGUI = EditBacklogGUI(self, self.backlog)

        self.initUI()

    def initUI(self):

        self.setWindowTitle("TurboClock")

        self.resize(400, 300)
        self.setWindowIcon(QIcon('Images//clock.png'))

        self.icon = QSystemTrayIcon(self)
        self.icon.setIcon(QIcon('Images//clock.png'))
        self.icon.setVisible(True)

        self.lcdNumber = QLCDNumber()
        self.lcdNumber.setNumDigits(8)

        self.btnStartPause = QPushButton('', self)
        self.btnStartPause.setIcon(QIcon('Images//play_icon.png'))
        self.btnStartPause.clicked.connect(self.manageStartPauseClickButton)

        self.btnDutyDetails = QPushButton('Duty details...')
        self.btnDutyDetails.clicked.connect(self.manageDutyDetailsClickedEvent)

        self.btnAddTfsTask = QPushButton('', self)
        self.btnAddTfsTask.setIcon(QIcon('Images//plus_icon.png'))
        self.btnAddTfsTask.clicked.connect(self.manageEditTasksOptions)

        self.progressBar = QProgressBar()
        self.progressBar.setValue(0)

        self.dutyTimeCompLbl = QLabel()

        self.taskCb = QComboBox(self)
        self.initTaskCombobox()

        mainLayout = QVBoxLayout(self)

        layoutTimer = QVBoxLayout()
        layoutTimer.addWidget(self.lcdNumber)

        fieldsInputLayout = QHBoxLayout()

        layoutInputCodes = QVBoxLayout()
        layoutInputCodes.addWidget(self.taskCb)

        layoutAddBtn = QVBoxLayout()
        layoutAddBtn.addWidget(self.btnAddTfsTask)

        fieldsInputLayout.addLayout(layoutInputCodes)
        fieldsInputLayout.addLayout(layoutAddBtn)

        layoutDutyStat = QHBoxLayout()
        layoutDutyStat.addWidget(self.dutyTimeCompLbl)

        layoutProgressBar = QHBoxLayout()
        layoutProgressBar.addWidget(self.progressBar)

        mainLayout.addLayout(layoutTimer)
        mainLayout.addLayout(fieldsInputLayout)
        mainLayout.addWidget(self.btnStartPause)
        mainLayout.addWidget(self.btnDutyDetails)
        mainLayout.addWidget(self.progressBar)
        mainLayout.addLayout(layoutDutyStat)

        self.timer = QTimer(self)
        self.deltaTimer = 0
        self.currTimeLCD = QTime(0, 0, 0)
        self.currTimeDuty = QTime(0, 0, 0)

        self.timer.timeout.connect(self.incrementTimer)

        self.updateTimeLCD()
        self.updateDutyTimeDisp()
        self.updateProgressBarDisplay()

    def initTaskCombobox(self):

        self.updateTaskCombobox()

        self.taskCb.currentIndexChanged.connect(self.manageCbIndexChange)

    def updateProgressBarDisplay(self):

        estimatedTime = self.currTask.estimatedTime

        if estimatedTime == 0:
            return

        ratioFromTimer = (self.deltaTimer / estimatedTime)

        totalCompletionPerc = int(
            (self.currTask.completionRatio + ratioFromTimer) * 100)

        if totalCompletionPerc <= 100:
            self.progressBar.setValue(totalCompletionPerc)
        else:
            self.progressBar.setValue(100)

    def updateTaskCombobox(self):

        currTaskIndex = 0

        self.taskCb.clear()

        tasks = self.backlog.tasks

        for currTask in tasks:

            taskDesc = currTask.title + ' - ' + currTask.prjCode
            self.taskCb.addItem(taskDesc)

        self.taskCb.setCurrentIndex(currTaskIndex)

        self.manageSelectedTaskChange(self.taskCb.currentText())

    def manageCbIndexChange(self):

        self.currTaskItemRow = self.taskCb.currentIndex()

        if self.currTaskItemRow >= 0 and self.currTaskItemRow <= self.taskCb.count(
        ):

            currTextCb = self.taskCb.currentText()
            self.manageSelectedTaskChange(currTextCb)

        self.updateTimeLCD()

        self.deltaTimer = 0
        self.updateProgressBarDisplay()

    def updateTimeLCD(self):

        currTaskTimeStr = str(
            datetime.timedelta(seconds=self.currTask.completedTime))
        currTaskTime_split = str(currTaskTimeStr).split(':')

        h = int(currTaskTime_split[0])
        m = int(currTaskTime_split[1])
        s = int(currTaskTime_split[2])

        self.currTimeLCD = QTime(h, m, s)
        self.lcdNumber.display(self.currTimeLCD.toString('hh:mm:ss'))

    def updateDutyTimeDisp(self):

        currDutyTimeStr = str(
            datetime.timedelta(seconds=self.currDuty.totalTimeCompleted))
        currDutyTime_split = currDutyTimeStr.split(':')

        h = int(currDutyTime_split[0])
        m = int(currDutyTime_split[1])
        s = int(currDutyTime_split[2])

        self.currTimeDuty = QTime(h, m, s)
        self.dutyTimeCompLbl.setText('Daily time completed: ' +
                                     self.currTimeDuty.toString('hh:mm:ss'))

    def incrementTimer(self):

        self.currTimeLCD = self.currTimeLCD.addSecs(1)
        self.lcdNumber.display(self.currTimeLCD.toString('hh:mm:ss'))

        self.currTimeDuty = self.currTimeDuty.addSecs(1)
        self.dutyTimeCompLbl.setText('Daily time completed: ' +
                                     self.currTimeDuty.toString('hh:mm:ss'))

        self.deltaTimer += 1

        self.updateProgressBarDisplay()

    def manageSelectedTaskChange(self, iCbbText):

        splitCurrTextCb = iCbbText.split(' - ')

        title = splitCurrTextCb[0]
        prjCode = splitCurrTextCb[1]

        indexBacklogCurrTask = self.backlog.getIndexFromTask(
            Task(prjCode, title))

        if indexBacklogCurrTask != None:

            if self.isTimerRunning:

                self.endPiece()
                self.startPiece()

            self.currTask = self.backlog.tasks[indexBacklogCurrTask]

        else:
            return

    def startPiece(self):

        self.currPiece = Piece(self.currTask, datetime.datetime.now())
        self.isTimerRunning = True

    def endPiece(self):

        self.currPiece.setEndDateTime(datetime.datetime.now())

        self.currDuty.addPiece(self.currPiece)

        self.currTask.addCompletedTime(self.currPiece.task.completedTime)

        self.isTimerRunning = False

    def manageStartPauseClickButton(self):

        if self.currTask:

            self.deltaTimer = 0

            if self.isTimerRunning:
                self.timer.stop()
                self.endPiece()
                self.btnStartPause.setIcon(QIcon('Images//play_icon.png'))
            else:
                self.timer.start(1000)
                self.startPiece()
                self.btnStartPause.setIcon(QIcon('Images//pause_icon.png'))

    def manageDutyDetailsClickedEvent(self):
        pass

    def manageEditTasksOptions(self):

        self.editTasksGUI.exec_()