Пример #1
0
    def on_click_set_part(self, ent_part: QLineEdit, combo_1: QComboBox,
                          check: QCheckBox, ent_desc: QLineEdit,
                          combo_2: QComboBox):
        # obtain part number
        num_part = ent_part.text()
        ent_part.setText(None)

        # obtain original part number if selected
        id_part_orig = 'NULL'
        if combo_1.isEnabled():
            num_part_org = combo_1.currentText()
            sql1 = self.db.sql(
                "SELECT id_part FROM part WHERE num_part = '?';",
                [num_part_org])
            print(sql1)
            out = self.db.get(sql1)
            for id in out:
                id_part_orig = id[0]
            combo_1.clear()
            combo_1.clearEditText()
            combo_1.setEnabled(False)

        # clear QCheckBox
        if check.isChecked():
            check.setEnabled(False)

        # obtain part description
        description = ent_desc.text()
        ent_desc.setText(None)

        # obtain id_supplier from selected supplier on the QComboBox
        supplier = combo_2.currentText()
        sql2 = self.db.sql(
            "SELECT id_supplier FROM supplier WHERE name_supplier_short = '?';",
            [supplier])
        print(sql2)
        out = self.db.get(sql2)
        for id in out:
            id_supplier = id[0]

        print(num_part)
        print(description)
        print(supplier)
        print(id_supplier)

        # insert new part to part table
        sql3 = self.db.sql(
            "INSERT INTO part VALUES(NULL, ?, ?, '?', '?', NULL, NULL);",
            [id_part_orig, id_supplier, num_part, description])
        print(sql3)
        self.db.put(sql3)
Пример #2
0
    def part_selection_change(self, combo: QComboBox, lab_supplier: QLabel,
                              lab_desc: QLabel):
        num_part = combo.currentText()
        if len(num_part) == 0:
            return
        print(num_part)

        sql1 = self.db.sql(
            "SELECT id_part, id_supplier FROM part WHERE num_part = '?';",
            [num_part])
        out = self.db.get(sql1)
        for id in out:
            id_part = id[0]
            id_supplier = id[1]
        print(id_part)
        print(id_supplier)

        sql3 = self.db.sql(
            "SELECT name_supplier_short FROM supplier WHERE id_supplier = ?;",
            [id_supplier])
        out = self.db.get(sql3)
        for id in out:
            name_supplier_short = id[0]
        print(name_supplier_short)

        sql4 = self.db.sql("SELECT description FROM part WHERE id_part = ?;",
                           [id_part])
        out = self.db.get(sql4)
        for id in out:
            description = id[0]
        print(description)

        lab_supplier.setText(name_supplier_short)
        lab_desc.setText(description)
Пример #3
0
class TimebaseBox(QGroupBox):
    def __init__(self, controller, parent=None):
        super().__init__("Timebase", parent=parent)
        self.controller = controller

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.timebase_options = [
            "100 us",
            "200 us",
            "500 us",
            "1 ms",
            "2 ms",
            "5 ms",
            "10 ms",
            "20 ms",
        ]
        self.combobox_timebase = QComboBox()
        self.combobox_timebase.addItems(self.timebase_options)
        self.combobox_timebase.setCurrentIndex(7)

        layout.addWidget(QLabel("time/div (1 div = 1/10 graph)"))
        layout.addWidget(self.combobox_timebase)

        self.combobox_timebase.currentTextChanged.connect(self.set_timebase)

    def set_timebase(self):
        timebase = self.combobox_timebase.currentText()
        self.controller.set_timebase(timebase)
Пример #4
0
class KeyPressWidget(StepBaseWidget):
    def __init__(self, step: Steps.KeyPress, timeline):
        super(KeyPressWidget, self).__init__(step, timeline)

        detail_layout = self.ui.detailFrame.layout()

        # Key input
        self.key_label = QLabel("Key: ", self)
        self.key_line_edit = QLineEdit(self)
        self.key_line_edit.setMaxLength(1)
        self.key_line_edit.setText(self.step.key)
        self.key_line_edit.textChanged.connect(self.update_key)

        # Mod Input
        self.mod_label = QLabel("Mod: ", self)
        self.mod_combo = QComboBox(self)
        mod_list = ["None", "Ctrl", "Shift", "Alt", "Super"]
        self.mod_combo.addItems(mod_list)

        if self.step.mod:
            current_mod_index = mod_list.index(self.step.mod.capitalize())
            self.mod_combo.setCurrentIndex(current_mod_index)

        self.mod_combo.currentIndexChanged.connect(self.update_mod)

        # Add to layout
        detail_layout.addWidget(self.key_label)
        detail_layout.addWidget(self.key_line_edit)
        detail_layout.addWidget(self.mod_label)
        detail_layout.addWidget(self.mod_combo)

    def update_key(self):
        if not self.key_line_edit.text():
            self.key_line_edit.setText(" ")
        self.step.key = self.key_line_edit.text()

    def update_mod(self):
        if self.mod_combo.currentText() == "None":
            self.step.mod = None
        else:
            self.step.mod = self.mod_combo.currentText().lower()
Пример #5
0
class InterpolateBadsDialog(QDialog):
    def __init__(self, parent):
        super().__init__(parent)
        self.setWindowTitle("Interpolate bad channels")
        vbox = QVBoxLayout(self)
        grid = QGridLayout()
        grid.addWidget(QLabel("Reset bads:"), 0, 0)
        self.reset_bads_checkbox = QCheckBox()
        self.reset_bads_checkbox.setChecked(True)
        grid.addWidget(self.reset_bads_checkbox, 0, 1)
        grid.addWidget(QLabel("Mode:"), 1, 0)
        self.mode_select = QComboBox()
        self.modes = {"Accurate": "accurate", "Fast": "fast"}
        self.mode_select.addItems(self.modes.keys())
        self.mode_select.setCurrentText("Accurate")
        grid.addWidget(self.mode_select, 1, 1)
        grid.addWidget(QLabel("Origin (x, y, z):"), 2, 0)
        hbox = QHBoxLayout()
        self.x = QDoubleSpinBox()
        self.x.setValue(0)
        self.x.setDecimals(3)
        hbox.addWidget(self.x)
        self.y = QDoubleSpinBox()
        self.y.setValue(0)
        self.y.setDecimals(3)
        hbox.addWidget(self.y)
        self.z = QDoubleSpinBox()
        self.z.setValue(0.04)
        self.z.setDecimals(3)
        hbox.addWidget(self.z)
        grid.addLayout(hbox, 2, 1)

        vbox.addLayout(grid)
        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        vbox.addWidget(buttonbox)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        vbox.setSizeConstraint(QVBoxLayout.SetFixedSize)

    @property
    def origin(self):
        x = float(self.x.value())
        y = float(self.y.value())
        z = float(self.z.value())
        return x, y, z

    @property
    def mode(self):
        return self.mode_select.currentText()

    @property
    def reset_bads(self):
        return self.reset_bads_checkbox.isChecked()
Пример #6
0
class DeviceBox(QGroupBox):
    def __init__(self, controller, parent=None):
        super().__init__("Device", parent=parent)
        self.controller = controller

        self.is_connected = False

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.button_refresh = QPushButton("Refresh")
        self.combobox_ports = QComboBox()
        self.button_connect = QPushButton("Connect")

        layout.addWidget(self.button_refresh)
        layout.addWidget(self.combobox_ports)
        layout.addWidget(self.button_connect)

        self.button_refresh.clicked.connect(self.refresh_ports)
        self.button_connect.clicked.connect(self.connect_to_device)

    def refresh_ports(self):
        self.combobox_ports.clear()
        self.combobox_ports.addItems(self.controller.get_ports_names())

    def connect_to_device(self):

        if not self.is_connected:
            port = self.combobox_ports.currentText()
            self.controller.connect_to_device(port)
        else:
            self.controller.disconnect_device()

        self.is_connected = self.controller.is_device_connected()
        if self.is_connected:
            self.button_connect.setText("Disconnect")
        else:
            self.button_connect.setText("Connect")
Пример #7
0
class RunICADialog(QDialog):
    def __init__(self, parent, nchan, methods):
        super().__init__(parent)
        self.setWindowTitle("Run ICA")

        vbox = QVBoxLayout(self)
        grid = QGridLayout()
        grid.addWidget(QLabel("Method:"), 0, 0)
        self.method = QComboBox()
        self.method.addItems(methods)
        self.method.setCurrentIndex(0)
        self.method.currentIndexChanged.connect(self.toggle_options)
        grid.addWidget(self.method, 0, 1)

        self.extended_label = QLabel("Extended:")
        grid.addWidget(self.extended_label, 1, 0)
        self.extended = QCheckBox()
        self.extended.setChecked(True)
        grid.addWidget(self.extended, 1, 1)

        self.ortho_label = QLabel("Orthogonal:")
        grid.addWidget(self.ortho_label, 2, 0)
        self.ortho = QCheckBox()
        self.ortho.setChecked(False)
        grid.addWidget(self.ortho, 2, 1)
        if "Picard" not in methods:
            self.ortho_label.hide()
            self.ortho.hide()

        grid.addWidget(QLabel("Number of components:"), 3, 0)
        self.n_components = QSpinBox()
        self.n_components.setRange(0, nchan)
        self.n_components.setValue(nchan)
        self.n_components.setAlignment(Qt.AlignRight)
        grid.addWidget(self.n_components, 3, 1)

        grid.addWidget(QLabel("Exclude bad segments:"), 4, 0)
        self.exclude_bad_segments = QCheckBox()
        self.exclude_bad_segments.setChecked(True)
        grid.addWidget(self.exclude_bad_segments, 4, 1)

        vbox.addLayout(grid)

        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        vbox.addWidget(buttonbox)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        vbox.setSizeConstraint(QVBoxLayout.SetFixedSize)

        self.toggle_options()

    @Slot()
    def toggle_options(self):
        """Toggle extended options."""
        if self.method.currentText() == "Picard":  # enable extended and ortho
            self.extended_label.setEnabled(True)
            self.extended.setEnabled(True)
            self.ortho_label.setEnabled(True)
            self.ortho.setEnabled(True)
        elif self.method.currentText() == "Infomax":  # enable extended
            self.extended_label.setEnabled(True)
            self.extended.setEnabled(True)
            self.ortho_label.setEnabled(False)
            self.ortho.setChecked(False)
            self.ortho.setEnabled(False)
        else:
            self.extended_label.setEnabled(False)
            self.extended.setChecked(False)
            self.extended.setEnabled(False)
            self.ortho_label.setEnabled(False)
            self.ortho.setChecked(False)
            self.ortho.setEnabled(False)
