예제 #1
0
class main_program(QObject):
    def __init__(self):
        super(main_program, self).__init__()
        self.video_source = None
        self.ui = Ui_MainWindow()
        self.threadpool = QThreadPool()
        self.threadpool.setMaxThreadCount(8)
        self.database = Database()
        self.combo_list = [
            "Görüntü kaynağını seçiniz...", "Webcam", "IP Kamera",
            "IP Kamera 2"
        ]
        self.is_signedin = False

    def button_connections(self):
        # Activate in main.
        self.ui.start_stop_button.clicked.connect(self.Start)
        # self.ui.stop_button.clicked.connect(self.Stop)

        self.ui.to_taskbar_button.clicked.connect(MainWindow.showMinimized)
        self.ui.quit_button.clicked.connect(sys.exit)

        self.ui.btn_page_1.clicked.connect(
            lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.page_1))

        self.ui.btn_page_2.clicked.connect(
            lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.page_2))

        self.ui.media_source_combobox.addItems(self.combo_list)
        self.ui.media_source_combobox.activated.connect(self.ComboSelected)
        self.ui.sign_out_button.clicked.connect(self.sign_out_clicked)
        self.ui.sign_in_button.clicked.connect(self.login_func)
        self.ui.reload_table_button.clicked.connect(self.load_report_table)

    @pyqtSlot(QImage)
    def setImage(self, image):
        self.ui.image_frame.setPixmap(QPixmap.fromImage(image))
        if self.detection.stopped:
            self.ui.image_frame.setPixmap(
                QtGui.QPixmap(":/placeholders/Resources/placeholder2.png"))

    @pyqtSlot(str)
    def setInfo(self, statement):
        self.ui.out_info_box.setText(statement)

    @pyqtSlot(str)
    def setTitleBox(self, statement):
        self.ui.info_title_box.setText(statement)

    def Start(self):
        if self.is_signedin:
            self.ui.out_info_box.setText("")
            if self.check_video_source():
                self.ui.image_frame.setPixmap(
                    QtGui.QPixmap("Resources/please_wait.png"))
                self.detection = Detection()
                self.detection.video_source = self.video_source

                # Connect signals and slots
                self.detection.signals.changeButton.connect(
                    self.change_start_context)
                self.detection.signals.changePixmap.connect(self.setImage)
                self.detection.signals.changeTextBox.connect(self.setInfo)
                self.detection.signals.changeTitleBox.connect(self.setTitleBox)

                self.threadpool.start(self.detection)
                self.change_start_context("stop_button")
            else:
                self.ui.out_info_box.setText("Video kaynağınızı kontrol edin.")
        else:
            self.ui.out_info_box.setText("Lütfen önce giriş yapınız.")

    @pyqtSlot(str)
    def change_start_context(self, mode):
        if mode == "start_button":
            self.ui.start_stop_button.clicked.disconnect()
            self.ui.start_stop_button.clicked.connect(self.Start)
            self.ui.start_stop_button.setStyleSheet(
                "QPushButton {\n"
                "color: rgb(255, 255, 255);\n"
                "border: 0px solid;\n"
                "background-color:  #667BC4;\n"
                "padding:0.5em;\n"
                "font-weight:bold;\n"
                "font-size:12px;\n"
                "}\n"
                "QPushButton:hover {\n"
                "    background-color: #7289DA;\n"
                "}")
            self.ui.start_stop_button.setText("Başlat")

        elif mode == "stop_button":
            self.ui.start_stop_button.clicked.disconnect()
            self.ui.start_stop_button.clicked.connect(self.Stop)
            self.ui.start_stop_button.setStyleSheet(
                "QPushButton {\n"
                "color: rgb(255, 255, 255);\n"
                "border: 0px solid;\n"
                "background-color:  #ff2115;\n"
                "padding:0.5em;\n"
                "font-weight:bold;\n"
                "font-size:12px;\n"
                "}\n"
                "QPushButton:hover {\n"
                "background-color: #ff392e;\n"
                "}")
            self.ui.start_stop_button.setText("Durdur")

    def check_video_source(self):
        if self.video_source is None:
            return False
        else:
            _, frame = cv2.VideoCapture(self.video_source).read()
            if frame is not None:
                return True
            else:
                return False

    # TODO: When loop ends, button context should change.
    def Stop(self):
        try:
            self.detection.stopped = True
            self.threadpool.clear()
            self.threadpool.releaseThread()
            # print("Active thread count last (stop): {}".format(self.threadpool.activeThreadCount()))
            # self.change_start_context("start_button")

        except AttributeError:
            print("Detection is not initialize yet.")

    def ComboSelected(self):
        media_source_str = self.ui.media_source_combobox.currentText()
        current_index = self.ui.media_source_combobox.currentIndex()
        if current_index == 0:
            self.video_source = None
        if current_index == 1:
            self.video_source = 0
        if current_index == 2:
            self.video_source = 'videos/toprakli_fit_buyuk.mp4'
        if current_index == 3:
            self.video_source = "videos/inek_field.mp4"

    ####################################################
    #                    SIGN IN - SIGN OUT            #
    ####################################################

    def starting_page(self):
        """
        This function answer this question: 'Did user sign in before or not?'
        """
        is_matching, file_path = self.database.get_data_n_check()
        if is_matching:
            self.change_profile_button_context(1)
        else:
            try:
                os.remove(file_path)
                self.ui.info_box.setText(
                    "Güvenlikle ilgili bir sorun meydana geldi.\nYeniden giriş yapın."
                )
            except FileNotFoundError:
                print("Usr.md file doesn't exist.")
            self.change_profile_button_context(0)

    def change_profile_button_context(self, status):
        # 0 is for NOT signed in, 1 is for signed in.
        icon = QtGui.QIcon()
        if status == 0:
            self.ui.btn_page_4.disconnect()
            self.ui.btn_page_4.clicked.connect(
                lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.
                                                               sign_in_page))
            icon.addPixmap(
                QtGui.QPixmap(
                    ":/icons/Resources/icons/32px/user_alternative.png"),
                QtGui.QIcon.Normal, QtGui.QIcon.Off)
            self.ui.btn_page_4.setIcon(icon)
            self.is_signedin = False

        elif status == 1:
            self.ui.btn_page_4.disconnect()
            self.ui.btn_page_4.clicked.connect(
                lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.
                                                               profile_page))
            icon.addPixmap(
                QtGui.QPixmap(":/icons/Resources/icons/32px/user_active.png"),
                QtGui.QIcon.Normal, QtGui.QIcon.Off)
            self.ui.btn_page_4.setIcon(icon)
            self.is_signedin = True
            # cu stands for current user.
            cu_email, cu_name, cu_surname = self.database.get_current_user_info(
            )
            self.ui.current_name_surname.setText("{} {}".format(
                cu_name, cu_surname))
            self.ui.current_email.setText("{}".format(cu_email))

    def login_func(self):
        self.ui.profile_info_box.setAlignment(QtCore.Qt.AlignCenter)
        if self.ui.email.text() == "" or self.ui.password.text() == "":
            self.ui.info_box.setStyleSheet("color:#ff5048;font-weight: 700;")
            self.ui.info_box.setText("Boş alanları doldurunuz.")
        else:
            encrypted_pass = self.database.encrpt_password(
                self.ui.password.text())
            email = self.ui.email.text()

            try:
                self.database.cursor.execute(
                    "select name, email, password, userID from User WHERE User.email = %s and User.password=%s",
                    (email, encrypted_pass))
                x = self.database.cursor.next()
                CURRENT_USER_NAME = x[0]
                CURRENT_USER_EMAIL = x[1]
                CURRENT_USER_ID = x[3]

                # Save user information to local.
                self.save_current_user_local(CURRENT_USER_EMAIL,
                                             CURRENT_USER_ID)
                # Change the context and icon of profile button
                self.change_profile_button_context(1)
                # Redirecting to page 2.
                self.ui.stackedWidget.setCurrentWidget(self.ui.profile_page)
                # Complete message.
                self.ui.profile_info_box.setText(f"Giriş başarılı.")

            except StopIteration:
                self.ui.info_box.setStyleSheet(
                    "color:#ff5048; font-weight: 700;")
                self.ui.info_box.setText("E-postanız veya parolanız yanlış.")

    def save_current_user_local(self, email, uid):
        file_exist_message = "Old user. [File exist]"
        # Get OS of user.
        platform_name = platform.system()

        if platform_name == "Windows":
            save_dir = os.getenv('APPDATA')
            save_dir += '\\Provactus\\'
            file_path = save_dir + '\\usr.md'

        elif platform_name == "Linux":
            save_dir = '/var/Provactus'
            file_path = '/var/Provactus/usr.md'

        # Trying to create file.
        try:
            os.mkdir(save_dir)
        except FileExistsError:
            print(file_exist_message)
        # Local registry for following usages.
        with open(file_path, 'w+') as file:
            file.write(f"{uid}\n{email}\n")

    def sign_out_clicked(self):
        # Get OS of user.
        platform_name = platform.system()
        if platform_name == "Windows":
            save_dir = os.getenv('APPDATA')
            save_dir += '\\Provactus\\'
            file_path = save_dir + '\\Provactus\\usr.md'

        elif platform_name == "Linux":
            file_path = "/var/Provactus/usr.md"

        os.remove(file_path)
        self.change_profile_button_context(0)
        # Redirecting to page 2.
        self.ui.stackedWidget.setCurrentWidget(self.ui.sign_in_page)
        self.ui.info_box.setText("")

    ####################################################
    #                   Report                         #
    ####################################################
    def load_report_table(self):

        if self.is_signedin:
            t = datetime.now()
            current_time = t.strftime("%d/%m/%y %H:%M:%S.%f")[:-4]
            self.report_page_controls(True)
            self.ui.report_info_box.setText(
                "Son güncellenme tarihi: {}".format(current_time))
            # To update the information, we have to re-initialize the db.
            self.database = Database()
            (report_id, date, elapsed, total_left, total_right, user_id,
             enter_position) = self.database.get_reports(
                 self.database.get_id_local())
            var_collection = [date, elapsed, total_left, total_right]
            var_collection_rev = [date, elapsed, total_right, total_right]

            # reverse vars
            for var in var_collection:
                var.reverse()
            # listing
            if len(report_id) != 0:
                self.ui.report_table.setRowCount(len(report_id))

                for col_n in range(4):
                    for row_n in range(len(report_id)):
                        if enter_position[row_n] == "right":
                            self.ui.report_table.setItem(
                                row_n, col_n,
                                QtWidgets.QTableWidgetItem(
                                    str(var_collection[col_n][row_n])))
                        elif enter_position[row_n] == "left":
                            self.ui.report_table.setItem(
                                row_n, col_n,
                                QtWidgets.QTableWidgetItem(
                                    str(var_collection_rev[col_n][row_n])))

            else:
                self.report_page_controls(False)
                self.ui.report_info_box.setText("Henüz rapor oluşturmadınız.")
        else:
            self.report_page_controls(False)
            self.ui.report_info_box.setText("Önce giriş yapınız.")

    def report_page_controls(self, is_okay):
        self.ui.report_info_box.setAlignment(QtCore.Qt.AlignCenter)
        if is_okay is True:

            self.ui.report_info_box.setStyleSheet("color: #FFFFFF;\n"
                                                  "font-weight: 700;\n"
                                                  "font-size: 14px;\n"
                                                  "margin:2em;\n"
                                                  "")
            self.ui.report_table.show()
            self.ui.report_info_box.setText("")
        else:
            self.ui.report_info_box.setStyleSheet("color: #ff5048;\n"
                                                  "font-weight: 700;\n"
                                                  "font-size: 14px;\n"
                                                  "margin:2em;\n"
                                                  "")
            self.ui.report_table.close()
            self.ui.report_info_box.show()