class VideoFinderAddLink(AddLinkWindow):
    running_thread = None
    threadPool = {}

    def __init__(self, parent, receiver_slot, settings, video_dict={}):
        super().__init__(parent, receiver_slot, settings, video_dict)
        self.setWindowTitle(
            QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video Finder'))
        self.size_label.hide()

        # empty lists for no_audio and no_video and video_audio files
        self.no_audio_list = []
        self.no_video_list = []
        self.video_audio_list = []

        self.media_title = ''

        # add support for other languages
        locale = str(self.persepolis_setting.value('settings/locale'))
        QLocale.setDefault(QLocale(locale))
        self.translator = QTranslator()
        if self.translator.load(':/translations/locales/ui_' + locale, 'ts'):
            QCoreApplication.installTranslator(self.translator)

        # extension_label
        self.extension_label = QLabel(self.link_frame)
        self.change_name_horizontalLayout.addWidget(self.extension_label)

        # Fetch Button
        self.url_submit_pushButtontton = QPushButton(self.link_frame)
        self.link_horizontalLayout.addWidget(self.url_submit_pushButtontton)

        # Status Box
        self.status_box_textEdit = QTextEdit(self.link_frame)
        self.status_box_textEdit.setMaximumHeight(150)
        self.link_verticalLayout.addWidget(self.status_box_textEdit)

        # Select format horizontal layout
        select_format_horizontalLayout = QHBoxLayout()

        # Selection Label
        self.select_format_label = QLabel(self.link_frame)
        select_format_horizontalLayout.addWidget(self.select_format_label)

        # Selection combobox
        self.media_comboBox = QComboBox(self.link_frame)
        self.media_comboBox.setMinimumWidth(200)
        select_format_horizontalLayout.addWidget(self.media_comboBox)

        # Duration label
        self.duration_label = QLabel(self.link_frame)
        select_format_horizontalLayout.addWidget(self.duration_label)

        self.format_selection_frame = QFrame(self)
        self.format_selection_frame.setLayout(select_format_horizontalLayout)
        self.link_verticalLayout.addWidget(self.format_selection_frame)

        # advanced_format_selection_checkBox
        self.advanced_format_selection_checkBox = QCheckBox(self)
        self.link_verticalLayout.addWidget(
            self.advanced_format_selection_checkBox)

        # advanced_format_selection_frame
        self.advanced_format_selection_frame = QFrame(self)
        self.link_verticalLayout.addWidget(
            self.advanced_format_selection_frame)

        advanced_format_selection_horizontalLayout = QHBoxLayout(
            self.advanced_format_selection_frame)

        # video_format_selection
        self.video_format_selection_label = QLabel(
            self.advanced_format_selection_frame)
        self.video_format_selection_comboBox = QComboBox(
            self.advanced_format_selection_frame)

        # audio_format_selection
        self.audio_format_selection_label = QLabel(
            self.advanced_format_selection_frame)
        self.audio_format_selection_comboBox = QComboBox(
            self.advanced_format_selection_frame)

        for widget in [
                self.video_format_selection_label,
                self.video_format_selection_comboBox,
                self.audio_format_selection_label,
                self.audio_format_selection_comboBox
        ]:
            advanced_format_selection_horizontalLayout.addWidget(widget)

        # Set Texts
        self.url_submit_pushButtontton.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Fetch Media List'))
        self.select_format_label.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Select a format'))

        self.video_format_selection_label.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video format:'))
        self.audio_format_selection_label.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr", 'Audio format:'))

        self.advanced_format_selection_checkBox.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Advanced options'))

        # Add Slot Connections
        self.url_submit_pushButtontton.setEnabled(False)
        self.change_name_lineEdit.setEnabled(False)
        self.ok_pushButton.setEnabled(False)
        self.download_later_pushButton.setEnabled(False)

        self.format_selection_frame.setEnabled(True)
        self.advanced_format_selection_frame.setEnabled(False)
        self.advanced_format_selection_checkBox.toggled.connect(
            self.advancedFormatFrame)

        self.url_submit_pushButtontton.clicked.connect(self.submitClicked)

        self.media_comboBox.activated.connect(
            partial(self.mediaSelectionChanged, 'video_audio'))

        self.video_format_selection_comboBox.activated.connect(
            partial(self.mediaSelectionChanged, 'video'))

        self.audio_format_selection_comboBox.activated.connect(
            partial(self.mediaSelectionChanged, 'audio'))

        self.link_lineEdit.textChanged.disconnect(
            super().linkLineChanged)  # Should be disconnected.
        self.link_lineEdit.textChanged.connect(self.linkLineChangedHere)

        self.setMinimumSize(650, 480)

        self.status_box_textEdit.hide()
        self.format_selection_frame.hide()
        self.advanced_format_selection_frame.hide()
        self.advanced_format_selection_checkBox.hide()

        if 'link' in video_dict.keys() and video_dict['link']:
            self.link_lineEdit.setText(video_dict['link'])
            self.url_submit_pushButtontton.setEnabled(True)
        else:
            # check clipboard
            clipboard = QApplication.clipboard()
            text = clipboard.text()
            if (("tp:/" in text[2:6]) or ("tps:/" in text[2:7])):
                self.link_lineEdit.setText(str(text))

            self.url_submit_pushButtontton.setEnabled(True)

    def advancedFormatFrame(self, button):
        if self.advanced_format_selection_checkBox.isChecked():

            self.advanced_format_selection_frame.setEnabled(True)
            self.format_selection_frame.setEnabled(False)
            self.mediaSelectionChanged(
                'video',
                int(self.video_format_selection_comboBox.currentIndex()))

        else:
            self.advanced_format_selection_frame.setEnabled(False)
            self.format_selection_frame.setEnabled(True)
            self.mediaSelectionChanged('video_audio',
                                       int(self.media_comboBox.currentIndex()))

    def getReadableSize(self, size):
        try:
            return '{:1.2f} MB'.format(int(size) / 1048576)
        except:
            return str(size)

    def getReadableDuration(self, seconds):
        try:
            seconds = int(seconds)
            hours = seconds // 3600
            seconds = seconds % 3600
            minutes = seconds // 60
            seconds = seconds % 60
            return '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds)
        except:
            return str(seconds)

    # Define native slots

    def urlChanged(self, value):
        if ' ' in value or value == '':
            self.url_submit_pushButtontton.setEnabled(False)
            self.url_submit_pushButtontton.setToolTip(
                QCoreApplication.translate("ytaddlink_src_ui_tr",
                                           'Please enter a valid video link'))
        else:
            self.url_submit_pushButtontton.setEnabled(True)
            self.url_submit_pushButtontton.setToolTip('')

    def submitClicked(self, button=None):
        # Clear media list
        self.media_comboBox.clear()
        self.format_selection_frame.hide()
        self.advanced_format_selection_checkBox.hide()
        self.advanced_format_selection_frame.hide()
        self.video_format_selection_comboBox.clear()
        self.audio_format_selection_comboBox.clear()
        self.change_name_lineEdit.clear()
        self.threadPool.clear()
        self.change_name_checkBox.setChecked(False)
        self.video_audio_list.clear()
        self.no_video_list.clear()
        self.no_audio_list.clear()
        self.url_submit_pushButtontton.setEnabled(False)
        self.status_box_textEdit.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Fetching Media Info...'))
        self.status_box_textEdit.show()
        self.ok_pushButton.setEnabled(False)
        self.download_later_pushButton.setEnabled(False)

        dictionary_to_send = deepcopy(self.plugin_add_link_dictionary)
        # More options
        more_options = self.collectMoreOptions()
        for k in more_options.keys():
            dictionary_to_send[k] = more_options[k]
        dictionary_to_send['link'] = self.link_lineEdit.text()

        fetcher_thread = MediaListFetcherThread(self.fetchedResult,
                                                dictionary_to_send, self)
        self.parent.threadPool.append(fetcher_thread)
        self.parent.threadPool[len(self.parent.threadPool) - 1].start()

    def fileNameChanged(self, value):
        if value.strip() == '':
            self.ok_pushButton.setEnabled(False)

    def mediaSelectionChanged(self, combobox, index):
        try:
            if combobox == 'video_audio':
                if self.media_comboBox.currentText() == 'Best quality':
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' +
                                                 self.no_audio_list[-1]['ext'])

                else:
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText(
                        '.' + self.video_audio_list[index]['ext'])

                self.change_name_checkBox.setChecked(True)

            elif combobox == 'video':
                if self.video_format_selection_comboBox.currentText(
                ) != 'No video':
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' +
                                                 self.no_audio_list[index -
                                                                    1]['ext'])
                    self.change_name_checkBox.setChecked(True)

                else:

                    if self.audio_format_selection_comboBox.currentText(
                    ) != 'No audio':
                        self.change_name_lineEdit.setText(self.media_title)
                        self.extension_label.setText('.' + self.no_video_list[
                            int(self.audio_format_selection_comboBox.
                                currentIndex()) - 1]['ext'])

                        self.change_name_checkBox.setChecked(True)
                    else:
                        self.change_name_lineEdit.setChecked(False)

            elif combobox == 'audio':
                if self.audio_format_selection_comboBox.currentText(
                ) != 'No audio' and self.video_format_selection_comboBox.currentText(
                ) == 'No video':
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' +
                                                 self.no_video_list[index -
                                                                    1]['ext'])

                    self.change_name_checkBox.setChecked(True)

                elif (self.audio_format_selection_comboBox.currentText()
                      == 'No audio'
                      and self.video_format_selection_comboBox.currentText() !=
                      'No video') or (
                          self.audio_format_selection_comboBox.currentText() !=
                          'No audio' and
                          self.video_format_selection_comboBox.currentText() !=
                          'No video'):
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' + self.no_audio_list[
                        int(self.video_format_selection_comboBox.currentIndex(
                        )) - 1]['ext'])

                    self.change_name_checkBox.setChecked(True)

                elif self.audio_format_selection_comboBox.currentText(
                ) == 'No audio' and self.video_format_selection_comboBox.currentText(
                ) == 'No video':
                    self.change_name_checkBox.setChecked(False)

        except Exception as ex:
            logger.sendToLog(ex, "ERROR")

    def fetchedResult(self, media_dict):

        self.url_submit_pushButtontton.setEnabled(True)
        if 'error' in media_dict.keys():

            self.status_box_textEdit.setText('<font color="#f11">' +
                                             str(media_dict['error']) +
                                             '</font>')
            self.status_box_textEdit.show()
        else:  # Show the media list

            # add no audio and no video options to the comboboxes
            self.video_format_selection_comboBox.addItem('No video')
            self.audio_format_selection_comboBox.addItem('No audio')

            self.media_title = media_dict['title']
            if 'formats' not in media_dict.keys(
            ) and 'entries' in media_dict.keys():
                formats = media_dict['entries']
                formats = formats[0]
                media_dict['formats'] = formats['formats']
            elif 'formats' not in media_dict.keys(
            ) and 'format' in media_dict.keys():
                media_dict['formats'] = [media_dict.copy()]

            try:
                i = 0
                for f in media_dict['formats']:
                    no_audio = False
                    no_video = False
                    text = ''
                    if 'acodec' in f.keys():
                        # only video, no audio
                        if f['acodec'] == 'none':
                            no_audio = True

                        # resolution
                        if 'height' in f.keys():
                            text = text + ' ' + '{}p'.format(f['height'])

                    if 'vcodec' in f.keys():
                        #                         if f['vcodec'] == 'none' and f['acodec'] != 'none':
                        #                             continue

                        # No video, show audio bit rate
                        if f['vcodec'] == 'none':
                            text = text + '{}kbps'.format(f['abr'])
                            no_video = True

                    if 'ext' in f.keys():
                        text = text + ' ' + '.{}'.format(f['ext'])

                    if 'filesize' in f.keys() and f['filesize']:
                        # Youtube api does not supply file size for some formats, so check it.
                        text = text + ' ' + '{}'.format(
                            self.getReadableSize(f['filesize']))

                    else:  # Start spider to find file size
                        input_dict = deepcopy(self.plugin_add_link_dictionary)

                        input_dict['link'] = f['url']
                        more_options = self.collectMoreOptions()

                        for key in more_options.keys():
                            input_dict[key] = more_options[key]

                        size_fetcher = FileSizeFetcherThread(input_dict, i)
                        self.threadPool[str(i)] = {
                            'thread': size_fetcher,
                            'item_id': i
                        }
                        self.parent.threadPool.append(size_fetcher)
                        self.parent.threadPool[len(self.parent.threadPool) -
                                               1].start()
                        self.parent.threadPool[len(self.parent.threadPool) -
                                               1].FOUND.connect(
                                                   self.findFileSize)

                    # Add current format to the related comboboxes
                    if no_audio:
                        self.no_audio_list.append(f)
                        self.video_format_selection_comboBox.addItem(text)

                    elif no_video:
                        self.no_video_list.append(f)
                        self.audio_format_selection_comboBox.addItem(text)

                    else:
                        self.video_audio_list.append(f)
                        self.media_comboBox.addItem(text)

                    i = i + 1

                self.status_box_textEdit.hide()

                if 'duration' in media_dict.keys():
                    self.duration_label.setText(
                        'Duration ' +
                        self.getReadableDuration(media_dict['duration']))

                self.format_selection_frame.show()
                self.advanced_format_selection_checkBox.show()
                self.advanced_format_selection_frame.show()
                self.ok_pushButton.setEnabled(True)
                self.download_later_pushButton.setEnabled(True)

                # if we have no options for separate audio and video, then hide advanced_format_selection...
                if len(self.no_audio_list) == 0 and len(
                        self.no_video_list) == 0:
                    self.advanced_format_selection_checkBox.hide()
                    self.advanced_format_selection_frame.hide()

                # set index of comboboxes on best available quality.
                # we have both audio and video
                if len(self.no_audio_list) != 0 and len(
                        self.no_video_list) != 0:
                    self.media_comboBox.addItem('Best quality')
                    self.media_comboBox.setCurrentIndex(
                        len(self.video_audio_list))
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' +
                                                 self.no_audio_list[-1]['ext'])
                    self.change_name_checkBox.setChecked(True)

                # video and audio are not separate
                elif len(self.video_audio_list) != 0:
                    self.media_comboBox.setCurrentIndex(
                        len(self.video_audio_list) - 1)

                if len(self.no_audio_list) != 0:
                    self.video_format_selection_comboBox.setCurrentIndex(
                        len(self.no_audio_list))

                if len(self.no_video_list) != 0:
                    self.audio_format_selection_comboBox.setCurrentIndex(
                        len(self.no_video_list))

                # if we have only audio or we have only video then hide media_comboBox
                if len(self.video_audio_list) == 0:
                    self.media_comboBox.hide()
                    self.select_format_label.hide()

                    # only video
                    if len(self.no_video_list) != 0 and len(
                            self.no_audio_list) == 0:
                        self.mediaSelectionChanged(
                            'video',
                            int(self.video_format_selection_comboBox.
                                currentIndex()))
                        self.advanced_format_selection_checkBox.setChecked(
                            True)
                        self.advanced_format_selection_checkBox.hide()

                    # only audio
                    elif len(self.no_video_list) == 0 and len(
                            self.no_audio_list) != 0:
                        self.mediaSelectionChanged(
                            'audio',
                            int(self.audio_format_selection_comboBox.
                                currentIndex()))
                        self.advanced_format_selection_checkBox.setChecked(
                            True)
                        self.advanced_format_selection_checkBox.hide()

                    # audio and video
                    else:
                        self.mediaSelectionChanged(
                            'video_audio',
                            int(self.media_comboBox.currentIndex()))

            except Exception as ex:
                logger.sendToLog(ex, "ERROR")

    def findFileSize(self, result):
        try:
            item_id = self.threadPool[str(result['thread_key'])]['item_id']
            if result['file_size'] and result['file_size'] != '0':
                text = self.media_comboBox.itemText(item_id)
                self.media_comboBox.setItemText(
                    item_id, '{} - {}'.format(text, result['file_size']))
        except Exception as ex:
            logger.sendToLog(ex, "ERROR")

    def linkLineChangedHere(self, lineEdit):
        if str(lineEdit) == '':
            self.url_submit_pushButtontton.setEnabled(False)
        else:
            self.url_submit_pushButtontton.setEnabled(True)

    # This method collects additional information like proxy ip, user, password etc.
    def collectMoreOptions(self):
        options = {
            'ip': None,
            'port': None,
            'proxy_user': None,
            'proxy_passwd': None,
            'download_user': None,
            'download_passwd': None
        }
        if self.proxy_checkBox.isChecked():
            options['ip'] = self.ip_lineEdit.text()
            options['port'] = self.port_spinBox.value()
            options['proxy_user'] = self.proxy_user_lineEdit.text()
            options['proxy_passwd'] = self.proxy_pass_lineEdit.text()
        if self.download_checkBox.isChecked():
            options['download_user'] = self.download_user_lineEdit.text()
            options['download_passwd'] = self.download_pass_lineEdit.text()

        # These info (keys) are required for spider to find file size, because spider() does not check if key exists.
        additional_info = [
            'header', 'load_cookies', 'user_agent', 'referer', 'out'
        ]
        for i in additional_info:
            if i not in self.plugin_add_link_dictionary.keys():
                options[i] = None
        return options

    # user submitted information by pressing ok_pushButton, so get information
    # from VideoFinderAddLink window and return them to the mainwindow with callback!
    def okButtonPressed(self, download_later, button=None):

        link_list = []
        # separate audio format and video format is selected.
        if self.advanced_format_selection_checkBox.isChecked():

            if self.video_format_selection_comboBox.currentText(
            ) == 'No video' and self.audio_format_selection_comboBox.currentText(
            ) != 'No audio':

                # only audio link must be added to the link_list
                audio_link = self.no_video_list[
                    self.audio_format_selection_comboBox.currentIndex() -
                    1]['url']
                link_list.append(audio_link)

            elif self.video_format_selection_comboBox.currentText(
            ) != 'No video' and self.audio_format_selection_comboBox.currentText(
            ) == 'No audio':

                # only video link must be added to the link_list
                video_link = self.no_audio_list[
                    self.video_format_selection_comboBox.currentIndex() -
                    1]['url']
                link_list.append(video_link)

            elif self.video_format_selection_comboBox.currentText(
            ) != 'No video' and self.audio_format_selection_comboBox.currentText(
            ) != 'No audio':

                # video and audio links must be added to the link_list
                audio_link = self.no_video_list[
                    self.audio_format_selection_comboBox.currentIndex() -
                    1]['url']
                video_link = self.no_audio_list[
                    self.video_format_selection_comboBox.currentIndex() -
                    1]['url']
                link_list = [video_link, audio_link]

            elif self.video_format_selection_comboBox.currentText(
            ) == 'No video' and self.audio_format_selection_comboBox.currentText(
            ) == 'No audio':

                # no video and audio is selected! REALLY?!. user is DRUNK! close the window! :))
                self.close()
        else:
            if self.media_comboBox.currentText() == 'Best quality':

                # the last item in no_video_list and no_audio_list are the best.
                video_link = self.no_audio_list[-1]['url']
                audio_link = self.no_video_list[-1]['url']

                link_list = [video_link, audio_link]

            else:
                audio_and_video_link = self.video_audio_list[
                    self.media_comboBox.currentIndex()]['url']
                link_list.append(audio_and_video_link)

        # write user's new inputs in persepolis_setting for next time :)
        self.persepolis_setting.setValue('add_link_initialization/ip',
                                         self.ip_lineEdit.text())
        self.persepolis_setting.setValue('add_link_initialization/port',
                                         self.port_spinBox.value())
        self.persepolis_setting.setValue('add_link_initialization/proxy_user',
                                         self.proxy_user_lineEdit.text())
        self.persepolis_setting.setValue(
            'add_link_initialization/download_user',
            self.download_user_lineEdit.text())

        # get proxy information
        if not (self.proxy_checkBox.isChecked()):
            ip = None
            port = None
            proxy_user = None
            proxy_passwd = None
        else:
            ip = self.ip_lineEdit.text()
            if not (ip):
                ip = None
            port = self.port_spinBox.value()
            if not (port):
                port = None
            proxy_user = self.proxy_user_lineEdit.text()
            if not (proxy_user):
                proxy_user = None
            proxy_passwd = self.proxy_pass_lineEdit.text()
            if not (proxy_passwd):
                proxy_passwd = None

        # get download username and password information
        if not (self.download_checkBox.isChecked()):
            download_user = None
            download_passwd = None
        else:
            download_user = self.download_user_lineEdit.text()
            if not (download_user):
                download_user = None
            download_passwd = self.download_pass_lineEdit.text()
            if not (download_passwd):
                download_passwd = None

        # check that if user limits download speed.
        if not (self.limit_checkBox.isChecked()):
            limit = 0
        else:
            if self.limit_comboBox.currentText() == "KiB/s":
                limit = str(self.limit_spinBox.value()) + str("K")
            else:
                limit = str(self.limit_spinBox.value()) + str("M")

        # get start time for download if user set that.
        if not (self.start_checkBox.isChecked()):
            start_time = None
        else:
            start_time = self.start_time_qDataTimeEdit.text()

        # get end time for download if user set that.
        if not (self.end_checkBox.isChecked()):
            end_time = None
        else:
            end_time = self.end_time_qDateTimeEdit.text()

        # set name for file(s)
        if self.change_name_checkBox.isChecked():
            name = str(self.change_name_lineEdit.text())
            if name == '':
                name = 'video_finder_file'
        else:
            name = 'video_finder_file'

        # video finder always finds extension
        # but if it can't find file extension
        # use mp4 for extension.
        if str(self.extension_label.text()) == '':
            extension = '.mp4'
        else:
            extension = str(self.extension_label.text())

        # did user select separate audio and video?
        if len(link_list) == 2:
            video_name = name + extension
            audio_name = name + '.' + \
                str(self.no_video_list[self.audio_format_selection_comboBox.currentIndex() - 1]['ext'])

            name_list = [video_name, audio_name]
        else:
            name_list = [name + extension]

        # get number of connections
        connections = self.connections_spinBox.value()

        # get download_path
        download_path = self.download_folder_lineEdit.text()

        # referer
        if self.referer_lineEdit.text() != '':
            referer = self.referer_lineEdit.text()
        else:
            referer = None

        # header
        if self.header_lineEdit.text() != '':
            header = self.header_lineEdit.text()
        else:
            header = None

        # user_agent
        if self.user_agent_lineEdit.text() != '':
            user_agent = self.user_agent_lineEdit.text()
        else:
            user_agent = None

        # load_cookies
        if self.load_cookies_lineEdit.text() != '':
            load_cookies = self.load_cookies_lineEdit.text()
        else:
            load_cookies = None

        add_link_dictionary_list = []
        if len(link_list) == 1:
            # save information in a dictionary(add_link_dictionary).
            add_link_dictionary = {
                'referer': referer,
                'header': header,
                'user_agent': user_agent,
                'load_cookies': load_cookies,
                'out': name_list[0],
                'start_time': start_time,
                'end_time': end_time,
                'link': link_list[0],
                'ip': ip,
                'port': port,
                'proxy_user': proxy_user,
                'proxy_passwd': proxy_passwd,
                'download_user': download_user,
                'download_passwd': download_passwd,
                'connections': connections,
                'limit_value': limit,
                'download_path': download_path
            }

            add_link_dictionary_list.append(add_link_dictionary)

        else:
            video_add_link_dictionary = {
                'referer': referer,
                'header': header,
                'user_agent': user_agent,
                'load_cookies': load_cookies,
                'out': name_list[0],
                'start_time': start_time,
                'end_time': end_time,
                'link': link_list[0],
                'ip': ip,
                'port': port,
                'proxy_user': proxy_user,
                'proxy_passwd': proxy_passwd,
                'download_user': download_user,
                'download_passwd': download_passwd,
                'connections': connections,
                'limit_value': limit,
                'download_path': download_path
            }

            audio_add_link_dictionary = {
                'referer': referer,
                'header': header,
                'user_agent': user_agent,
                'load_cookies': load_cookies,
                'out': name_list[1],
                'start_time': None,
                'end_time': end_time,
                'link': link_list[1],
                'ip': ip,
                'port': port,
                'proxy_user': proxy_user,
                'proxy_passwd': proxy_passwd,
                'download_user': download_user,
                'download_passwd': download_passwd,
                'connections': connections,
                'limit_value': limit,
                'download_path': download_path
            }

            add_link_dictionary_list = [
                video_add_link_dictionary, audio_add_link_dictionary
            ]

        # get category of download
        category = str(self.add_queue_comboBox.currentText())

        del self.plugin_add_link_dictionary

        # return information to mainwindow
        self.callback(add_link_dictionary_list, download_later, category)

        # close window
        self.close()
Пример #9
0
class PlaylistPopup(QWidget):
    def __init__(self, result, parent=None):
        # Popup when "Add song to playlist" is clicked on
        # How this works is a QWidget that encompasses the entire window area, representing an unclickable translucent background.
        # Another QWidget is then contained inside that QWidget representing the popup.
        # result: (dict) Python dict containing information of the song clicked
        QWidget.__init__(self)
        self.setParent(parent)
        self.result = result

        # Signals are used to indicate to close the window
        self.SIGNALS = self.TranslucentWidgetSignals()

        # Make the window frameless and expanding.
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # Makes the window background colour translucent
        self.setAttribute(Qt.WA_StyledBackground)
        self.setStyleSheet(
            "PlaylistPopup { background-color: rgba(255, 255, 255, 0.5)}")

        # Sets the grid settings of the "background" and the "popup"
        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        playlistAdd = QWidget(self)
        playlistAdd.setFixedSize(800, 300)
        playlistAdd.setStyleSheet(
            ".QWidget { background-color: rgba(255, 255, 255, 1)}")
        innerLayout = QGridLayout()
        innerLayout.setContentsMargins(20, 20, 20, 20)
        innerLayout.setSpacing(30)

        # Heading font
        font = QFont()
        font.setPointSize(24)

        # Default label font
        font2 = QFont()
        font2.setPointSize(16)

        # Heading
        label = QLabel("添加到播放列表/Add to Playlist", self)
        label.setAlignment(Qt.AlignCenter)
        label.setFont(font)
        innerLayout.addWidget(label, 0, 0)

        # Playlist selection
        self.comboBox = QComboBox(self)
        self.comboBox.setFont(font)
        playlists = DB.getPlaylists("")
        for playlist in playlists:
            self.comboBox.addItem(playlist["playlist_name"])
        self.comboBox.setCurrentIndex(-1)
        innerLayout.addWidget(self.comboBox, 1, 0)

        # Textbox to create a new playlist
        self.textBox = QLineEdit(self)
        self.textBox.setFont(font2)
        self.textBox.setAlignment(Qt.AlignCenter)
        self.textBox.setPlaceholderText(
            "输入以创建新的播放列表/Type to create a new playlist")
        self.textBox.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        # TODO: resize textbox with window
        self.textBox.setFixedWidth(760)
        innerLayout.addWidget(self.textBox, 2, 0, Qt.AlignCenter)

        # Add actions for then the QComboBox or QLineEdit is changed.
        # This is done so there is only one action between "Add to existing Playlist" or "Add to new Playlist"
        self.comboBox.currentIndexChanged.connect(self.comboBoxChanged)
        self.textBox.textEdited.connect(self.textBoxChanged)

        # Confirm button
        confirmButton = QToolButton(self)
        confirmButton.setText("确认/Confirm")
        confirmButton.setFont(font)
        confirmButton.clicked.connect(self.processPlaylistRequest)
        innerLayout.addWidget(confirmButton, 3, 0, Qt.AlignCenter)

        # Exit button
        btn = QToolButton(self)
        btn.setFixedSize(44, 44)
        btn.setText("X")
        btn.setFont(font)
        btn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        btn.clicked.connect(lambda: self.SIGNALS.CLOSE.emit())
        innerLayout.addWidget(btn, 0, 0, Qt.AlignRight)

        playlistAdd.setLayout(innerLayout)
        layout.addWidget(playlistAdd, 0, 0, Qt.AlignCenter)
        self.setLayout(layout)

    def comboBoxChanged(self):
        # Called when the ComboBox is changed
        # Clears the text in the "Create Playlist" TextBox
        if self.textBox.text() != "":
            self.textBox.setText("")

    def textBoxChanged(self):
        # Called when the TextBox is changed
        # Clears the selection in the "Add to Playlist" ComboBox
        if self.comboBox.currentIndex != -1:
            self.comboBox.setCurrentIndex(-1)

    def processPlaylistRequest(self):
        # Called when the Confirm button is clicked
        def addToPlaylist(self, playlistID):
            # Adds the song to the playlist
            # Get song ID
            song = self.result["song_id"]
            DB.addPlaylistSong(playlistID, song)

        if self.textBox.text() != "":
            # New playlist
            playlistName = self.textBox.text()
            counter = 1
            while DB.checkPlaylist(playlistName):
                playlistName = "{} ({})".format(self.textBox.text(), counter)
                counter += 1
            playlistID = DB.newPlaylist(playlistName)[0]["playlist_id"]
            addToPlaylist(self, playlistID)
            self.SIGNALS.CLOSE.emit()
        elif self.comboBox.currentIndex != -1:
            playlistID = DB.checkPlaylist(
                self.comboBox.currentText())[0]["playlist_id"]
            # Add to existing playlist
            addToPlaylist(self, playlistID)
            self.SIGNALS.CLOSE.emit()

    # Taken from https://stackoverflow.com/questions/44264852/pyside-pyqt-overlay-widget
    class TranslucentWidgetSignals(QtCore.QObject):
        CLOSE = QtCore.Signal()
Пример #10
0
class LocationDialog(QDialog):
    def __init__(self, parent=None):
        super(LocationDialog, self).__init__(parent)

        self.format_combo = QComboBox()
        self.format_combo.addItem("Native")
        self.format_combo.addItem("INI")

        self.scope_cCombo = QComboBox()
        self.scope_cCombo.addItem("User")
        self.scope_cCombo.addItem("System")

        self.organization_combo = QComboBox()
        self.organization_combo.addItem("Trolltech")
        self.organization_combo.setEditable(True)

        self.application_combo = QComboBox()
        self.application_combo.addItem("Any")
        self.application_combo.addItem("Application Example")
        self.application_combo.addItem("Assistant")
        self.application_combo.addItem("Designer")
        self.application_combo.addItem("Linguist")
        self.application_combo.setEditable(True)
        self.application_combo.setCurrentIndex(3)

        format_label = QLabel("&Format:")
        format_label.setBuddy(self.format_combo)

        scope_label = QLabel("&Scope:")
        scope_label.setBuddy(self.scope_cCombo)

        organization_label = QLabel("&Organization:")
        organization_label.setBuddy(self.organization_combo)

        application_label = QLabel("&Application:")
        application_label.setBuddy(self.application_combo)

        self.locations_groupbox = QGroupBox("Setting Locations")

        self.locations_table = QTableWidget()
        self.locations_table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.locations_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.locations_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.locations_table.setColumnCount(2)
        self.locations_table.setHorizontalHeaderLabels(("Location", "Access"))
        self.locations_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        self.locations_table.horizontalHeader().resizeSection(1, 180)

        self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

        self.format_combo.activated.connect(self.update_locations)
        self.scope_cCombo.activated.connect(self.update_locations)
        self.organization_combo.lineEdit().editingFinished.connect(self.update_locations)
        self.application_combo.lineEdit().editingFinished.connect(self.update_locations)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)

        locations_layout = QVBoxLayout(self.locations_groupbox)
        locations_layout.addWidget(self.locations_table)

        mainLayout = QGridLayout(self)
        mainLayout.addWidget(format_label, 0, 0)
        mainLayout.addWidget(self.format_combo, 0, 1)
        mainLayout.addWidget(scope_label, 1, 0)
        mainLayout.addWidget(self.scope_cCombo, 1, 1)
        mainLayout.addWidget(organization_label, 2, 0)
        mainLayout.addWidget(self.organization_combo, 2, 1)
        mainLayout.addWidget(application_label, 3, 0)
        mainLayout.addWidget(self.application_combo, 3, 1)
        mainLayout.addWidget(self.locations_groupbox, 4, 0, 1, 2)
        mainLayout.addWidget(self.button_box, 5, 0, 1, 2)

        self.update_locations()

        self.setWindowTitle("Open Application Settings")
        self.resize(650, 400)

    def format(self):
        if self.format_combo.currentIndex() == 0:
            return QSettings.NativeFormat
        else:
            return QSettings.IniFormat

    def scope(self):
        if self.scope_cCombo.currentIndex() == 0:
            return QSettings.UserScope
        else:
            return QSettings.SystemScope

    def organization(self):
        return self.organization_combo.currentText()

    def application(self):
        if self.application_combo.currentText() == "Any":
            return ''

        return self.application_combo.currentText()

    def update_locations(self):
        self.locations_table.setUpdatesEnabled(False)
        self.locations_table.setRowCount(0)

        for i in range(2):
            if i == 0:
                if self.scope() == QSettings.SystemScope:
                    continue

                actualScope = QSettings.UserScope
            else:
                actualScope = QSettings.SystemScope

            for j in range(2):
                if j == 0:
                    if not self.application():
                        continue

                    actualApplication = self.application()
                else:
                    actualApplication = ''

                settings = QSettings(self.format(), actualScope,
                                     self.organization(), actualApplication)

                row = self.locations_table.rowCount()
                self.locations_table.setRowCount(row + 1)

                item0 = QTableWidgetItem()
                item0.setText(settings.fileName())

                item1 = QTableWidgetItem()
                disable = not (settings.childKeys() or settings.childGroups())

                if row == 0:
                    if settings.isWritable():
                        item1.setText("Read-write")
                        disable = False
                    else:
                        item1.setText("Read-only")
                    self.button_box.button(QDialogButtonBox.Ok).setDisabled(disable)
                else:
                    item1.setText("Read-only fallback")

                if disable:
                    item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled)
                    item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled)

                self.locations_table.setItem(row, 0, item0)
                self.locations_table.setItem(row, 1, item1)

        self.locations_table.setUpdatesEnabled(True)
class JobsWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.quit_button = QPushButton("Quit", self)
        self.update_button = QPushButton("Update Data", self)
        self.enter_data = QPushButton("Enter Data", self)
        self.data_button = QPushButton("Run Data Visualization", self)
        self.back_button = QPushButton("Back", self)
        self.text_visualization_button = QPushButton("Text Visualization", self)
        self.map_visualization = QPushButton("Map Visualization", self)
        self.order_selector_text = QComboBox(self)
        self.data_selector_map = QComboBox(self)
        self.data_visualization_label = QLabel("Welcome to data visualization!", self)
        self.welcome_label = QLabel("Welcome to Jobs data Visualization.", self)
        self.list_control = None
        self.update_label_01 = QLabel("", self)
        self.update_label_02 = QLabel("", self)
        self.update_label_03 = QLabel("", self)
        self.update_label_04 = QLabel("", self)
        self.update_label_05 = QLabel("", self)
        self.update_label_06 = QLabel("", self)
        self.update_label_07 = QLabel("", self)
        self.update_label_08 = QLabel("", self)
        self.excel_label = QLabel("Excel Spreadsheet:", self)
        self.update_information = QLabel(
            "If you would like to update a single entry please select the table and enter all of its information.\n"
            "If you would like to import from a spreadsheet type it into the box on the right and select the table.\n"
            "When you are ready with which ever function press Enter Data.\n"
            "For any data you want to append make sure the id is None.\n"
            "Also only work from one method at a time and make sure he other is empty.", self)
        self.table_selection = QComboBox(self)
        self.update_box_01 = QLineEdit(self)
        self.update_box_02 = QLineEdit(self)
        self.update_box_03 = QLineEdit(self)
        self.update_box_04 = QLineEdit(self)
        self.update_box_05 = QLineEdit(self)
        self.update_box_06 = QLineEdit(self)
        self.update_box_07 = QLineEdit(self)
        self.update_box_08 = QLineEdit(self)
        self.update_excel_selection = QLineEdit(self)
        self.list_control = None
        self.setup_window()

    def setup_window(self):
        self.setWindowTitle("Jobs Window")
        display_list = QListWidget(self)
        self.list_control = display_list
        display_list.resize(500, 350)
        self.setGeometry(50, 50, 500, 500)
        self.quit_button.clicked.connect(QApplication.instance().quit)
        self.quit_button.resize(self.quit_button.sizeHint())
        self.quit_button.move(415, 450)
        self.update_button.clicked.connect(self.update_data)
        self.update_button.move(200, 200)
        self.data_button.clicked.connect(self.run_data_visualization)
        self.data_button.move(175, 250)
        self.back_button.clicked.connect(self.go_back)
        self.back_button.move(25, 450)
        self.data_visualization_label.move(20, 400)
        self.text_visualization_button.move(400 - self.text_visualization_button.width(), 600)
        self.order_selector_text.move(self.text_visualization_button.x(),
                                      self.text_visualization_button.y()+self.text_visualization_button.height()+10)
        self.text_visualization_button.clicked.connect(self.text_visualization)
        self.map_visualization.move(self.text_visualization_button.x() + self.text_visualization_button.width(),
                                    self.text_visualization_button.y())
        self.data_selector_map.move(self.map_visualization.x(),
                                    self.map_visualization.y()+self.map_visualization.height()+10)
        self.map_visualization.clicked.connect(self.run_map_visualization)
        self.welcome_label.move(150, 150)
        self.update_box_01.move(150, 30)
        self.update_box_02.move(150, 60)
        self.update_box_03.move(150, 90)
        self.update_box_04.move(150, 120)
        self.update_box_05.move(150, 150)
        self.update_box_06.move(150, 180)
        self.update_box_07.move(150, 210)
        self.update_box_08.move(150, 240)
        self.excel_label.move(340, 70)
        self.update_excel_selection.move(340, 90)
        self.update_information.move(25, 325)
        self.update_label_01.setGeometry(5, 30, 145, 20)
        self.update_label_02.setGeometry(5, 60, 145, 20)
        self.update_label_03.setGeometry(5, 90, 145, 20)
        self.update_label_04.setGeometry(5, 120, 145, 20)
        self.update_label_05.setGeometry(5, 150, 145, 20)
        self.update_label_06.setGeometry(5, 180, 145, 20)
        self.update_label_07.setGeometry(5, 210, 145, 20)
        self.update_label_08.setGeometry(5, 240, 145, 20)
        self.table_selection.setGeometry(10, 10, 145, 20)
        self.enter_data.move(10, 260)
        self.enter_data.clicked.connect(self.import_data)
        self.table_selection.addItem("---")
        self.table_selection.addItem("Schools")
        self.table_selection.addItem("Jobs")
        self.order_selector_text.addItem("---")
        self.order_selector_text.addItem("ASC")
        self.order_selector_text.addItem("DESC")
        self.data_selector_map.addItem("---")
        self.data_selector_map.addItem("Employment to Graduates")
        self.data_selector_map.addItem("Average Salary to Average Declining Balance Percent")
        self.table_selection.currentIndexChanged.connect(self.update_selection)
        self.hidden_at_start()

        self.show()

    def hidden_at_start(self):
        self.hide_update_boxes()
        self.list_control.hide()
        self.update_information.hide()
        self.map_visualization.hide()
        self.text_visualization_button.hide()
        self.data_visualization_label.hide()
        self.back_button.hide()
        self.table_selection.hide()
        self.enter_data.hide()
        self.update_excel_selection.hide()
        self.excel_label.hide()
        self.data_selector_map.hide()
        self.order_selector_text.hide()

    def hide_update_boxes(self):
        self.update_box_01.hide()
        self.update_box_02.hide()
        self.update_box_03.hide()
        self.update_box_04.hide()
        self.update_box_05.hide()
        self.update_box_06.hide()
        self.update_box_07.hide()
        self.update_box_08.hide()
        self.update_label_01.setText("")
        self.update_label_02.setText("")
        self.update_label_03.setText("")
        self.update_label_04.setText("")
        self.update_label_05.setText("")
        self.update_label_06.setText("")
        self.update_label_07.setText("")
        self.update_label_08.setText("")

    def update_data(self):
        self.update_button.hide()
        self.data_button.hide()
        self.back_button.show()
        self.welcome_label.hide()
        self.table_selection.show()
        self.enter_data.show()
        self.update_information.show()
        self.update_excel_selection.show()
        self.excel_label.show()

    def update_selection(self):
        self.hide_update_boxes()
        if self.table_selection.currentText() == "Jobs":
            self.update_box_01.show()
            self.update_label_01.setText("jobs_id")
            self.update_box_02.show()
            self.update_label_02.setText("state_name")
            self.update_box_03.show()
            self.update_label_03.setText("occupation_code")
            self.update_box_04.show()
            self.update_label_04.setText("tittle")
            self.update_box_05.show()
            self.update_label_05.setText("employment")
            self.update_box_06.show()
            self.update_label_06.setText("salary_25th_percentile")
        elif self.table_selection.currentText() == "Schools":
            self.update_box_01.show()
            self.update_label_01.setText("school_id")
            self.update_box_02.show()
            self.update_label_02.setText("name")
            self.update_box_03.show()
            self.update_label_03.setText("state_abrev")
            self.update_box_04.show()
            self.update_label_04.setText("size_2017")
            self.update_box_05.show()
            self.update_label_05.setText("size_2018")
            self.update_box_06.show()
            self.update_label_06.setText("earnings")
            self.update_box_07.show()
            self.update_label_07.setText("repayment_overall")
            self.update_box_08.show()
            self.update_label_08.setText("repayment_cohort")

    def import_data(self):
        if self.update_excel_selection.text() == "":
            if self.table_selection.currentText() == "Jobs":
                information_to_update = [self.update_box_01.text(), self.update_box_02.text(),
                                         self.update_box_03.text(), self.update_box_04.text(),
                                         self.update_box_05.text(), self.update_box_06.text()]
                jobs.update_data_from_list(information_to_update, "Jobs", "jobs_db.sqlite")
            elif self.table_selection.currentText() == "Schools":
                information_to_update = [self.update_box_01.text(), self.update_box_02.text(),
                                         self.update_box_03.text(), self.update_box_04.text(),
                                         self.update_box_05.text(), self.update_box_06.text(),
                                         self.update_box_07.text(), self.update_box_08.text()]
                jobs.update_data_from_list(information_to_update, "Schools", "jobs_db.sqlite")
        else:
            if self.table_selection.currentText() == "Jobs":
                jobs.update_data_from_excel(self.update_excel_selection.text(), "Jobs", "jobs_db.sqlite")
            elif self.table_selection.currentText() == "Schools":
                jobs.update_data_from_excel(self.update_excel_selection.text(), "Jobs", "jobs_db.sqlite")

    def run_data_visualization(self):
        self.update_button.hide()
        self.data_button.hide()
        self.data_visualization_label.show()
        self.back_button.show()
        self.setGeometry(50, 50, 800, 800)
        self.back_button.move(25, 750)
        self.quit_button.move(715, 750)
        self.welcome_label.hide()
        self.map_visualization.show()
        self.text_visualization_button.show()
        self.data_selector_map.show()
        self.order_selector_text.show()

    def go_back(self):
        self.back_button.hide()
        self.update_button.show()
        self.data_button.show()
        self.data_visualization_label.hide()
        self.setGeometry(50, 50, 500, 500)
        self.back_button.move(25, 450)
        self.quit_button.move(415, 450)
        self.welcome_label.show()
        self.hidden_at_start()

    def text_visualization(self):
        self.list_control.clear()
        conn, cursor = jobs.open_db("jobs_db.sqlite")
        if self.order_selector_text.currentText() == "ASC":
            data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + '''
            total(jobs.employment) as employment,
            total(school.size_2018/4),
            round(avg(school.repayment_cohort),3) as repayment_cohort,
            round(avg(jobs.salary_25th_percentile)) as averge_entry_salary
            FROM school
            JOIN states using(state_abrev)
            JOIN jobs using(state_name)
            GROUP BY state_name
            ORDER BY employment ASC;''', cursor)
        elif self.order_selector_text.currentText() == "DESC":
            data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + '''
                        total(jobs.employment) as employment,
                        total(school.size_2018/4),
                        round(avg(school.repayment_cohort),3) as repayment_cohort,
                        round(avg(jobs.salary_25th_percentile)) as averge_entry_salary
                        FROM school
                        JOIN states using(state_abrev)
                        JOIN jobs using(state_name)
                        GROUP BY state_name
                        ORDER BY employment DESC;''', cursor)
        else:
            data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + '''
                                    total(jobs.employment) as employment,
                                    total(school.size_2018/4),
                                    round(avg(school.repayment_cohort),3) as repayment_cohort,
                                    round(avg(jobs.salary_25th_percentile)) as averge_entry_salary
                                    FROM school
                                    JOIN states using(state_abrev)
                                    JOIN jobs using(state_name)
                                    GROUP BY state_name
                                    ;''', cursor)
        QListWidgetItem("State", listview=self.list_control)
        for state in data_visualization_per_state:
            state_display_data = f"{state[0]}, {state[1]}"
            grad_employ_data = f"Employment/Graduates: {state[2]/state[3]}"
            repayment_data = f"Average Entry Salary/Average Declining Balance Percent: {state[5]/state[4]}"
            state_item = QListWidgetItem(state_display_data, listview=self.list_control)
            grad_item = QListWidgetItem(grad_employ_data, listview=self.list_control)
            repayment_item = QListWidgetItem(repayment_data, listview=self.list_control)
            grad_item.setForeground(Qt.darkGreen)
            repayment_item.setForeground(Qt.blue)
            state_item.setForeground(Qt.white)
            state_item.setBackground(Qt.black)
        self.list_control.show()
        jobs.close_db(conn)

    def run_map_visualization(self):
        conn, cursor = jobs.open_db("jobs_db.sqlite")
        data_visualization_per_state = jobs.query_run('''SELECT state_abrev, state_name, ''' + '''
                total(jobs.employment) as employment,
                total(school.size_2018/4),
                round(avg(school.repayment_cohort),3) as repayment_cohort,
                round(avg(jobs.salary_25th_percentile)) as averge_entry_salary
                FROM school
                JOIN states using(state_abrev)
                JOIN jobs using(state_name)
                GROUP BY state_name
                ;''', cursor)
        state_abrev = []
        state_grads = []
        state_repayment = []

        for state in data_visualization_per_state:
            state_abrev.append(state[0])
            state_grads.append(state[2]/state[3])
            state_repayment.append(state[5]/state[4])

        if self.data_selector_map.currentText() == "Graduates to Employment":
            us_map = px.Figure(data=px.Choropleth(locations=state_abrev, z=state_grads,
                                                  locationmode='USA-states', colorbar_title="Employment/Graduates"
                                                  ))
            us_map.update_layout(geo_scope='usa', title_text='Employment VS Graduates By State')
            us_map.show()
        elif self.data_selector_map.currentText() == "Average Declining Balance Percent":
            us_map = px.Figure(data=px.Choropleth(locations=state_abrev, z=state_repayment,
                                                  locationmode='USA-states', colorbar_title="Salary/Average Percent"
                                                  ))
            us_map.update_layout(geo_scope='usa', title_text='Average Salary VS Average '
                                                             'Percent of People with Declining Loans')
            us_map.show()
        else:
            us_map = px.Figure(data=px.Choropleth(locations=state_abrev, z=state_grads,
                                                  locationmode='USA-states', colorbar_title="Graduates"
                                                  ))
            us_map.update_layout(geo_scope='usa', title_text='Graduates By State')
            us_map.show()
        jobs.close_db(conn)
        self.list_control.hide()