예제 #2
0
class WindowingWidget(QWidget):
    SendPath = QtCore.pyqtSignal(str)

    def __init__(self, path):

        super().__init__()
        self.resize(QtCore.QSize(1000, 700))
        self.path = path[1:]
        # Set configurations of the widget
        self.bandsNumber = 10
        self.slidersList = []
        self.gainLabels = []
        self.windowComboBoxes = []
        self.selectedWindows = [["Rectangular"] * self.bandsNumber,
                                ["Rectangular"] * self.bandsNumber]
        self.threadPool = QThreadPool()
        app.aboutToQuit.connect(self.closeEvent)

        self.selectedChannel = 0
        self.changeButton = QPushButton("Change to Channel 2")
        self.changeButton.clicked.connect(self.channelChanged)

        # Setting original data graph
        self.originalLayout = QHBoxLayout()
        self.originalTime = GraphWidget()
        self.originalFreq = GraphWidget()
        self.originalLayout.addWidget(self.originalTime)
        self.originalLayout.addWidget(self.originalFreq)
        self.orignalBox = QGroupBox()
        self.orignalBox.setLayout(self.originalLayout)
        # Setting the sliders
        self.slidersLayout = self.SlidersLayout(self.bandsNumber)
        self.slidersGroupBox = QGroupBox()
        self.slidersGroupBox.setLayout(self.slidersLayout)

        # Reading the data from .wav file and plotting the data
        self.channels = [WavClass(self.path), WavClass(self.path)]
        self.originalTime.setPlot(
            self.channels[self.selectedChannel].wavClass.time,
            self.channels[self.selectedChannel].wavClass.data.astype(int))
        self.originalFreq.setPlot(
            self.channels[self.selectedChannel].wavClass.freq,
            self.channels[self.selectedChannel].wavClass.fftPlotting)

        # Edited data plotting
        self.editedLayout = QHBoxLayout()
        self.editedBox = QGroupBox()
        self.editedFreq = GraphWidget()
        self.editedTime = GraphWidget()
        self.editedTime.YRange(
            np.min(
                self.channels[self.selectedChannel].wavClass.data.astype(int)),
            np.max(
                self.channels[self.selectedChannel].wavClass.data.astype(int)))
        self.editedFreq.YRange(
            0, 6 *
            np.max(self.channels[self.selectedChannel].wavClass.fftPlotting))
        self.editedFreq.setPlot(
            self.channels[self.selectedChannel].wavClass.freq,
            self.channels[self.selectedChannel].wavClass.fftPlotting,
            pen='r')
        self.editedTime.setPlot(
            self.channels[self.selectedChannel].wavClass.time,
            self.channels[self.selectedChannel].wavClass.data.astype(int),
            pen='r')
        self.editedData = [
            copy(self.channels[0].amplitudeBands),
            copy(self.channels[1].amplitudeBands)
        ]
        self.editedpFFTData = [
            copy(self.channels[0].pfftBands),
            copy(self.channels[1].pfftBands)
        ]
        self.editednFFTData = [
            copy(self.channels[0].nfftBands),
            copy(self.channels[1].nfftBands)
        ]
        self.editedLayout.addWidget(self.editedTime)
        self.editedLayout.addWidget(self.editedFreq)
        self.editedBox.setLayout(self.editedLayout)

        self.submit = QPushButton("Submit")
        # list(itertools.chain.from_iterable(list2d))
        self.submit.clicked.connect(lambda: self.createNewSong(
            np.append(
                np.array(
                    list(
                        itertools.chain.from_iterable(self.editedpFFTData[
                            self.selectedChannel]))),
                np.flip(
                    np.array(
                        list(
                            itertools.chain.from_iterable(self.editednFFTData[
                                self.selectedChannel]))))), "e321s.wav"))

        self.play = QPushButton("Play")
        self.play.clicked.connect(lambda: self.playSong(
            np.append(
                np.array(
                    list(
                        itertools.chain.from_iterable(self.editedpFFTData[
                            self.selectedChannel]))),
                np.flip(
                    np.array(
                        list(
                            itertools.chain.from_iterable(self.editednFFTData[
                                self.selectedChannel])))))))

        self.stop = QPushButton("Stop")
        self.stop.clicked.connect(lambda: sd.stop())

        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.changeButton)
        self.mainLayout.addWidget(self.orignalBox)
        self.mainLayout.addWidget(self.slidersGroupBox)
        self.mainLayout.addWidget(self.submit)

        self.playPauseLayout = QHBoxLayout()
        self.playPauseLayout.addWidget(self.play)
        self.playPauseLayout.addWidget(self.stop)
        self.playPauseBox = QGroupBox()
        self.playPauseBox.setLayout(self.playPauseLayout)

        self.mainLayout.addWidget(self.playPauseBox)
        self.mainLayout.addWidget(self.editedBox)

        self.multiTime = MultiGraph()
        self.multiFreq = MultiGraph()

        self.multiTime.AddPlot(
            self.channels[self.selectedChannel].wavClass.time,
            self.channels[self.selectedChannel].wavClass.data.astype(int),
            pen='w')
        self.multiFreq.AddPlot(
            self.channels[self.selectedChannel].wavClass.freq,
            self.channels[self.selectedChannel].wavClass.fftPlotting,
            pen='w')
        self.multiTime.AddPlot(
            self.channels[self.selectedChannel].wavClass.time,
            self.channels[self.selectedChannel].wavClass.data.astype(int),
            pen='r')
        self.multiFreq.AddPlot(
            self.channels[self.selectedChannel].wavClass.freq,
            self.channels[self.selectedChannel].wavClass.fftPlotting,
            pen='r')
        self.multiTime.AddPlot(
            self.channels[self.selectedChannel].wavClass.time,
            self.channels[self.selectedChannel].wavClass.data.astype(int),
            pen='b')
        self.multiFreq.AddPlot(
            self.channels[self.selectedChannel].wavClass.freq,
            self.channels[self.selectedChannel].wavClass.fftPlotting,
            pen='b')

        self.mainLayout.addWidget(self.multiTime)
        self.mainLayout.addWidget(self.multiFreq)
        self.setLayout(self.mainLayout)
        self.show()

    def SlidersLayout(self, number=10):
        layout = QHBoxLayout()
        for index in range(number):
            sliderBox = QVBoxLayout()
            sliderGroup = QGroupBox()
            slider = QSlider()
            slider.setOrientation(Qt.Vertical)
            slider.setTickPosition(QSlider.TicksBelow)
            slider.setTickInterval(1)
            slider.setValue(0)
            slider.setMinimum(-8)
            slider.setMaximum(8)
            label = QLabel()
            label.setText("0  dB")
            self.gainLabels.append(label)
            windowCombo = QComboBox()
            windowCombo.addItem("Rectangular")
            windowCombo.addItem("Hamming")
            windowCombo.addItem("Hanning")
            self.setComboFunction(windowCombo, index)
            self.windowComboBoxes.append(windowCombo)
            self.setSliderFunction(slider, index, label)
            self.slidersList.append(slider)
            sliderBox.addWidget(slider)
            sliderBox.addWidget(label)
            sliderBox.addWidget(windowCombo)
            sliderBox.setAlignment(Qt.AlignCenter)
            sliderGroup.setLayout(sliderBox)
            sliderGroup.setMinimumHeight(300)
            layout.addWidget(sliderGroup)

        return layout

    def setSliderFunction(self, slider, index, label):
        slider.sliderReleased.connect(lambda: self.sliderMoved(index, label))

    def setComboFunction(self, windowCombo, index):
        windowCombo.activated[str].connect(lambda: self.windowSelected(index))

    def channelChanged(self):
        if self.selectedChannel == 0:
            self.selectedChannel = 1
            self.changeButton.setText("Change to Channel 1")
            pen = 'b'
        elif self.selectedChannel == 1:
            self.selectedChannel = 0
            self.changeButton.setText("Change to Channel 2")
            pen = 'r'
        for i in range(10):
            self.slidersList[i].setValue(
                self.channels[self.selectedChannel].gains[i])
            self.gainLabels[i].setText(
                str(self.channels[self.selectedChannel].gains[i]) + " dB")
            index = 0
            if self.selectedWindows[self.selectedChannel][i] == "Rectangular":
                index = 0
            elif self.selectedWindows[self.selectedChannel][i] == "Hamming":
                index = 1
            elif self.selectedWindows[self.selectedChannel][i] == "Hanning":
                index = 2
            self.windowComboBoxes[i].setCurrentIndex(index)

        self.editedTime.UpdatePlot([], [])
        self.editedFreq.UpdatePlot([], [])
        self.editedTime.YRange(
            np.min(
                self.channels[self.selectedChannel].wavClass.data.astype(int)),
            np.max(
                self.channels[self.selectedChannel].wavClass.data.astype(int)))
        compressedData = list(
            itertools.chain.from_iterable(
                self.editedData[self.selectedChannel]))
        self.editedFreq.setPlot(
            self.channels[self.selectedChannel].wavClass.freq,
            compressedData,
            pen=pen)

        compressedTime = np.append(
            np.array(
                list(
                    itertools.chain.from_iterable(
                        self.editedpFFTData[self.selectedChannel]))),
            np.flip(
                np.array(
                    list(
                        itertools.chain.from_iterable(
                            self.editednFFTData[self.selectedChannel])))))

        self.editedTime.setPlot(
            self.channels[self.selectedChannel].wavClass.time,
            data2wav(compressedTime),
            pen=pen)
        # self.editedFreq.setPlot(self.channels[self.selectedChannel].wavClass.freq, compressedData)

    def windowSelected(self, index):
        self.selectedWindows[self.selectedChannel][
            index] = self.windowComboBoxes[index].currentText()
        # print(self.selectedWindows[index], index)
        self.sliderMoved(index, self.gainLabels[index])

    def sliderMoved(self, index, label):
        gainDB = self.slidersList[index].value()
        self.channels[self.selectedChannel].gains[index] = gainDB
        label.setText(str(gainDB) + "dB")
        gain = self.getGain(gainDB)
        self.applyWindow(gain, index)

    def getGain(self, db):
        return 10**(db / 20)

    def applyWindow(self, gain, index):
        factorFFT = 1
        factorAmp = 1
        pfactorData = 1
        nfactorData = 1
        windowType = self.selectedWindows[self.selectedChannel][index]

        if windowType == "Rectangular":
            factorAmp = [gain] * len(
                self.channels[self.selectedChannel].amplitudeBands[index])

        elif windowType == "Hanning":
            factorAmp = np.hanning(
                len(self.channels[
                    self.selectedChannel].amplitudeBands[index])) * gain

        elif windowType == "Hamming":
            factorAmp = np.hamming(
                len(self.channels[
                    self.selectedChannel].amplitudeBands[index])) * gain

        factorFWHM = FWHM(
            factorAmp,
            len(self.channels[self.selectedChannel].amplitudeBands[index]))

        self.editedData[self.selectedChannel][index] = self.channels[
            self.selectedChannel].amplitudeBands[index] * factorFWHM.middle
        self.editedpFFTData[self.selectedChannel][index] = self.channels[
            self.selectedChannel].pfftBands[index] * factorFWHM.middle

        if index == self.bandsNumber - 1:
            if len(np.append(factorFWHM.middle, [0.5])) == len(
                    self.channels[self.selectedChannel].nfftBands[index]):
                self.editednFFTData[
                    self.selectedChannel][index] = self.channels[
                        self.selectedChannel].nfftBands[index] * np.append(
                            factorFWHM.middle, [0.5])

        else:
            self.editednFFTData[self.selectedChannel][index] = self.channels[
                self.selectedChannel].nfftBands[index] * factorFWHM.middle

        if index != 0:
            self.editedData[self.selectedChannel][
                index - 1][-factorFWHM.beforeLength:] = self.editedData[
                    self.selectedChannel][
                        index -
                        1][-factorFWHM.beforeLength:] * factorFWHM.before
            self.editedpFFTData[self.selectedChannel][
                index - 1][-factorFWHM.beforeLength:] = self.editedpFFTData[
                    self.selectedChannel][
                        index -
                        1][-factorFWHM.beforeLength:] * factorFWHM.before
            self.editednFFTData[self.selectedChannel][
                index - 1][-factorFWHM.beforeLength:] = self.editednFFTData[
                    self.selectedChannel][
                        index -
                        1][-factorFWHM.beforeLength:] * factorFWHM.before

        if index != self.bandsNumber - 1:
            self.editedData[self.selectedChannel][
                index +
                1][:factorFWHM.
                   afterLength] = self.editedData[self.selectedChannel][
                       index + 1][:factorFWHM.afterLength] * factorFWHM.after
            self.editedpFFTData[self.selectedChannel][
                index +
                1][:factorFWHM.
                   afterLength] = self.editedpFFTData[self.selectedChannel][
                       index + 1][:factorFWHM.afterLength] * factorFWHM.after
            self.editednFFTData[self.selectedChannel][
                index +
                1][:factorFWHM.
                   afterLength] = self.editednFFTData[self.selectedChannel][
                       index + 1][:factorFWHM.afterLength] * factorFWHM.after

        compressedTime = np.append(
            np.array(
                list(
                    itertools.chain.from_iterable(
                        self.editedpFFTData[self.selectedChannel]))),
            np.flip(
                np.array(
                    list(
                        itertools.chain.from_iterable(
                            self.editednFFTData[self.selectedChannel])))))

        timePlotter = TimePlotter(lambda: self.plotTime(compressedTime))
        self.threadPool.start(timePlotter)
        freqPlotter = FreqPlotter(self.plotFreq)
        self.threadPool.start(freqPlotter)

    def createNewSong(self, data, name):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog  # Qt's builtin File Dialogue
        fileName, _ = QFileDialog.getSaveFileName(self,
                                                  "Save",
                                                  "",
                                                  "All Files (*.*)",
                                                  options=options)
        if fileName:
            dataAudio = data2wav(data)
            wavio.write(fileName,
                        dataAudio.astype(np.int32),
                        self.channels[self.selectedChannel].wavClass.rate,
                        sampwidth=4)
            self.AddToPlaylist(fileName)

    def stopArray(self):
        try:
            self.play_obj.stop()
        except:
            pass

    def plotTime(self, data):
        timeData = data2wav(data)
        self.editedTime.UpdatePlot(
            self.channels[self.selectedChannel].wavClass.time, timeData)
        self.multiTime.UpdatePlot(
            self.channels[self.selectedChannel].wavClass.time,
            timeData.astype(int), self.selectedChannel + 1)

    def plotFreq(self):
        compressedData = list(
            itertools.chain.from_iterable(
                self.editedData[self.selectedChannel]))
        self.editedFreq.UpdatePlot(
            self.channels[self.selectedChannel].wavClass.freq, compressedData)
        self.multiFreq.UpdatePlot(
            self.channels[self.selectedChannel].wavClass.freq, compressedData,
            self.selectedChannel + 1)

    @QtCore.pyqtSlot()
    def AddToPlaylist(self, path):
        self.SendPath.emit(path)

    def playSong(self, array):
        dataAudio = data2wav(array)
        sd.play(dataAudio.astype(np.int16),
                self.channels[self.selectedChannel].wavClass.rate)

    def closeEvent(self, event=None):
        sd.stop()
        self.threadPool.releaseThread()
        if event:
            event.accept()
예제 #3
0
class DemoApp(QWidget):
    # -------------------------------------------------------------------------
    # シグナルの初期化
    # -------------------------------------------------------------------------
    sig_progressBar_value = pyqtSignal(int)
    sig_error_message = pyqtSignal(object)

    def __init__(self, parent=None):

        # ---------------------------------------------------------------------
        # ウィジェットの初期化
        # ---------------------------------------------------------------------
        super(DemoApp, self).__init__(parent)
        self.ui = Ui_DemoApp()
        self.ui.setupUi(self)
        # ---------------------------------------------------------------------
        # シグナルとスロットの接続
        #   参考にしたサイト
        #     http://t2y.hatenablog.jp/entry/20100914/1284402024
        # ---------------------------------------------------------------------
        self.threadPool = QThreadPool()
        self.sig_progressBar_value.connect(self.refresh_progressBar)
        self.sig_error_message.connect(self.display_sig_error_message)
        # ---------------------------------------------------------------------
        # フラグの初期化
        # ---------------------------------------------------------------------
        self.mainFlag = False
        self.errorFlag = False

    @pyqtSlot(int)
    def refresh_progressBar(self, int):

        # ---------------------------------------------------------------------
        # プログレスバーの値を更新する
        # ---------------------------------------------------------------------
        self.ui.progressBar.setValue(int)

    def watch_progressBar_status(self):

        # ---------------------------------------------------------------------
        # カウントしたファイル数に達するまで、ループし続ける
        # ---------------------------------------------------------------------
        while (globalParams.fileCounter < globalParams.fileNum
               and self.errorFlag != True):
            # シグナルを受け取ったら、プログレスバーの値を更新する
            time.sleep(0.2)
            self.sig_progressBar_value.emit(globalParams.fileCounter)

    def location_on_the_screen(self, xPos, yPos):

        # ---------------------------------------------------------------------
        # 画面の左上へウィンドウを移動する
        # ---------------------------------------------------------------------
        self.move(xPos, yPos)

    def showInputFolderDialog(self):

        # ---------------------------------------------------------------------
        # 入力フォルダ選択用ダイアログの表示
        # ---------------------------------------------------------------------
        self.inputFd = QFileDialog()
        self.inputFp = self.inputFd.getExistingDirectory()
        if self.inputFd:
            self.ui.inputFolderLineEdit.setText(self.inputFp)
        elif self.inputFd == "":
            pass

    def showOutputFolderDialog(self):

        # ---------------------------------------------------------------------
        # 出力フォルダ選択用ダイアログの表示
        # ---------------------------------------------------------------------
        self.outputFd = QFileDialog()
        self.outputFp = self.outputFd.getExistingDirectory()
        if self.outputFd:
            self.ui.outputFolderLineEdit.setText(self.outputFp)
        elif self.outputFd == "":
            pass

    def readConfigFileDialog(self):

        # ---------------------------------------------------------------------
        # Configファイル選択用ダイアログの表示
        # ---------------------------------------------------------------------
        self.readConfigFd = QFileDialog()
        self.readConfigFp = self.readConfigFd.getOpenFileName(
            self, u"ファイルを開く", "", u"Configファイル(*.ini)")
        print(self.readConfigFp)
        # ---------------------------------------------------------------------
        # ConfigファイルのパースとGUIへの反映
        # ---------------------------------------------------------------------
        if self.readConfigFp[0]:
            self.parseConfigFile()
            QMessageBox.information(self, "Message",
                                    u"設定内容をConfigファイルから読み込みました")
        elif self.readConfigFp[0] == "":
            pass

    def writeConfigFileDialog(self):

        # ---------------------------------------------------------------------
        # Configファイル選択用ダイアログの表示
        # ---------------------------------------------------------------------
        self.writeConfigFd = QFileDialog()
        self.writeConfigFp = self.writeConfigFd.getSaveFileName(
            self, u"名前を付けて保存", "", u"Configファイル(*.ini)")
        # ---------------------------------------------------------------------
        # GUIの内容をConfigファイルに書き込む
        # ---------------------------------------------------------------------
        if self.writeConfigFp[0]:
            self.setToConfigFile()
            self.ui.configFileLineEdit.setText(self.writeConfigFp[0])
            QMessageBox.information(self, "Message",
                                    u"設定内容をConfigファイルに書き込みました")
        elif self.writeConfigFp[0] == "":
            pass

    def setToConfigFile(self):

        # ---------------------------------------------------------------------
        # configparserの初期化
        # ---------------------------------------------------------------------
        config = configparser.ConfigParser()
        # ---------------------------------------------------------------------
        # GUIの設定内容をconfigへセットする
        # ---------------------------------------------------------------------
        section1 = "File"
        config.add_section(section1)
        config.set(section1, "input", self.ui.inputFolderLineEdit.text())
        config.set(section1, "output", self.ui.outputFolderLineEdit.text())
        # ---------------------------------------------------------------------
        # configの内容を.iniファイルとして出力
        # ---------------------------------------------------------------------
        with open(self.writeConfigFp[0], "w") as file:
            config.write(file)

    def parseConfigFile(self):

        # ---------------------------------------------------------------------
        # configparserの初期化
        # ---------------------------------------------------------------------
        config = configparser.ConfigParser()
        # ---------------------------------------------------------------------
        # Configファイルの内容をパースし、GUIへ内容を反映する
        # ---------------------------------------------------------------------
        config.read(self.readConfigFp[0])
        section1 = "File"
        self.ui.inputFolderLineEdit.setText(config.get(section1, "input"))
        self.ui.outputFolderLineEdit.setText(config.get(section1, "output"))
        self.ui.configFileLineEdit.setText(self.readConfigFp[0])

    def update_status_mainAnalysis(self):

        # ---------------------------------------------------------------------
        # finishedシグナルを受け取った後に、実行される内容
        # ---------------------------------------------------------------------
        if self.errorFlag != True:
            QMessageBox.information(self, "Message", u"処理が完了しました。")
        self.ui.analyzerStateLabel.setText(u"待機中")
        self.ui.progressBar.setValue(0)
        # ---------------------------------------------------------------------
        # 全スレッドを開放する
        # ---------------------------------------------------------------------
        self.threadPool.releaseThread()

    def multiThread_runMainAnalysis(self):

        # ---------------------------------------------------------------------
        # グローバル変数の初期化
        # ---------------------------------------------------------------------
        globalParams.fileNum = 0
        globalParams.fileCounter = 0
        # ---------------------------------------------------------------------
        # Thread(解析プログラム)の初期化
        # ---------------------------------------------------------------------
        worker = Worker(self.runMainModule)
        worker.signals.finished.connect(self.update_status_mainAnalysis)
        # ---------------------------------------------------------------------
        # Thread(プログレスバー更新用メソッド)の初期化
        # ---------------------------------------------------------------------
        worker2 = Worker(self.watch_progressBar_status)
        # ---------------------------------------------------------------------
        # 解析を実行するファイル数のカウント & プログレスバーの初期化
        # ---------------------------------------------------------------------
        try:
            self.countInputFiles()
            self.ui.progressBar.setRange(0, int(globalParams.fileNum))
            # ---------------------------------------------------------------------
            # Threadの実行
            # ---------------------------------------------------------------------
            self.threadPool.start(worker)
            self.threadPool.start(worker2)
        except:
            pass

    def singleThread_runMainAnalysis(self):

        # ---------------------------------------------------------------------
        # グローバル変数の初期化
        # ---------------------------------------------------------------------
        globalParams.fileNum = 0
        globalParams.fileCounter = 0
        # ---------------------------------------------------------------------
        # 解析を実行するファイル数のカウント & プログレスバーの初期化
        # ---------------------------------------------------------------------
        try:
            self.countInputFiles()
            self.ui.progressBar.setRange(0, int(globalParams.fileNum))
            # ---------------------------------------------------------------------
            # main処理の実行
            # ---------------------------------------------------------------------
            self.runMainModule()
        except:
            pass

    @pyqtSlot(object)
    def display_sig_error_message(self, object):

        # ---------------------------------------------------------------------
        # エラー種別に応じたメッセージを出力する
        # ---------------------------------------------------------------------
        if type(object) == ValueError:
            QMessageBox.warning(self, "Message",
                                u"不正な値が入力されました。\n\n正しい値を入力してください。")
        elif type(object) == FileNotFoundError:
            QMessageBox.warning(self, "Message", u"ファイルが見つかりません。")
        elif type(object) == PermissionError:
            QMessageBox.warning(self, "Message", u"開いているファイルを閉じてください。")
        else:
            print("Error Type: {0}".format(object))
            QMessageBox.critical(
                self, "Message", u"予期せぬエラーが発生しました。\n\n設定したパラメータが正しいか確認してください。")
        # ---------------------------------------------------------------------
        # 全スレッドの開放 & フラグとプログレスバーの初期化
        # ---------------------------------------------------------------------
        self.threadPool.releaseThread()
        self.errorFlag = False
        self.ui.analyzerStateLabel.setText(u"待機中")
        self.ui.progressBar.setValue(0)

    def countInputFiles(self):

        # ---------------------------------------------------------------------
        # グローバル変数の初期化
        # ---------------------------------------------------------------------
        if (self.ui.inputFolderLineEdit.text() == "入力フォルダの絶対パスを指定してください"
                or self.ui.inputFolderLineEdit.text() == ""):
            # 初期値、もしくは、何も入力されていない場合は、ValueErrorを送出する
            self.display_sig_error_message(ValueError)
        else:
            # 指定されたフォルダの中にあるファイル数を数える
            filePath = glob.glob(self.ui.inputFolderLineEdit.text() + "/*.*")
            globalParams.fileNum = len(filePath)

    def runMainModule(self):

        # ---------------------------------------------------------------------
        # アプリケーションの状態表示を更新する
        # ---------------------------------------------------------------------
        self.ui.analyzerStateLabel.setText(u"実行中")
        QApplication.processEvents()
        # ---------------------------------------------------------------------
        # Configファイルの内容を、GUI上に表示されている内容で上書きする
        # ---------------------------------------------------------------------
        self.writeConfigFp = []
        self.writeConfigFp.append(self.ui.configFileLineEdit.text())
        self.setToConfigFile()
        # ---------------------------------------------------------------------
        # Mainモジュールの実行
        # ---------------------------------------------------------------------
        try:
            # -----------------------------------------------------------------
            # 例外テスト用
            # -----------------------------------------------------------------
            if self.ui.valueErrorCheckBox.isChecked() == True:
                raise ValueError
            elif self.ui.fileNotFoundErrorCheckBox.isChecked() == True:
                raise FileNotFoundError
            elif self.ui.permissionErrorCheckBox.isChecked() == True:
                raise PermissionError
            else:
                # -------------------------------------------------------------
                # 例外テスト用のチェックボックスに、チェックが付いてない場合は、
                # 通常通りに処理を実行する
                # -------------------------------------------------------------
                sA = SluggishActionClass(globalParams.fileNum)
                mainFlag = sA.main()
                if mainFlag == True:
                    pass
        except ValueError as e:
            self.send_error_signal(e)
        except FileNotFoundError as e:
            self.send_error_signal(e)
        except PermissionError as e:
            self.send_error_signal(e)
        except:
            # Tracebackの内容をシグナルとして送る
            e = traceback.format_exc()
            self.send_error_signal(e)

    def send_error_signal(self, e):

        # ---------------------------------------------------------------------
        # エラー用フラグを上げる
        # ---------------------------------------------------------------------
        self.errorFlag = True
        # ---------------------------------------------------------------------
        # エラー内容をシグナルとして送る
        # ---------------------------------------------------------------------
        self.sig_error_message.emit(e)