Пример #12
0
class UIManipulateROIWindow:
    def setup_ui(self, manipulate_roi_window_instance, rois, dataset_rtss,
                 roi_color, signal_roi_manipulated):

        self.patient_dict_container = PatientDictContainer()
        self.rois = rois
        self.dataset_rtss = dataset_rtss
        self.signal_roi_manipulated = signal_roi_manipulated
        self.roi_color = roi_color

        self.roi_names = []  # Names of selected ROIs
        self.all_roi_names = []  # Names of all existing ROIs
        for roi_id, roi_dict in self.rois.items():
            self.all_roi_names.append(roi_dict['name'])

        # Operation names
        self.single_roi_operation_names = [
            "Expand", "Contract", "Inner Rind (annulus)",
            "Outer Rind (annulus)"
        ]
        self.multiple_roi_operation_names = [
            "Union", "Intersection", "Difference"
        ]
        self.operation_names = self.multiple_roi_operation_names + \
                               self.single_roi_operation_names

        self.new_ROI_contours = None
        self.manipulate_roi_window_instance = manipulate_roi_window_instance

        self.dicom_view = DicomAxialView(metadata_formatted=True,
                                         is_four_view=True)
        self.dicom_preview = DicomAxialView(metadata_formatted=True,
                                            is_four_view=True)
        self.dicom_view.slider.valueChanged.connect(
            self.dicom_view_slider_value_changed)
        self.dicom_preview.slider.valueChanged.connect(
            self.dicom_preview_slider_value_changed)
        self.init_layout()

        QtCore.QMetaObject.connectSlotsByName(manipulate_roi_window_instance)

    def retranslate_ui(self, manipulate_roi_window_instance):
        _translate = QtCore.QCoreApplication.translate
        manipulate_roi_window_instance.setWindowTitle(
            _translate("ManipulateRoiWindowInstance",
                       "OnkoDICOM - Draw Region Of Interest"))
        self.first_roi_name_label.setText(
            _translate("FirstROINameLabel", "ROI 1: "))
        self.first_roi_name_dropdown_list.setPlaceholderText("ROI 1")
        self.first_roi_name_dropdown_list.addItems(self.all_roi_names)
        self.operation_name_label.setText(
            _translate("OperationNameLabel", "Operation"))
        self.operation_name_dropdown_list.setPlaceholderText("Operation")
        self.operation_name_dropdown_list.addItems(self.operation_names)
        self.second_roi_name_label.setText(
            _translate("SecondROINameLabel", "ROI 2: "))
        self.second_roi_name_dropdown_list.setPlaceholderText("ROI 2")
        self.second_roi_name_dropdown_list.addItems(self.all_roi_names)
        self.manipulate_roi_window_instance_draw_button.setText(
            _translate("ManipulateRoiWindowInstanceDrawButton", "Draw"))
        self.manipulate_roi_window_instance_save_button.setText(
            _translate("ManipulateRoiWindowInstanceSaveButton", "Save"))
        self.manipulate_roi_window_instance_cancel_button.setText(
            _translate("ManipulateRoiWindowInstanceCancelButton", "Cancel"))
        self.margin_label.setText(_translate("MarginLabel", "Margin (mm): "))
        self.new_roi_name_label.setText(
            _translate("NewROINameLabel", "New ROI Name"))
        self.ROI_view_box_label.setText("ROI")
        self.preview_box_label.setText("Preview")

    def init_layout(self):
        """
        Initialize the layout for the DICOM View tab.
        Add the view widget and the slider in the layout.
        Add the whole container 'tab2_view' as a tab in the main page.
        """

        # Initialise a ManipulateROIWindow
        if platform.system() == 'Darwin':
            self.stylesheet_path = "res/stylesheet.qss"
        else:
            self.stylesheet_path = "res/stylesheet-win-linux.qss"
        stylesheet = open(resource_path(self.stylesheet_path)).read()
        window_icon = QIcon()
        window_icon.addPixmap(QPixmap(resource_path("res/images/icon.ico")),
                              QIcon.Normal, QIcon.Off)
        self.manipulate_roi_window_instance.setObjectName(
            "ManipulateRoiWindowInstance")
        self.manipulate_roi_window_instance.setWindowIcon(window_icon)

        # Creating a form box to hold all buttons and input fields
        self.manipulate_roi_window_input_container_box = QFormLayout()
        self.manipulate_roi_window_input_container_box.setObjectName(
            "ManipulateRoiWindowInputContainerBox")
        self.manipulate_roi_window_input_container_box.setLabelAlignment(
            Qt.AlignLeft)

        # Create a label for denoting the first ROI name
        self.first_roi_name_label = QLabel()
        self.first_roi_name_label.setObjectName("FirstROINameLabel")
        self.first_roi_name_dropdown_list = QComboBox()
        # Create an dropdown list for ROI name
        self.first_roi_name_dropdown_list.setObjectName(
            "FirstROINameDropdownList")
        self.first_roi_name_dropdown_list.setSizePolicy(
            QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.first_roi_name_dropdown_list.resize(
            self.first_roi_name_dropdown_list.sizeHint().width(),
            self.first_roi_name_dropdown_list.sizeHint().height())
        self.first_roi_name_dropdown_list.activated.connect(
            self.update_selected_rois)
        self.manipulate_roi_window_input_container_box.addRow(
            self.first_roi_name_label, self.first_roi_name_dropdown_list)

        # Create a label for denoting the operation
        self.operation_name_label = QLabel()
        self.operation_name_label.setObjectName("OperationNameLabel")
        self.operation_name_dropdown_list = QComboBox()
        # Create an dropdown list for operation name
        self.operation_name_dropdown_list.setObjectName(
            "OperationNameDropdownList")
        self.operation_name_dropdown_list.setSizePolicy(
            QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.operation_name_dropdown_list.resize(
            self.operation_name_dropdown_list.sizeHint().width(),
            self.operation_name_dropdown_list.sizeHint().height())
        self.operation_name_dropdown_list.activated.connect(
            self.operation_changed)
        self.manipulate_roi_window_input_container_box.addRow(
            self.operation_name_label, self.operation_name_dropdown_list)

        # Create a label for denoting the second ROI name
        self.second_roi_name_label = QLabel()
        self.second_roi_name_label.setObjectName("SecondROINameLabel")
        self.second_roi_name_label.setVisible(False)
        self.second_roi_name_dropdown_list = QComboBox()
        # Create an dropdown list for ROI name
        self.second_roi_name_dropdown_list.setObjectName(
            "SecondROINameDropdownList")
        self.second_roi_name_dropdown_list.setSizePolicy(
            QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.second_roi_name_dropdown_list.resize(
            self.second_roi_name_dropdown_list.sizeHint().width(),
            self.second_roi_name_dropdown_list.sizeHint().height())
        self.second_roi_name_dropdown_list.setVisible(False)
        self.second_roi_name_dropdown_list.activated.connect(
            self.update_selected_rois)
        self.manipulate_roi_window_input_container_box.addRow(
            self.second_roi_name_label, self.second_roi_name_dropdown_list)

        # Create a label for denoting the margin
        self.margin_label = QLabel()
        self.margin_label.setObjectName("MarginLabel")
        self.margin_label.setVisible(False)
        # Create input for the new ROI name
        self.margin_line_edit = QLineEdit()
        self.margin_line_edit.setObjectName("MarginInput")
        self.margin_line_edit.setSizePolicy(QSizePolicy.MinimumExpanding,
                                            QSizePolicy.Minimum)
        self.margin_line_edit.resize(self.margin_line_edit.sizeHint().width(),
                                     self.margin_line_edit.sizeHint().height())
        self.margin_line_edit.setVisible(False)
        self.margin_line_edit.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[.]?[0-9]*$")))
        self.manipulate_roi_window_input_container_box.addRow(
            self.margin_label, self.margin_line_edit)

        # Create a label for denoting the new ROI name
        self.new_roi_name_label = QLabel()
        self.new_roi_name_label.setObjectName("NewROINameLabel")
        # Create input for the new ROI name
        self.new_roi_name_line_edit = QLineEdit()
        self.new_roi_name_line_edit.setObjectName("NewROINameInput")
        self.new_roi_name_line_edit.setSizePolicy(QSizePolicy.MinimumExpanding,
                                                  QSizePolicy.Minimum)
        self.new_roi_name_line_edit.resize(
            self.new_roi_name_line_edit.sizeHint().width(),
            self.new_roi_name_line_edit.sizeHint().height())
        self.manipulate_roi_window_input_container_box.addRow(
            self.new_roi_name_label, self.new_roi_name_line_edit)

        # Create a spacer between inputs and buttons
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        spacer.setFocusPolicy(Qt.NoFocus)
        self.manipulate_roi_window_input_container_box.addRow(spacer)

        # Create a warning message when missing inputs
        self.warning_message = QWidget()
        self.warning_message.setContentsMargins(8, 5, 8, 5)
        warning_message_layout = QHBoxLayout()
        warning_message_layout.setAlignment(QtCore.Qt.AlignLeft
                                            | QtCore.Qt.AlignLeft)

        warning_message_icon = QLabel()
        warning_message_icon.setPixmap(
            QtGui.QPixmap(
                resource_path("res/images/btn-icons/alert_icon.png")))
        warning_message_layout.addWidget(warning_message_icon)

        self.warning_message_text = QLabel()
        self.warning_message_text.setStyleSheet("color: red")
        warning_message_layout.addWidget(self.warning_message_text)
        self.warning_message.setLayout(warning_message_layout)
        self.warning_message.setVisible(False)
        self.manipulate_roi_window_input_container_box.addRow(
            self.warning_message)

        # Create a draw button
        self.manipulate_roi_window_instance_draw_button = QPushButton()
        self.manipulate_roi_window_instance_draw_button.setObjectName(
            "ManipulateRoiWindowInstanceDrawButton")
        self.manipulate_roi_window_instance_draw_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
        self.manipulate_roi_window_instance_draw_button.resize(
            self.manipulate_roi_window_instance_draw_button.sizeHint().width(),
            self.manipulate_roi_window_instance_draw_button.sizeHint().height(
            ))
        self.manipulate_roi_window_instance_draw_button.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.manipulate_roi_window_instance_draw_button.clicked.connect(
            self.onDrawButtonClicked)
        self.manipulate_roi_window_input_container_box.addRow(
            self.manipulate_roi_window_instance_draw_button)

        # Create a horizontal box for saving and cancel the drawing
        self.manipulate_roi_window_cancel_save_box = QHBoxLayout()
        self.manipulate_roi_window_cancel_save_box.setObjectName(
            "ManipulateRoiWindowCancelSaveBox")
        # Create an exit button to cancel the drawing
        # Add a button to go back/exit from the application
        self.manipulate_roi_window_instance_cancel_button = QPushButton()
        self.manipulate_roi_window_instance_cancel_button.setObjectName(
            "ManipulateRoiWindowInstanceCancelButton")
        self.manipulate_roi_window_instance_cancel_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
        self.manipulate_roi_window_instance_cancel_button.resize(
            self.manipulate_roi_window_instance_cancel_button.sizeHint().width(
            ),
            self.manipulate_roi_window_instance_cancel_button.sizeHint().
            height())
        self.manipulate_roi_window_instance_cancel_button.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.manipulate_roi_window_instance_cancel_button.clicked.connect(
            self.onCancelButtonClicked)
        self.manipulate_roi_window_instance_cancel_button.setProperty(
            "QPushButtonClass", "fail-button")
        icon_cancel = QtGui.QIcon()
        icon_cancel.addPixmap(
            QtGui.QPixmap(
                resource_path('res/images/btn-icons/cancel_icon.png')))
        self.manipulate_roi_window_instance_cancel_button.setIcon(icon_cancel)
        self.manipulate_roi_window_cancel_save_box.addWidget(
            self.manipulate_roi_window_instance_cancel_button)
        # Create a save button to save all the changes
        self.manipulate_roi_window_instance_save_button = QPushButton()
        self.manipulate_roi_window_instance_save_button.setObjectName(
            "ManipulateRoiWindowInstanceSaveButton")
        self.manipulate_roi_window_instance_save_button.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
        self.manipulate_roi_window_instance_save_button.resize(
            self.manipulate_roi_window_instance_save_button.sizeHint().width(),
            self.manipulate_roi_window_instance_save_button.sizeHint().height(
            ))
        self.manipulate_roi_window_instance_save_button.setProperty(
            "QPushButtonClass", "success-button")
        icon_save = QtGui.QIcon()
        icon_save.addPixmap(
            QtGui.QPixmap(resource_path('res/images/btn-icons/save_icon.png')))
        self.manipulate_roi_window_instance_save_button.setIcon(icon_save)
        self.manipulate_roi_window_instance_save_button.clicked.connect(
            self.onSaveClicked)
        self.manipulate_roi_window_cancel_save_box.addWidget(
            self.manipulate_roi_window_instance_save_button)
        self.manipulate_roi_window_input_container_box.addRow(
            self.manipulate_roi_window_cancel_save_box)

        # Creating a horizontal box to hold the ROI view and the preview
        self.manipulate_roi_window_instance_view_box = QHBoxLayout()
        self.manipulate_roi_window_instance_view_box.setObjectName(
            "ManipulateRoiWindowInstanceViewBoxes")
        # Font for the ROI view and preview's labels
        font = QFont()
        font.setBold(True)
        font.setPixelSize(20)
        # Creating the ROI view
        self.ROI_view_box_layout = QVBoxLayout()
        self.ROI_view_box_label = QLabel()
        self.ROI_view_box_label.setFont(font)
        self.ROI_view_box_label.setAlignment(Qt.AlignHCenter)
        self.ROI_view_box_layout.addWidget(self.ROI_view_box_label)
        self.ROI_view_box_layout.addWidget(self.dicom_view)
        self.ROI_view_box_widget = QWidget()
        self.ROI_view_box_widget.setLayout(self.ROI_view_box_layout)
        # Creating the preview
        self.preview_box_layout = QVBoxLayout()
        self.preview_box_label = QLabel()
        self.preview_box_label.setFont(font)
        self.preview_box_label.setAlignment(Qt.AlignHCenter)
        self.preview_box_layout.addWidget(self.preview_box_label)
        self.preview_box_layout.addWidget(self.dicom_preview)
        self.preview_box_widget = QWidget()
        self.preview_box_widget.setLayout(self.preview_box_layout)

        # Add View and Slider into horizontal box
        self.manipulate_roi_window_instance_view_box.addWidget(
            self.ROI_view_box_widget)
        self.manipulate_roi_window_instance_view_box.addWidget(
            self.preview_box_widget)
        # Create a widget to hold the image slice box
        self.manipulate_roi_window_instance_view_widget = QWidget()
        self.manipulate_roi_window_instance_view_widget.setObjectName(
            "ManipulateRoiWindowInstanceActionWidget")
        self.manipulate_roi_window_instance_view_widget.setLayout(
            self.manipulate_roi_window_instance_view_box)

        # Create a horizontal box for containing the input fields and the
        # viewports
        self.manipulate_roi_window_main_box = QHBoxLayout()
        self.manipulate_roi_window_main_box.setObjectName(
            "ManipulateRoiWindowMainBox")
        self.manipulate_roi_window_main_box.addLayout(
            self.manipulate_roi_window_input_container_box, 1)
        self.manipulate_roi_window_main_box.addWidget(
            self.manipulate_roi_window_instance_view_widget, 11)

        # Create a new central widget to hold the horizontal box layout
        self.manipulate_roi_window_instance_central_widget = QWidget()
        self.manipulate_roi_window_instance_central_widget.setObjectName(
            "ManipulateRoiWindowInstanceCentralWidget")
        self.manipulate_roi_window_instance_central_widget.setLayout(
            self.manipulate_roi_window_main_box)

        self.retranslate_ui(self.manipulate_roi_window_instance)
        self.manipulate_roi_window_instance.setStyleSheet(stylesheet)
        self.manipulate_roi_window_instance.setCentralWidget(
            self.manipulate_roi_window_instance_central_widget)
        QtCore.QMetaObject.connectSlotsByName(
            self.manipulate_roi_window_instance)

    def dicom_view_slider_value_changed(self):
        """
        Display selected ROIs in dropbox when moving to another image slice
        """
        self.display_selected_roi()
        if self.dicom_preview.slider.value() != self.dicom_view.slider.value():
            self.dicom_preview.slider.setValue(self.dicom_view.slider.value())

    def dicom_preview_slider_value_changed(self):
        """
        Display generated ROI when moving to another image slice
        """
        self.draw_roi()
        if self.dicom_preview.slider.value() != self.dicom_view.slider.value():
            self.dicom_view.slider.setValue(self.dicom_preview.slider.value())

    def onCancelButtonClicked(self):
        """
        This function is used for canceling the drawing
        """
        self.close()

    def onDrawButtonClicked(self):
        """
        Function triggered when the Draw button is pressed from the menu.
        """
        # Hide warning message
        self.warning_message.setVisible(False)

        # Check inputs
        selected_operation = self.operation_name_dropdown_list.currentText()
        roi_1 = self.first_roi_name_dropdown_list.currentText()
        roi_2 = self.second_roi_name_dropdown_list.currentText()
        new_roi_name = self.new_roi_name_line_edit.text()

        # Check the selected inputs and execute the operations
        if roi_1 != "" and new_roi_name != "" and \
                self.margin_line_edit.text() != "" and \
                selected_operation in self.single_roi_operation_names:
            # Single ROI operations
            dict_rois_contours = ROI.get_roi_contour_pixel(
                self.patient_dict_container.get("raw_contour"), [roi_1],
                self.patient_dict_container.get("pixluts"))
            roi_geometry = ROI.roi_to_geometry(dict_rois_contours[roi_1])
            margin = float(self.margin_line_edit.text())

            if selected_operation == self.single_roi_operation_names[0]:
                new_geometry = ROI.scale_roi(roi_geometry, margin)
            elif selected_operation == self.single_roi_operation_names[1]:
                new_geometry = ROI.scale_roi(roi_geometry, -margin)
            elif selected_operation == self.single_roi_operation_names[2]:
                new_geometry = ROI.rind_roi(roi_geometry, -margin)
            else:
                new_geometry = ROI.rind_roi(roi_geometry, margin)
            self.new_ROI_contours = ROI.geometry_to_roi(new_geometry)

            self.draw_roi()
            return True
        elif roi_1 != "" and roi_2 != "" and new_roi_name != "" and \
                selected_operation in self.multiple_roi_operation_names:
            # Multiple ROI operations
            dict_rois_contours = ROI.get_roi_contour_pixel(
                self.patient_dict_container.get("raw_contour"), [roi_1, roi_2],
                self.patient_dict_container.get("pixluts"))
            roi_1_geometry = ROI.roi_to_geometry(dict_rois_contours[roi_1])
            roi_2_geometry = ROI.roi_to_geometry(dict_rois_contours[roi_2])

            # Execute the selected operation
            new_geometry = ROI.manipulate_rois(roi_1_geometry, roi_2_geometry,
                                               selected_operation.upper())
            self.new_ROI_contours = ROI.geometry_to_roi(new_geometry)

            self.draw_roi()
            return True

        self.warning_message_text.setText("Not all values are specified.")
        self.warning_message.setVisible(True)
        return False

    def onSaveClicked(self):
        """ Save the new ROI """
        # Get the name of the new ROI
        new_roi_name = self.new_roi_name_line_edit.text()

        # If the new ROI hasn't been drawn, draw the new ROI. Then if the new
        # ROI is drawn successfully, proceed to save the new ROI.
        if self.new_ROI_contours is None:
            if not self.onDrawButtonClicked():
                return

        # Get a dict to convert SOPInstanceUID to slice id
        slice_ids_dict = get_dict_slice_to_uid(PatientDictContainer())

        # Transform new_ROI_contours to a list of roi information
        rois_to_save = {}

        for uid, contour_sequence in self.new_ROI_contours.items():
            slider_id = slice_ids_dict[uid]
            location = self.patient_dict_container.filepaths[slider_id]
            ds = pydicom.dcmread(location)
            slice_info = {'coords': contour_sequence, 'ds': ds}
            rois_to_save[slider_id] = slice_info

        roi_list = ROI.convert_hull_list_to_contours_data(
            rois_to_save, self.patient_dict_container)

        connectSaveROIProgress(self, roi_list, self.dataset_rtss, new_roi_name,
                               self.roi_saved)

    def draw_roi(self):
        """ Draw the new ROI """
        # Get the new ROI's name
        new_roi_name = self.new_roi_name_line_edit.text()

        # Check if the new ROI contour is None
        if self.new_ROI_contours is None:
            return

        # Get the info required to draw the new ROI
        slider_id = self.dicom_preview.slider.value()
        curr_slice = self.patient_dict_container.get("dict_uid")[slider_id]

        # Calculate the new ROI's polygon
        dict_ROI_contours = {}
        dict_ROI_contours[new_roi_name] = self.new_ROI_contours
        polygons = ROI.calc_roi_polygon(new_roi_name, curr_slice,
                                        dict_ROI_contours)

        # Set the new ROI color
        color = QtGui.QColor()
        color.setRgb(90, 250, 175, 200)
        pen_color = QtGui.QColor(color.red(), color.green(), color.blue())
        pen = QtGui.QPen(pen_color)
        pen.setStyle(QtCore.Qt.PenStyle(1))
        pen.setWidthF(2.0)

        # Draw the new ROI
        self.dicom_preview.update_view()
        for i in range(len(polygons)):
            self.dicom_preview.scene.addPolygon(polygons[i], pen,
                                                QtGui.QBrush(color))

    def update_selected_rois(self):
        """ Get the names of selected ROIs """
        # Hide warning message
        self.warning_message.setVisible(False)

        self.roi_names = []
        if self.first_roi_name_dropdown_list.currentText() != "":
            self.roi_names.append(
                self.first_roi_name_dropdown_list.currentText())
        if self.second_roi_name_dropdown_list.currentText() != "" and \
                self.second_roi_name_dropdown_list.isVisible():
            self.roi_names.append(
                self.second_roi_name_dropdown_list.currentText())

        self.dict_rois_contours_axial = ROI.get_roi_contour_pixel(
            self.patient_dict_container.get("raw_contour"), self.roi_names,
            self.patient_dict_container.get("pixluts"))

        self.display_selected_roi()

    def display_selected_roi(self):
        """ Display selected ROIs """
        # Get the info required to display the selected ROIs
        slider_id = self.dicom_view.slider.value()
        curr_slice = self.patient_dict_container.get("dict_uid")[slider_id]
        self.rois = self.patient_dict_container.get("rois")

        # Display the selected ROIs
        self.dicom_view.update_view()
        for roi_id, roi_dict in self.rois.items():
            roi_name = roi_dict['name']
            if roi_name in self.roi_names:
                polygons = ROI.calc_roi_polygon(roi_name, curr_slice,
                                                self.dict_rois_contours_axial)
                self.dicom_view.draw_roi_polygons(roi_id, polygons,
                                                  self.roi_color)

    def operation_changed(self):
        """ Change the form when users select different operations """
        # Hide warning message
        self.warning_message.setVisible(False)

        selected_operation = self.operation_name_dropdown_list.currentText()
        if selected_operation in self.single_roi_operation_names:
            self.second_roi_name_label.setVisible(False)
            self.second_roi_name_dropdown_list.setVisible(False)
            self.margin_label.setVisible(True)
            self.margin_line_edit.setVisible(True)
            self.update_selected_rois()
        else:
            self.second_roi_name_label.setVisible(True)
            self.second_roi_name_dropdown_list.setVisible(True)
            self.margin_label.setVisible(False)
            self.margin_line_edit.setVisible(False)
            self.update_selected_rois()

    def roi_saved(self, new_rtss):
        """ Create a new ROI in Structure Tab and notify user """
        new_roi_name = self.new_roi_name_line_edit.text()
        self.signal_roi_manipulated.emit((new_rtss, {"draw": new_roi_name}))
        QMessageBox.about(self.manipulate_roi_window_instance, "Saved",
                          "New contour successfully created!")
        self.close()
Пример #13
0
class Dialog_Dose(QDialog):
    """
    This class creates the user input dialog for when Modifying or
    Adding a isodose level option for ISO2ROI functionality.
    """
    def __init__(self, dose, notes):
        super(Dialog_Dose, self).__init__()

        # Class variables
        self.dose = dose
        self.notes = notes
        self.setWindowIcon(
            QtGui.QIcon("res/images/btn-icons/onkodicom_icon.png"))
        buttonBox = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self)
        self.iso_dose = QLineEdit()
        self.iso_dose.setText(self.dose)
        self.iso_unit = QComboBox()
        self.iso_unit.addItems(["cGy", "%"])
        self.iso_notes = QLineEdit()
        self.iso_notes.setText(self.notes)

        # Input dialog layout
        layout = QFormLayout(self)
        layout.addRow(QLabel("Isodose Level:"), self.iso_dose)
        layout.addRow(QLabel("Unit:"), self.iso_unit)
        layout.addRow(QLabel("Notes:"), self.iso_notes)
        layout.addWidget(buttonBox)
        buttonBox.accepted.connect(self.accepting)
        buttonBox.rejected.connect(self.reject)
        self.setWindowTitle("Isodose Levels")

    def getInputs(self):
        """
        Return the inputs from the dialog box.
        :return: tuple of dialog inputs - (isodose level, isodose unit,
                 isodose name, isodose notes)
        """
        # Get appropriate name for unit selected
        if self.iso_unit.currentText() == "%":
            iso_name = str('ISOp_' + self.iso_dose.text())
        else:
            iso_name = str('ISO' + self.iso_dose.text())

        # Return inputs from dialog box
        return (self.iso_dose.text(), self.iso_unit.currentText(), iso_name,
                self.iso_notes.text())

    def accepting(self):
        """
        Process the event when the user clicks "ok" in the dialog box.
        """
        # Make sure the isodose level is a number
        if (self.iso_dose.text() != ''):
            if re.match(r'^\d+$', self.iso_dose.text()):
                self.accept()
            else:
                buttonReply = QMessageBox.warning(
                    self, "Error Message",
                    "The Isodose level should to be a number!", QMessageBox.Ok)
                if buttonReply == QMessageBox.Ok:
                    pass
        # Make sure the isodose level is not blank
        else:
            buttonReply = QMessageBox.warning(
                self, "Error Message",
                "The Isodose field should not be empty!", QMessageBox.Ok)
            if buttonReply == QMessageBox.Ok:
                pass
Пример #14
0
class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.init_ui()

        self.combobox.currentTextChanged.connect(self.slot_combo_textchanged)
        self.btn_open_conn.clicked.connect(self.slot_conn_clicked)
        self.btn_close_conn.clicked.connect(self.slot_conn_close)
        self.btn_status.clicked.connect(self.slot_send_status_packet)
        self.btn_head.clicked.connect(self.slot_send_head_packet)
        self.btn_motion.clicked.connect(self.slof_send_motion_packet)

    def slot_conn_close(self):
        #TODO 关闭其他窗口
        self.fd.close()
        self.set_send_btn_statu(False)

    def slot_send_status_packet(self):
        statuswidget = StatusWidget(self.fd)
        statuswidget.show()

    def slot_send_head_packet(self):
        headwidget = HeadWidget(self.fd)
        headwidget.show()

    def slof_send_motion_packet(self):
        motionwidget = MotionWidget(self.fd)
        motionwidget.show()
        pass

    def init_ui(self):
        self.tuple_method = ("Connect to Server", "Connect to /dev")
        self.combobox = QComboBox()
        self.combobox.addItems(self.tuple_method)
        self.addr_edit = QLineEdit()
        self.port_edit = QLineEdit()
        self.btn_open_conn = QPushButton("Connect/Open")
        self.btn_close_conn = QPushButton("Close Conn")
        self.fd = None
        self.method_layout = QVBoxLayout()
        self.method_layout.addWidget(self.combobox)
        self.method_layout.addWidget(self.addr_edit)
        self.method_layout.addWidget(self.port_edit)
        self.method_layout.addWidget(self.btn_open_conn)
        self.method_layout.addWidget(self.btn_close_conn)
        self.btn_status = QPushButton("Send Status Packet")
        self.btn_head = QPushButton("Send Head Packet")
        self.btn_motion = QPushButton("Send Motion Packet")
        self.packet_layout = QVBoxLayout()
        self.packet_layout.addWidget(self.btn_status)
        self.packet_layout.addWidget(self.btn_head)
        self.packet_layout.addWidget(self.btn_motion)
        self.main_layout = QVBoxLayout()
        self.main_layout.addLayout(self.method_layout)
        self.main_layout.addLayout(self.packet_layout)
        self.setLayout(self.main_layout)
        self.set_send_btn_statu(False)

    def set_send_btn_statu(self, statu):
        self.btn_motion.setEnabled(statu)
        self.btn_head.setEnabled(statu)
        self.btn_status.setEnabled(statu)
        self.btn_close_conn.setEnabled(statu)
        self.btn_open_conn.setEnabled(True if statu == False else False)

    def slot_combo_textchanged(self, current_text):
        if current_text == "Connect to /dev":
            self.port_edit.setVisible(False)
        else:
            self.port_edit.setVisible(True)

    def slot_conn_clicked(self):
        # try:
        if self.combobox.currentText() == "Connect to /dev":
            self.fd = open(self.addr_edit.text(), "wb")

        elif self.combobox.currentText() == "Connect to Server":
            self.fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.fd.connect(("127.0.0.1", int(self.port_edit.text())))
        # except :
        #     pass

        # TODO except

        QMessageBox.information(self, "success", "connected")
        self.set_send_btn_statu(True)
Пример #15
0
class ImageFusionOptions(object):
    """
    UI class that can be used by the AddOnOptions Class to allow the user
    customise their input parameters for auto-registration.
    """
    def __init__(self, window_options):
        self.auto_image_fusion_frame = QtWidgets.QFrame()
        self.window = window_options
        self.moving_image = None
        self.fixed_image = None
        self.dict = {}

        self.setupUi()
        self.create_view()
        self.get_patients_info()

    def set_value(self, key, value):
        """
        Stores values into a dictionary to the corresponding key.
        Parameters
        ----------
        key (Any):

        value (Any):
        """
        self.dict[key] = value

    def create_view(self):
        """
        Create a table to hold all the ROI creation by isodose entries.
        """
        self.auto_image_fusion_frame.setVisible(False)

    def setVisible(self, visibility):
        """
        Custom setVisible function that will set the visibility of the GUI.

        Args:
            visibility (bool): flag for setting the GUI to visible
        """
        self.auto_image_fusion_frame.setVisible(visibility)

    def setupUi(self):
        """
        Constructs the GUI and sets the limit of each input field.
        """
        # Create a vertical Widget to hold Vertical Layout
        self.vertical_layout_widget = QWidget()
        self.vertical_layout = QtWidgets.QVBoxLayout()

        # Create a Widget and set layout to a GridLayout
        self.gridLayoutWidget = QWidget()
        self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
        self.gridLayout.setSizeConstraint(QLayout.SetDefaultConstraint)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setVerticalSpacing(0)

        # Create horizontal spacer in the middle of the grid
        hspacer = QtWidgets.QSpacerItem(QtWidgets.QSizePolicy.Expanding,
                                        QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(hspacer, 0, 5, 16, 1)

        # Labels
        self.fixed_image_label = QLabel("Fixed Image: ")
        fixed_image_sizePolicy = QSizePolicy(QSizePolicy.Maximum,
                                             QSizePolicy.Preferred)
        fixed_image_sizePolicy.setHorizontalStretch(0)
        fixed_image_sizePolicy.setVerticalStretch(0)
        fixed_image_sizePolicy.setHeightForWidth(
            self.fixed_image_label.sizePolicy().hasHeightForWidth())

        self.fixed_image_label.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                            | Qt.AlignVCenter)

        self.fixed_image_placeholder \
            = QLabel("This is a placeholder for fixed image")
        self.fixed_image_placeholder.setWordWrap(False)
        self.fixed_image_placeholder.setText(str(self.fixed_image))
        self.fixed_image_placeholder.setMaximumSize(200, 50)

        self.moving_image_label = QLabel("Moving Image: ")
        moving_image_label_sizePolicy = QSizePolicy(QSizePolicy.Maximum,
                                                    QSizePolicy.Maximum)
        moving_image_label_sizePolicy.setHorizontalStretch(0)
        moving_image_label_sizePolicy.setVerticalStretch(0)
        moving_image_label_sizePolicy.setHeightForWidth(
            self.moving_image_label.sizePolicy().hasHeightForWidth())
        self.moving_image_label.setSizePolicy(moving_image_label_sizePolicy)

        self.moving_image_placeholder = QLabel("This is a placeholder")
        self.moving_image_placeholder.setWordWrap(False)
        self.moving_image_placeholder.setText(str(self.moving_image))
        self.moving_image_placeholder.setMaximumSize(200, 50)

        self.gridLayout.addWidget(self.fixed_image_label, 0, 0)
        self.gridLayout.addWidget(self.fixed_image_placeholder, 0, 1)
        self.gridLayout.addWidget(self.moving_image_label, 0, 2)
        self.gridLayout.addWidget(self.moving_image_placeholder, 0, 3)

        # Default Numbers
        self.default_numbers_label = QLabel("Default Numbers")
        self.default_numbers_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing
                                                | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.default_numbers_label, 1, 0)

        self.default_number_spinBox = QSpinBox(self.gridLayoutWidget)
        self.default_number_spinBox.setRange(-2147483648, 2147483647)
        self.default_number_spinBox.setSizePolicy(QSizePolicy.Minimum,
                                                  QSizePolicy.Fixed)
        self.default_number_spinBox.setToolTip(
            "Default voxel value. Defaults to -1000.")
        self.gridLayout.addWidget(self.default_number_spinBox, 1, 1)

        # Final Interp
        self.interp_order_label = QLabel("Final Interp")
        self.interp_order_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing
                                             | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.interp_order_label, 2, 0)

        self.interp_order_spinbox = QSpinBox(self.gridLayoutWidget)
        self.interp_order_spinbox.setSizePolicy(QSizePolicy.Minimum,
                                                QSizePolicy.Fixed)
        self.interp_order_spinbox.setToolTip("The final interpolation order.")
        self.gridLayout.addWidget(self.interp_order_spinbox, 2, 1)

        # Metric
        self.metric_label = QLabel("Metric")
        self.metric_label.setAlignment(QtCore.Qt.AlignLeft | Qt.AlignTrailing
                                       | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.metric_label, 3, 0)

        self.metric_comboBox = QComboBox()
        self.metric_comboBox.addItem("correlation")
        self.metric_comboBox.addItem("mean_squares")
        self.metric_comboBox.addItem("mattes_mi")
        self.metric_comboBox.addItem("joint_hist_mi")
        self.metric_comboBox.setToolTip(
            "The metric to be optimised during image registration.")
        self.gridLayout.addWidget(self.metric_comboBox, 3, 1)

        # Number of Iterations
        self.no_of_iterations_label = QLabel("Number of Iterations")
        self.no_of_iterations_label.setAlignment(Qt.AlignLeft
                                                 | Qt.AlignTrailing
                                                 | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.no_of_iterations_label, 4, 0)

        self.no_of_iterations_spinBox = QSpinBox(self.gridLayoutWidget)
        self.no_of_iterations_spinBox.setSizePolicy(QSizePolicy.Minimum,
                                                    QSizePolicy.Fixed)
        self.no_of_iterations_spinBox.setRange(0, 100)
        self.no_of_iterations_spinBox.setToolTip(
            "Number of iterations in each multi-resolution step.")
        self.gridLayout.addWidget(self.no_of_iterations_spinBox, 4, 1)

        # Shrink Factor
        self.shrink_factor_label = QLabel("Shrink Factor")
        self.shrink_factor_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing
                                              | Qt.AlignVCenter)

        self.gridLayout.addWidget(self.shrink_factor_label, 5, 0)

        self.shrink_factor_qLineEdit = QLineEdit()
        self.shrink_factor_qLineEdit.resize(
            self.shrink_factor_qLineEdit.sizeHint().width(),
            self.shrink_factor_qLineEdit.sizeHint().height())

        self.shrink_factor_qLineEdit.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[,]?[0-9]*[,]?[0-9]")))

        self.shrink_factor_qLineEdit.setToolTip(
            "The multi-resolution downsampling factors. Can be up to three "
            "integer elements in an array. Example [8, 2, 1]")
        self.gridLayout.addWidget(self.shrink_factor_qLineEdit, 5, 1)

        # Optimiser
        self.optimiser_label = QLabel("Optimiser")
        self.optimiser_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing
                                          | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.optimiser_label, 1, 2)

        self.optimiser_comboBox = QComboBox(self.gridLayoutWidget)
        self.optimiser_comboBox.addItem("lbfgsb")
        self.optimiser_comboBox.addItem("gradient_descent")
        self.optimiser_comboBox.addItem("gradient_descent_line_search")
        self.optimiser_comboBox.setToolTip(
            "The optimiser algorithm used for image registration.")
        self.gridLayout.addWidget(self.optimiser_comboBox, 1, 3)

        # Reg Method
        self.reg_method_label = QLabel("Reg Method")
        self.reg_method_label.setAlignment(QtCore.Qt.AlignLeft
                                           | Qt.AlignTrailing
                                           | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.reg_method_label, 2, 2)

        self.reg_method_comboBox = QComboBox()
        self.reg_method_comboBox.addItem("translation")
        self.reg_method_comboBox.addItem("rigid")
        self.reg_method_comboBox.addItem("similarity")
        self.reg_method_comboBox.addItem("affine")
        self.reg_method_comboBox.addItem("scaleversor")
        self.reg_method_comboBox.addItem("scaleskewversor")
        self.reg_method_comboBox.setToolTip(
            "The linear transformation model to be used for image "
            "registration.")
        self.gridLayout.addWidget(self.reg_method_comboBox, 2, 3)

        # Sampling Rate
        self.sampling_rate_label = QLabel("Sampling Rate")
        self.sampling_rate_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing
                                              | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.sampling_rate_label, 3, 2)

        self.sampling_rate_spinBox = QDoubleSpinBox(self.gridLayoutWidget)
        self.sampling_rate_spinBox.setMinimum(0)
        self.sampling_rate_spinBox.setMaximum(1)
        self.sampling_rate_spinBox.setSingleStep(0.01)
        self.sampling_rate_spinBox.setSizePolicy(QSizePolicy.Minimum,
                                                 QSizePolicy.Fixed)
        self.sampling_rate_spinBox.setToolTip("The fraction of voxels sampled "
                                              "during each iteration.")
        self.gridLayout.addWidget(self.sampling_rate_spinBox, 3, 3)

        # Smooth Sigmas
        self.smooth_sigma_label = QLabel("Smooth Sigma")
        self.smooth_sigma_label.setAlignment(Qt.AlignLeft | Qt.AlignTrailing
                                             | Qt.AlignVCenter)
        self.gridLayout.addWidget(self.smooth_sigma_label, 4, 2)

        self.smooth_sigmas_qLineEdit = QLineEdit()
        self.smooth_sigmas_qLineEdit.resize(
            self.smooth_sigmas_qLineEdit.sizeHint().width(),
            self.smooth_sigmas_qLineEdit.sizeHint().height())
        self.smooth_sigmas_qLineEdit.setValidator(
            QRegularExpressionValidator(
                QRegularExpression("^[0-9]*[,]?[0-9]*[,]?[0-9]")))
        self.smooth_sigmas_qLineEdit.setToolTip(
            "The multi-resolution smoothing kernal scale (Gaussian). Can be "
            "up to three integer elements in an array. Example [4, 2, 1]")
        self.gridLayout.addWidget(self.smooth_sigmas_qLineEdit, 4, 3)

        # Label to hold warning labels.
        self.warning_label = QLabel()

        # Button for fast mode
        self.fast_mode_button = QtWidgets.QPushButton("Fast Mode")
        self.fast_mode_button.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.fast_mode_button.clicked.connect(self.set_fast_mode)

        # Add Widgets to the vertical layout
        self.vertical_layout.addWidget(self.fast_mode_button)
        self.vertical_layout.addWidget(self.gridLayoutWidget)
        self.vertical_layout.addWidget(self.warning_label)

        # Set layout of frame to the gridlayout widget
        self.auto_image_fusion_frame.setLayout(self.vertical_layout)

    def set_gridLayout(self):
        """
        Set the UI based on the values taken from the JSON
        """
        msg = ""

        # If-Elif statements for setting the dict
        # this can only be done in if-else statements.
        if self.dict["reg_method"] == "translation":
            self.reg_method_comboBox.setCurrentIndex(0)
        elif self.dict["reg_method"] == "rigid":
            self.reg_method_comboBox.setCurrentIndex(1)
        elif self.dict["reg_method"] == "similarity":
            self.reg_method_comboBox.setCurrentIndex(2)
        elif self.dict["reg_method"] == "affine":
            self.reg_method_comboBox.setCurrentIndex(3)
        elif self.dict["reg_method"] == "scaleversor":
            self.reg_method_comboBox.setCurrentIndex(4)
        elif self.dict["reg_method"] == "scaleskewversor":
            self.reg_method_comboBox.setCurrentIndex(5)
        else:
            msg += 'There was an error setting the reg_method value.\n'
            self.warning_label.setText(msg)

        if self.dict["metric"] == "coorelation":
            self.metric_comboBox.setCurrentIndex(0)
        elif self.dict["metric"] == "mean_squares":
            self.metric_comboBox.setCurrentIndex(1)
        elif self.dict["metric"] == "mattes_mi":
            self.metric_comboBox.setCurrentIndex(2)
        elif self.dict["metric"] == "joint_hist_mi":
            self.metric_comboBox.setCurrentIndex(3)
        else:
            msg += 'There was an error setting the metric value.\n'
            self.warning_label.setText(msg)

        if self.dict["optimiser"] == "lbfgsb":
            self.optimiser_comboBox.setCurrentIndex(0)
        elif self.dict["optimiser"] == "gradient_descent":
            self.optimiser_comboBox.setCurrentIndex(1)
        elif self.dict["optimiser"] == "gradient_descent_line_search":
            self.optimiser_comboBox.setCurrentIndex(2)
        else:
            msg += 'There was an error setting the optimiser value.\n'
            self.warning_label.setText(msg)

        # Check if all elements in list are ints
        if all(isinstance(x, int) for x in self.dict["shrink_factors"]):
            # Shrink_factors is stored as a list in JSON convert the list into
            # a string.
            shrink_factor_list_json = ', '.join(
                str(e) for e in self.dict["shrink_factors"])
            self.shrink_factor_qLineEdit.setText(shrink_factor_list_json)
        else:
            msg += 'There was an error setting the Shrink Factors value.\n'
            self.warning_label.setText(msg)

        # Check if all elements in list are ints
        if all(isinstance(x, int) for x in self.dict["smooth_sigmas"]):
            # Since smooth_sigma is stored as a list in JSON convert the list
            # into a string.
            smooth_sigma_list_json = ', '.join(
                str(e) for e in self.dict["smooth_sigmas"])
            self.smooth_sigmas_qLineEdit.setText(smooth_sigma_list_json)
        else:
            msg += 'There was an error setting the Smooth Sigmas value.\n'
            self.warning_label.setText(msg)

        try:
            self.sampling_rate_spinBox.setValue(
                float(self.dict["sampling_rate"]))
        except ValueError:
            msg += 'There was an error setting the Sampling Rate value.\n'
            self.warning_label.setText(msg)

        try:
            self.interp_order_spinbox.setValue(int(self.dict["final_interp"]))
        except ValueError:
            msg += 'There was an error setting the Final Interp value.\n'
            self.warning_label.setText(msg)

        try:
            self.no_of_iterations_spinBox.setValue(
                int(self.dict["number_of_iterations"]))
        except ValueError:
            msg += 'There was an error setting the Number of iterations ' \
                   'value.\n'
            self.warning_label.setText(msg)

        try:
            self.default_number_spinBox.setValue(
                int(self.dict["default_value"]))
        except ValueError:
            msg += 'There was an error setting the Default Number'
            self.warning_label.setText(msg)

    def get_patients_info(self):
        """
        Retrieve the patient's study description of the fixed image
        and for the moving image (if it exists).
        """
        patient_dict_container = PatientDictContainer()
        if not patient_dict_container.is_empty():
            filename = patient_dict_container.filepaths[0]
            dicom_tree_slice = DicomTree(filename)
            dict_tree = dicom_tree_slice.dict
            try:
                self.fixed_image = dict_tree["Series Instance UID"][0]
            except:
                self.fixed_image = ""
                self.warning_label.setText(
                    'Couldn\'t find the series instance '
                    'UID for the Fixed Image.')

        moving_dict_container = MovingDictContainer()
        if not moving_dict_container.is_empty():
            filename = moving_dict_container.filepaths[0]
            dicom_tree_slice = DicomTree(filename)
            dict_tree = dicom_tree_slice.dict
            try:
                self.moving_image = dict_tree["Series Instance UID"][0]
            except:
                self.moving_image = ""
                self.warning_label.setText(
                    'Couldn\'t find the series instance '
                    'UID for the Moving Image.')

        if moving_dict_container.is_empty() and self.moving_image != "":
            self.moving_image = ""

        self.fixed_image_placeholder.setText(str(self.fixed_image))
        self.moving_image_placeholder.setText(str(self.moving_image))

    def get_values_from_UI(self):
        """
        Sets values from the GUI to the dict that will be used to store the
        relevant parameters to imageFusion.json.
        """
        self.dict["reg_method"] = str(self.reg_method_comboBox.currentText())
        self.dict["metric"] = str(self.metric_comboBox.currentText())
        self.dict["optimiser"] = str(self.optimiser_comboBox.currentText())

        a_string = self.shrink_factor_qLineEdit.text().split(",")
        a_int = list(map(int, a_string))
        self.dict["shrink_factors"] = a_int

        a_string = self.smooth_sigmas_qLineEdit.text().split(",")
        a_int = list(map(int, a_string))
        self.dict["smooth_sigmas"] = a_int

        self.dict["sampling_rate"] = self.sampling_rate_spinBox.value()
        self.dict["final_interp"] = self.interp_order_spinbox.value()
        self.dict[
            "number_of_iterations"] = self.no_of_iterations_spinBox.value()
        self.dict["default_value"] = self.default_number_spinBox.value()

        return self.dict

    def check_parameter(self):
        """
        Check the number of values of the smooth sigma and shrink factors of 
        that are parameters used for images fusion.
        """
        len_smooth_sigmas = len(self.dict["smooth_sigmas"])
        len_shrink_factor = len(self.dict["shrink_factors"])
        if len_smooth_sigmas != len_shrink_factor:
            raise ValueError

    def set_fast_mode(self):
        """These settings are customised to be fast for images fusion."""
        self.reg_method_comboBox.setCurrentIndex(1)
        self.metric_comboBox.setCurrentIndex(1)
        self.optimiser_comboBox.setCurrentIndex(1)
        self.shrink_factor_qLineEdit.setText("8")
        self.smooth_sigmas_qLineEdit.setText("10")
        self.sampling_rate_spinBox.setValue(0.25)
        self.interp_order_spinbox.setValue(2)
        self.no_of_iterations_spinBox.setValue(50)
        self.default_number_spinBox.setValue(-1000)
Пример #16
0
class ImageManipulation(QWidget):
    def __init__(self):
        super().__init__()

        # Declare Widgets
        self.edit_label = QLabel('Change your image')

        # set up list and combo box option
        self.my_list = ["Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia", "Negative", "Grayscale", "None"]
        self.my_combo_box = QComboBox()
        self.my_combo_box.addItems(self.my_list)

        self.edit_btn = QPushButton("Edit")
        self.cancel_btn = QPushButton("Back")

        # Create U.I. Layout
        vbox = QVBoxLayout()
        vbox.addWidget(self.edit_label)
        vbox.addWidget(self.my_combo_box)
        vbox.addWidget(self.edit_btn)
        vbox.addWidget(self.cancel_btn)
        self.setLayout(vbox) # apply layout to this class

        # when button is clicked send lineedit and combo box info to on_submit
        self.edit_btn.clicked.connect(self.on_edit)
        self.cancel_btn.clicked.connect(self.on_back)

    @Slot()
    def on_edit(self):

        # set up im_edit as which filter the user chose
        im_edit = self.my_combo_box.currentText()

        ##TODO change to correct image
        input_image = Image.open("image.png")
        input_pixels = input_image.load()

        output_image = Image.new("RGB", input_image.size)
        draw = ImageDraw.Draw(output_image)

        # Options are: ["Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia", "Negative", "Grayscale", "None"]
        if (im_edit == "Luminosity"):
            luminosity = 80

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b, a = input_pixels[x, y]
                    r = int(r + luminosity)
                    g = int(g + luminosity)
                    b = int(b + luminosity)
                    draw.point((x, y), (r, g, b))

            #output_image.save("output.png")
            output_image.show()

        elif (im_edit == "Contrast"):
            # Find minimum and maximum luminosity
            imin = 255
            imax = 0
            for x in range(input_image.width):
                for y in range(input_image.height):
                    r, g, b, a = input_pixels[x, y]
                    i = (r + g + b) / 3
                    imin = min(imin, i)
                    imax = max(imax, i)

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b, a = input_pixels[x, y]
                    # Current luminosity
                    i = (r + g + b) / 3
                    # New luminosity
                    ip = 255 * (i - imin) / (imax - imin)
                    r = int(r * ip / i)
                    g = int(g * ip / i)
                    b = int(b * ip / i)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        elif (im_edit == "Colorize"):
            # Square distance between 2 colors
            def distance2(color1, color2):
                r1, g1, b1 = color1
                r2, g2, b2, a2 = color2
                return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2

            color_to_change = (0, 0, 255)
            threshold = 220

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b, a = input_pixels[x, y]
                    if distance2(color_to_change, input_pixels[x, y]) < threshold ** 2:
                        r = int(r * .5)
                        g = int(g * 1.25)
                        b = int(b * .5)
                    draw.point((x, y), (r, g, b))

            #output_image.save("output.png")
            output_image.show()
        elif (im_edit == "Sepia"):
            def sepia(pixel):
                if pixel[0] < 63:
                    r,g,b = int(pixel[0]*1.1), pixel[1], int(pixel[2]*.9)
                elif pixel[0]>62 and pixel[0]<192:
                    r,g,b = int(pixel[0]*1.15), pixel[1], int(pixel[2]*.85)
                else:
                    r = int(pixel[0]*1.08)
                    if r>255: r=255
                    g,b = pixel[1], pixel[2]//2  
                return r,g,b
            sepia_list = map(sepia, input_image.getdata())
            output_image.putdata(list(sepia_list))
            #output_image.save("output.png")
            output_image.show()
        elif (im_edit == "Negative"):
            negative_list = [(255-p[0], 255-p[1], 255-p[2])
                                for p in input_image.getdata()]
            output_image.putdata(negative_list)
            #output_image.save("output.png")
            output_image.show()
        elif (im_edit == "Grayscale"):
            new_list = [ ( (a[0]+a[1]+a[2])//3, ) * 3
                                for a in input_image.getdata() ]
            output_image.putdata(new_list)
            #output_image.save("output.png")
            output_image.show()
        else: #"Pick a value" or "None"
            input_image.show()


    @Slot()
    def on_back(self):
        print("back")
Пример #17
0
class PredictionWindow(QWidget):
    """Subwindow dedicated to random forest prediction functions."""

    # Private Instance Attributes:
    # - _predict_btn: Button that signals for a prediction to be made.
    # - _predict_btn: Button that signals for the selected model to be deleted.
    # - _model: The RandomForest model currently loaded.
    # - _model_info: QPlainTextEdit widget displaying information about the selected model.
    # - _target_date: Calendar widget for the user to select a target prediction date.
    # -_plot_window: Window for displaying historical information with a prediction.
    _predict_btn: QDialogButtonBox
    _delete_btn: QDialogButtonBox
    _model: QComboBox
    _model_info: QPlainTextEdit
    _target_date: QCalendarWidget
    _plot_window: QMainWindow

    def __init__(self) -> None:
        super().__init__()

        main_layout = QGridLayout()
        button_box = self._create_button_box()
        main_layout.addWidget(self._create_options_group_box(), 0, 0)
        main_layout.addWidget(button_box, 1, 0)

        main_layout.setSizeConstraint(QLayout.SetMinimumSize)

        self.setLayout(main_layout)

        self._refresh_model_info()
        self.setWindowTitle('Predict')
        self._plot_window = QMainWindow()

    def show(self) -> None:
        """Override of QWidget's show() function.

        Refreshes window and then shows the window.
        """
        self._refresh_lists()
        return super().show()

    @property
    def _selected_model(self) -> Union[RandomForest, None]:
        """Gets the currently selected model."""
        model_name = self._model.currentText()
        if model_name != '':
            try:
                return load_model(model_name)
            except pickle.UnpicklingError:
                self._error_event(f'{model_name} is an invalid model.')
                return None
        else:
            return None

    def _create_button_box(self) -> QDialogButtonBox:
        """Creates the lower control buttons at the bottom of the window."""
        button_box = QDialogButtonBox()

        self._predict_btn = button_box.addButton('Predict',
                                                 QDialogButtonBox.ActionRole)
        self._delete_btn = button_box.addButton('Delete Model',
                                                QDialogButtonBox.ActionRole)
        refresh_btn = button_box.addButton('Refresh &Options',
                                           QDialogButtonBox.ActionRole)

        self._predict_btn.clicked.connect(self._predict)
        refresh_btn.clicked.connect(self._refresh_lists)
        self._delete_btn.clicked.connect(self._delete)

        return button_box

    def _create_options_group_box(self) -> QGroupBox:
        """Returns the group of prediction options."""
        options_group_box = QGroupBox("Options")

        options_layout = QGridLayout()
        left_options = QGridLayout()
        right_options = QGridLayout()

        date_label = QLabel("Target Date:")
        self._target_date = QCalendarWidget()

        left_options.addWidget(date_label, 0, 0)
        left_options.addWidget(self._target_date, 1, 0, 1, 3)

        left_options.setColumnStretch(0, 1)

        self._model = QComboBox()
        self._model_info = QPlainTextEdit()
        self._model_info.setReadOnly(True)

        self._model.currentTextChanged.connect(self._refresh_model_info)

        self._refresh_lists()

        models_label = QLabel("Models:")
        info_label = QLabel("Model Information:")

        right_options.addWidget(models_label, 0, 0)
        right_options.addWidget(self._model, 1, 0)

        right_options.addWidget(info_label, 2, 0)
        right_options.addWidget(self._model_info, 3, 0)

        options_layout.addLayout(left_options, 0, 0)
        options_layout.addLayout(right_options, 0, 1)

        options_group_box.setLayout(options_layout)

        return options_group_box

    def _delete(self) -> None:
        """Deletes the currently selected dataset."""
        self.setEnabled(False)
        name = self._model.currentText()

        warning = f'Are you sure you want to delete {name}?'

        response = QMessageBox.warning(self, self.tr("Delete Model"), warning,
                                       QMessageBox.Yes, QMessageBox.No)

        if response == QMessageBox.Yes:
            data_ingest.delete_data(name, file_type='model')
            self._refresh_lists()

        self.setEnabled(True)

    def _refresh_lists(self) -> None:
        """Refreshes avaliable datasets for training."""
        self._model.clear()

        data_list = data_ingest.get_avaliable_data(search_type='model')

        self._model.addItems(data_list)

    def _refresh_model_info(self) -> None:
        """Refreshes avaliable features for the selected target."""
        self._predict_btn.setEnabled(False)
        self._target_date.setEnabled(False)
        self._model_info.clear()

        model_name = self._model.currentText()

        model = self._selected_model
        if model is None:
            self._delete_btn.setEnabled(False)
            return None

        self._delete_btn.setEnabled(True)

        self._display_model_info(model)

        req_features = model.window.req_features

        avaliable_sym = data_ingest.get_avaliable_sym()

        if len(req_features - avaliable_sym) != 0:
            self._error_event(
                f'Missing required data for {model_name}: {req_features - avaliable_sym}'
            )
            return None

        dfs = load_corresponding_dataframes(model)
        grouped_dataframe = data_ingest.create_grouped_dataframe(dfs)

        date_offset = pd.DateOffset(days=model.window.target_shift)

        self._target_date.setMaximumDate(grouped_dataframe.index.max() +
                                         date_offset)
        self._target_date.setMinimumDate(grouped_dataframe.index.min() +
                                         date_offset)

        self._target_date.setEnabled(True)
        self._predict_btn.setEnabled(True)

        return None

    def _display_model_info(self, model: RandomForest) -> None:
        """Updates model info box to display current model's information."""
        self._model_info.appendPlainText(
            f'Target Feature Name: \n{model.window.target_lbl}')
        self._model_info.appendPlainText('Window Information:')
        self._model_info.appendPlainText(
            f'\t- Window Size: {model.window.window_size}')
        self._model_info.appendPlainText(
            f'\t- Target Shift: {model.window.target_shift}')
        self._model_info.appendPlainText(
            f'\t- Required Features: {model.window.req_features}')
        self._model_info.appendPlainText('Forest Information:')
        self._model_info.appendPlainText(
            f'\t- Number of Trees: {model.forest.n_trees}')
        self._model_info.appendPlainText(
            f'\t- Tree Max Depth: {model.forest.max_depth}')
        self._model_info.appendPlainText(f'\t- Seed: {model.forest.seed}')

    def _predict(self) -> None:
        """Creates a model prediction using the selected target date and model."""
        self.setEnabled(False)
        self._predict_btn.setEnabled(False)
        model = self._selected_model
        if model is None:
            self.setEnabled(True)
            return None

        target_date = self._target_date.selectedDate().toPython()

        try:
            dfs = load_corresponding_dataframes(model)
            prediction_input = data_ingest.create_input(
                model.window.window_size, model.window.target_shift,
                target_date, dfs)
        except ce.MissingData:
            self._error_event(
                'Missing required data. Could be that loaded datasets have holes.'
            )
            self.setEnabled(True)
            return None

        prediction = model.predict(prediction_input)

        historical_dfs = load_corresponding_dataframes(model, 'target')
        if len(historical_dfs) == 0:
            self._prediction_historical_error(prediction)
        else:
            self._plot_prediction(historical_dfs, model, prediction,
                                  target_date)

        self._predict_btn.setEnabled(True)
        self.setEnabled(True)
        return None

    def _plot_prediction(self, historical_dfs: list[pd.DataFrame],
                         model: RandomForest, prediction: ndarray,
                         target_date: datetime.date) -> None:
        """Opens a window with a plot of the historical target data as well as the prediction
        the model made."""
        hdf = historical_dfs[0]
        for frame in historical_dfs[1:]:
            hdf = hdf.combine_first(frame)
        window_end = target_date - \
            pd.DateOffset(days=model.window.target_shift)
        window_start = window_end - pd.DateOffset(days=30 - 1)
        hdf = pd.Series(
            hdf.loc[window_end:window_start][model.window.target_lbl])

        hdf_data = hdf.to_list()
        hdf_dates = hdf.index

        hdf_dates = [ts.to_pydatetime().timestamp() for ts in hdf_dates]

        b_axis = pg.DateAxisItem(orientation='bottom')
        b_axis.setLabel('Date')
        plot = PlotWidget(axisItems={'bottom': b_axis})

        target_time = datetime.combine(target_date, datetime.min.time())

        plot.addLegend()
        plot.plot(x=hdf_dates,
                  y=hdf_data,
                  name=f'Historical {model.window.target_lbl}')
        plot.plot(x=[target_time.timestamp()],
                  y=prediction,
                  pen=None,
                  symbol='o',
                  name=f'Predicted Value: {prediction[0]}')
        model_name = self._model.currentText()
        self._plot_window.setWindowTitle(f'{model_name} Prediction')
        self._plot_window.setCentralWidget(plot)
        self._plot_window.show()

    def _prediction_historical_error(self, prediction: list) -> None:
        """Displays a message for when historical target is unavalable such that
        a graph can't be made."""
        QMessageBox.information(
            self, self.tr("Information"), f'Prediction was: {prediction}. \n '
            'Unable to display graph due to missing historical data.',
            QtWidgets.QMessageBox.Ok)

    def _error_event(
        self,
        error: str,
        choice: bool = False,
        btn: QMessageBox = QMessageBox.Abort
    ) -> Union[QMessageBox.Ignore, QMessageBox.Abort, None]:
        """Displays an error message with the given error."""
        if choice:
            response = QMessageBox.critical(self, self.tr("Error"), error, btn,
                                            QMessageBox.Ignore)
            return response
        else:
            QMessageBox.critical(self, self.tr("Error"), error, QMessageBox.Ok)
            return None
Пример #18
0
class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        # Title and dimensions
        self.setWindowTitle("Patterns detection")
        self.setGeometry(0, 0, 800, 500)

        # Main menu bar
        self.menu = self.menuBar()
        self.menu_file = self.menu.addMenu("File")
        exit = QAction("Exit", self, triggered=qApp.quit)
        self.menu_file.addAction(exit)

        self.menu_about = self.menu.addMenu("&About")
        about = QAction("About Qt", self, shortcut=QKeySequence(QKeySequence.HelpContents),
                        triggered=qApp.aboutQt)
        self.menu_about.addAction(about)

        # Create a label for the display camera
        self.label = QLabel(self)
        self.label.setFixedSize(640, 480)

        # Thread in charge of updating the image
        self.th = Thread(self)
        self.th.finished.connect(self.close)
        self.th.updateFrame.connect(self.setImage)

        # Model group
        self.group_model = QGroupBox("Trained model")
        self.group_model.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        model_layout = QHBoxLayout()

        self.combobox = QComboBox()
        for xml_file in os.listdir(cv2.data.haarcascades):
            if xml_file.endswith(".xml"):
                self.combobox.addItem(xml_file)

        model_layout.addWidget(QLabel("File:"), 10)
        model_layout.addWidget(self.combobox, 90)
        self.group_model.setLayout(model_layout)

        # Buttons layout
        buttons_layout = QHBoxLayout()
        self.button1 = QPushButton("Start")
        self.button2 = QPushButton("Stop/Close")
        self.button1.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        self.button2.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        buttons_layout.addWidget(self.button2)
        buttons_layout.addWidget(self.button1)

        right_layout = QHBoxLayout()
        right_layout.addWidget(self.group_model, 1)
        right_layout.addLayout(buttons_layout, 1)

        # Main layout
        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addLayout(right_layout)

        # Central widget
        widget = QWidget(self)
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        # Connections
        self.button1.clicked.connect(self.start)
        self.button2.clicked.connect(self.kill_thread)
        self.button2.setEnabled(False)
        self.combobox.currentTextChanged.connect(self.set_model)

    @Slot()
    def set_model(self, text):
        self.th.set_file(text)

    @Slot()
    def kill_thread(self):
        print("Finishing...")
        self.button2.setEnabled(False)
        self.button1.setEnabled(True)
        self.th.cap.release()
        cv2.destroyAllWindows()
        self.status = False
        self.th.terminate()
        # Give time for the thread to finish
        time.sleep(1)

    @Slot()
    def start(self):
        print("Starting...")
        self.button2.setEnabled(True)
        self.button1.setEnabled(False)
        self.th.set_file(self.combobox.currentText())
        self.th.start()

    @Slot(QImage)
    def setImage(self, image):
        self.label.setPixmap(QPixmap.fromImage(image))
Пример #19
0
class App(QWidget):
    def __init__(self):

        #init
        super(App, self).__init__()

        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
        #parameters for the resume generation.
        self.params = {
            "White": 1.0,
            "Black": 1.0,
            "Hispanic": 1.0,
            "Asian": 1.0,
            "GenderRatio": 0.5,
            "TestSection": '',
            "TestMode": 2,
            "WorkPath": "",
            "BeginYear": "",
            "EndYear": "",
            "BeginMonth": "",
            "EndMonth": "",
            "BeginYearEdu": "",
            "EndYearEdu": "",
            "BeginMonthEdu": "",
            "EndMonthEdu": ""
        }
        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

        #Dictionaries for UI buttons

        self.testModes = {"Before": 1, "After": 2, "Replace": 3}

        self.testSections = {
            "Address": 1,
            "Education": 2,
            "Work History": 3,
            "Skills": 4
        }
        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
        #Window sizing for application
        self.title = "COEHP Resume Generator"
        self.left = 10
        self.top = 10
        self.width = 100
        self.height = 300

        #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
        #Window is created here
        self.makeUI()

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #Function creates window and adds widgets

    def makeUI(self):

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.createLayout()

        windowLayout = QGridLayout()

        windowLayout.addWidget(self.box0, 1, 1, 1, 1)
        windowLayout.addWidget(self.box4, 0, 0, 1, 1)
        windowLayout.addWidget(self.box6, 1, 0, 1, 1)
        windowLayout.addWidget(self.box7, 0, 1, 1, 1)
        windowLayout.addWidget(self.box5, 3, 0, 1, 2)
        windowLayout.addWidget(self.box8, 2, 0, 1, 2)

        windowLayout.setAlignment(QtCore.Qt.AlignTop)

        self.setLayout(windowLayout)
        self.show()

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #All QGroupBoxes for features are added here.
    def createLayout(self):
        self.box0 = QGroupBox("Timeframe")
        self.box4 = QGroupBox("Test Data")
        self.box6 = QGroupBox("Output Directory")
        self.box5 = QGroupBox("")
        self.box7 = QGroupBox("Demographic Settings")
        self.box8 = QGroupBox("Resume Layout")

        #Demographic Settings

        self.wPercent = QTextEdit("0.25")
        self.bPercent = QTextEdit("0.25")
        self.aPercent = QTextEdit("0.25")
        self.hPercent = QTextEdit("0.25")
        self.gPercent = QTextEdit("0.5")
        self.wLabel = QLabel("White %")
        self.bLabel = QLabel("Black %")
        self.aLabel = QLabel("Asian %")
        self.hLabel = QLabel("Hispanic %")
        self.gLabel = QLabel("       Gender Ratio")

        self.wPercent.setFixedSize(100, 30)
        self.bPercent.setFixedSize(100, 30)
        self.aPercent.setFixedSize(100, 30)
        self.hPercent.setFixedSize(100, 30)
        self.gPercent.setFixedSize(100, 30)

        #Resume Layout Settings

        self.testSectionLabel1 = QLabel("Test Location")
        self.testSectionLabel2 = QLabel("Section")
        self.testSectionLabel3 = QLabel("Location of Content")
        self.sectionSelect = QComboBox()
        self.sectionSelect.addItems(
            ["Address", "Education", "Work History", "Skills"])
        self.sectionSelect.setFixedSize(300, 30)

        self.modeSelect = QComboBox()
        self.modeSelect.addItems(["Before", "After", "Replace"])
        self.modeSelect.setFixedSize(300, 30)

        #Academic Year

        #First Semester
        self.monthBegin = QComboBox()
        self.monthBegin.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthBegin.setFixedSize(100, 30)

        self.yearBeginLabel = QLabel("First Semester")
        self.yearBegin = QComboBox()
        self.yearBegin.setFixedSize(100, 30)

        for year in range(1970, 2050):
            self.yearBegin.addItem(str(year))

        #Last Semester
        self.monthEnd = QComboBox()
        self.monthEnd.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthEnd.setFixedSize(100, 30)

        self.yearEnd = QComboBox()
        self.yearEndLabel = QLabel("Semester of Graduation")
        for year in range(1970, 2050):
            self.yearEnd.addItem(str(year))
        self.yearEnd.setFixedSize(100, 30)

        #Earliest relevant employment
        self.monthWorkBegin = QComboBox()
        self.monthWorkBegin.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthBegin.setFixedSize(100, 30)

        self.yearWorkBeginLabel = QLabel(
            "Earliest Possible Date of Employment")
        self.yearWorkBegin = QComboBox()
        self.yearWorkBegin.setFixedSize(100, 30)

        for year in range(1970, 2050):
            self.yearWorkBegin.addItem(str(year))

        #Latest relevant employment
        self.monthWorkEnd = QComboBox()
        self.monthWorkEnd.addItems([
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "November", "December"
        ])
        self.monthWorkEnd.setFixedSize(100, 30)

        self.yearWorkEnd = QComboBox()
        self.yearWorkEndLabel = QLabel("Latest Possible Date of Employment")
        for year in range(1970, 2050):
            self.yearWorkEnd.addItem(str(year))
        self.yearWorkEnd.setFixedSize(100, 30)

        currentYear = date.today().year
        index = currentYear - 1970
        self.yearEnd.setCurrentIndex(index)
        self.yearBegin.setCurrentIndex(index)
        self.yearWorkBegin.setCurrentIndex(index)
        self.yearWorkEnd.setCurrentIndex(index)

        #Output Directory
        self.dirLabel = QLabel("Output Directory")
        self.currentDir = QTextEdit()
        self.currentDir.setText("Not Selected")
        self.currentDir.layout()
        self.currentDir.setFixedSize(300, 30)
        self.currentDir.setReadOnly(True)
        self.outputName = QTextEdit()

        self.outputLabel = QLabel("Output Folder Name")
        self.outputName.setText("None written")
        self.outputName.setToolTip(
            "Type in the name of the new Folder you would like to make for your Resume batch. \n Otherwise, this will use the current timestamp."
        )
        self.outputName.setFixedSize(300, 30)
        #Select ouput folder button

        self.outputButton = QPushButton('Select Output Directory')
        self.outputButton.setToolTip(
            "Click here to tell the generator where to put this batch of Resumes when it is finished."
        )
        self.outputButton.clicked.connect(
            lambda: self.openDir(self.currentDir))
        self.currentTest = QTextEdit()
        self.currentTest.setText("SportsCollegeList.csv")

        #Output Directory
        self.workLabel = QLabel("Output Directory")
        self.currentWork = QTextEdit()
        self.currentWork.setText("SportsCollegeList.csv")
        self.currentWork.layout()
        self.currentWork.setFixedSize(300, 30)
        self.currentWork.setReadOnly(True)

        #Select work datafolder button
        self.workButton = QPushButton('Select Work Data (.CSV)')
        self.workButton.setToolTip(
            "Click here to select a source file for the employment information in this Resume Batch."
        )
        self.workButton.clicked.connect(lambda: self.openDir(self.currentWork))

        #Select School Data

        self.workLabel = QLabel("Output Directory")
        self.currentSchool = QTextEdit()
        self.currentSchool.setText("Not Selected")
        self.currentSchool.layout()
        self.currentSchool.setFixedSize(300, 30)
        self.currentSchool.setReadOnly(True)

        #Select work datafolder button
        self.schoolButton = QPushButton('Select Work Data (.CSV)')
        self.schoolButton.clicked.connect(
            lambda: self.openDir(self.currentWork))

        #Select test data

        self.testLabel = QLabel("Output Directory")
        self.currentTest = QTextEdit()
        self.currentTest.setText("SportsCollegeList.csv")
        self.currentTest.layout()
        self.currentTest.setFixedSize(300, 30)
        self.currentTest.setReadOnly(True)
        self.testButton = QPushButton('Select Test Data (.CSV)')
        self.testButton.clicked.connect(lambda: self.openDir(self.currentTest))

        #Generate Resumes button
        self.begin = QPushButton('Generate Resumes')
        self.begin.clicked.connect(
            lambda: self.beginTask(self.currentTest.toPlainText()))

        layout = QGridLayout()
        self.box0.setLayout(layout)
        layout.addWidget(self.yearBeginLabel, 0, 0, 1, 2)
        layout.addWidget(self.monthBegin, 1, 0, 1, 1)
        layout.addWidget(self.yearBegin, 1, 1, 1, 1)
        layout.addWidget(self.yearEndLabel, 2, 0, 1, 2)
        layout.addWidget(self.monthEnd, 3, 0, 1, 1)
        layout.addWidget(self.yearEnd, 3, 1, 1, 1)

        layout.addWidget(self.yearWorkBeginLabel, 4, 0, 1, 2)
        layout.addWidget(self.monthWorkBegin, 5, 0, 1, 1)
        layout.addWidget(self.yearWorkBegin, 5, 1, 1, 1)
        layout.addWidget(self.yearWorkEndLabel, 6, 0, 1, 2)
        layout.addWidget(self.monthWorkEnd, 7, 0, 1, 1)
        layout.addWidget(self.yearWorkEnd, 7, 1, 1, 1)

        layout1 = QGridLayout()
        self.box8.setLayout(layout1)
        layout1.addWidget(self.testSectionLabel1, 0, 0, 1, 1)
        layout1.addWidget(self.testSectionLabel3, 1, 0, 1, 1)
        layout1.addWidget(self.sectionSelect, 0, 1, 1, 1)
        layout1.addWidget(self.modeSelect, 1, 1, 1, 1)

        layout2 = QGridLayout()
        self.box7.setLayout(layout2)
        layout2.addWidget(self.wLabel, 0, 0, 1, 1)
        layout2.addWidget(self.bLabel, 1, 0, 1, 1)
        layout2.addWidget(self.hLabel, 0, 2, 1, 1)
        layout2.addWidget(self.aLabel, 2, 0, 1, 1)
        layout2.addWidget(self.wPercent, 0, 1, 1, 1)
        layout2.addWidget(self.bPercent, 1, 1, 1, 1)
        layout2.addWidget(self.hPercent, 0, 3, 1, 1)
        layout2.addWidget(self.aPercent, 2, 1, 1, 1)
        layout2.addWidget(self.gLabel, 3, 1, 1, 1)
        layout2.addWidget(self.gPercent, 3, 2, 1, 2)

        layout = QGridLayout()
        self.box5.setLayout(layout)
        layout.addWidget(self.begin, 0, 0, 1, 2)

        layout3 = QGridLayout()
        layout3.addWidget(self.testButton, 0, 0, 1, 2)
        layout3.addWidget(self.currentTest, 1, 0, 1, 2)
        self.box4.setLayout(layout3)

        layout4 = QGridLayout()

        layout4.addWidget(self.outputButton, 0, 0, 1, 2)
        layout4.addWidget(self.currentDir, 1, 0, 1, 2)
        layout4.addWidget(self.outputLabel, 2, 0, 1, 2)
        layout4.addWidget(self.outputName, 3, 0, 1, 2)
        self.box6.setLayout(layout4)

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #
    def openDir(self, target):
        fileName = QFileDialog()
        filenames = list()
        if fileName.exec_():
            fileNames = fileName.selectedFiles()
            target.setText(fileNames[0])

    #▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
    #
    def beginTask(self, path):
        self.beginGen(path)

    def beginGen(self, path):

        self.params["White"] = self.wPercent.toPlainText()
        self.params["Black"] = self.bPercent.toPlainText()
        self.params["Hispanic"] = self.hPercent.toPlainText()
        self.params["Asian"] = self.aPercent.toPlainText()
        self.params["GenderRatio"] = self.gPercent.toPlainText()
        self.params["TestMode"] = str(self.modeSelect.currentText())
        self.params["TestSection"] = str(self.sectionSelect.currentText())
        self.params["BeginYear"] = str(self.yearWorkBegin.currentText())
        self.params["EndYear"] = str(self.yearWorkEnd.currentText())
        self.params["BeginMonth"] = str(self.monthWorkBegin.currentText())
        self.params["EndMonth"] = str(self.monthWorkEnd.currentText())
        self.params["workPath"] = "work.csv"
        self.params["BeginYearEdu"] = str(self.yearBegin.currentText())
        self.params["EndYearEdu"] = str(self.yearEnd.currentText())
        self.params["BeginMonthEdu"] = str(self.monthBegin.currentText())
        self.params["EndMonthEdu"] = str(self.monthEnd.currentText())

        print(self.params)
        Printer.begin(self.currentDir.toPlainText(), path,
                      self.outputName.toPlainText(), self.params)
Пример #20
0
class ImageManipulation(QWidget):
    def __init__(self, img):
        super().__init__()

        # Declare Widgets
        self.edit_label = QLabel('Change your image')

        # set up list and combo box option
        self.my_list = [
            "Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia",
            "Negative", "Grayscale", "None"
        ]
        self.my_combo_box = QComboBox()
        self.my_combo_box.addItems(self.my_list)

        self.edit_btn = QPushButton("Edit")

        # Create U.I. Layout
        mbox = QHBoxLayout()

        vbox = QVBoxLayout()
        vbox.addWidget(self.edit_label)
        vbox.addWidget(self.my_combo_box)
        vbox.addWidget(self.edit_btn)

        mbox.addLayout(vbox)
        image = Image.open(requests.get(img['urls']['thumb'], stream=True).raw)
        editpath = "./editing/edit.jpg"
        image.save(editpath)
        self.lbl = QLabel()
        pix = QPixmap(editpath)
        self.lbl.setPixmap(pix)
        mbox.addWidget(self.lbl)

        self.setLayout(mbox)  # apply layout to this class

        # when button is clicked send lineedit and combo box info to on_submit
        self.edit_btn.clicked.connect(self.on_edit)

    @Slot()
    def on_edit(self):

        # set up im_edit as which filter the user chose
        im_edit = self.my_combo_box.currentText()

        # take the image to edit and load it
        input_image = Image.open("./editing/edit.jpg")
        input_pixels = input_image.load()

        output_image = Image.new("RGB", input_image.size)
        draw = ImageDraw.Draw(output_image)

        # Options are: ["Pick a value", "Luminosity", "Contrast", "Colorize", "Sepia", "Negative", "Grayscale", "None"]
        # Luminostity brightens the image overall
        if (im_edit == "Luminosity"):
            luminosity = 80

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b = input_pixels[x, y]
                    r = int(r + luminosity)
                    g = int(g + luminosity)
                    b = int(b + luminosity)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        # Contrast makes the image slightly darker overall
        elif (im_edit == "Contrast"):
            # Find minimum and maximum luminosity
            imin = 255
            imax = 0
            for x in range(input_image.width):
                for y in range(input_image.height):
                    r, g, b = input_pixels[x, y]
                    i = (r + g + b) / 3
                    imin = min(imin, i)
                    imax = max(imax, i)

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b = input_pixels[x, y]
                    # Current luminosity
                    i = (r + g + b) / 3
                    # New luminosity
                    ip = 255 * (i - imin) / (imax - imin)
                    r = int(r * ip / i)
                    g = int(g * ip / i)
                    b = int(b * ip / i)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        # Colorize increases one color in the image
        elif (im_edit == "Colorize"):
            # Square distance between 2 colors
            def distance2(color1, color2):
                r1, g1, b1 = color1
                r2, g2, b2 = color2
                return (r1 - r2)**2 + (g1 - g2)**2 + (b1 - b2)**2

            color_to_change = (0, 0, 255)
            threshold = 220

            # Generate image
            for x in range(output_image.width):
                for y in range(output_image.height):
                    r, g, b = input_pixels[x, y]
                    if distance2(color_to_change,
                                 input_pixels[x, y]) < threshold**2:
                        r = int(r * .5)
                        g = int(g * 1.25)
                        b = int(b * .5)
                    draw.point((x, y), (r, g, b))

            output_image.show()
        # Sepia increases the red and decreases the blue value depending on the intensity
        elif (im_edit == "Sepia"):

            def sepia(pixel):
                if pixel[0] < 63:
                    r, g, b = int(pixel[0] * 1.1), pixel[1], int(pixel[2] * .9)
                elif pixel[0] > 62 and pixel[0] < 192:
                    r, g, b = int(pixel[0] * 1.15), pixel[1], int(pixel[2] *
                                                                  .85)
                else:
                    r = int(pixel[0] * 1.08)
                    if r > 255: r = 255
                    g, b = pixel[1], pixel[2] // 2
                return r, g, b

            sepia_list = map(sepia, input_image.getdata())
            output_image.putdata(list(sepia_list))
            output_image.show()
        # Negative swaps the rgb values to their opposite counterparts
        elif (im_edit == "Negative"):
            negative_list = [(255 - p[0], 255 - p[1], 255 - p[2])
                             for p in input_image.getdata()]
            output_image.putdata(negative_list)
            output_image.show()
        # Grayscale averages the rgb values and creates the gray version of the image
        elif (im_edit == "Grayscale"):
            new_list = [((a[0] + a[1] + a[2]) // 3, ) * 3
                        for a in input_image.getdata()]
            output_image.putdata(new_list)
            output_image.show()
        else:  #"Pick a value" or "None"
            input_image.show()