Ejemplo n.º 1
0
    def hikdef(self):
        chue_nod_kho_nok = None
        chue_nod_poly = self.cbb_poly.currentText()
        if (mc.objExists(chue_nod_poly)):
            if (mc.objExists(chue_nod_poly + '_sentaa')):
                chue_nod_kho_nok = chue_nod_poly + '_sentaa'
            elif (mc.objExists(chue_nod_poly + '_subetenooya')):
                chue_nod_kho_nok = chue_nod_poly + '_subetenooya'

        if (not chue_nod_kho_nok):
            QMessageBox.about(self, '何か間違いかも', '該当のジョイントが見つかりません')
            return

        self.wdg.setFixedSize(600, 2000)
        self.btn_hikdef.setEnabled(False)
        self.cbb_poly.setEnabled(False)
        dic_chue = {}
        if (chue_nod_kho_nok[0] != '|'):
            chue_nod_kho_nok = '|' + chue_nod_kho_nok
        set_hik = set(mc.ls(type='HIKCharacterNode'))
        mel.eval('hikCreateDefinition')
        chue_nod_hik = (set(mc.ls(type='HIKCharacterNode')) - set_hik).pop()
        chue_nod_hik = mc.rename(chue_nod_hik, 'HIK_' + chue_nod_poly)
        lis_chue_nod_kho = [chue_nod_kho_nok] + mc.listRelatives(
            chue_nod_kho_nok, allDescendents=True, fullPath=True)
        for lek in dic_hik:
            hbl = QHBoxLayout()
            self.vbl.addLayout(hbl)
            lb = QLabel(dic_hik[lek][0])
            hbl.addWidget(lb)
            lb.setFixedWidth(80)
            for chue_nod_kho in lis_chue_nod_kho:
                khonha = re.findall(r'\|%s$' % dic_hik[lek][1], chue_nod_kho)
                if (khonha):
                    dic_chue[lek] = chue_nod_kho
                    mel.eval('hikSetCharacterObject %s %s %d 0' %
                             (chue_nod_kho, chue_nod_hik, lek))

                    btn = QPushButton('選択')
                    hbl.addWidget(btn)
                    btn.setFixedSize(50, 30)

                    le = QLineEdit(chue_nod_kho)
                    hbl.addWidget(le)
                    btn.clicked.connect((lambda x:
                                         (lambda: mc.select(x.text())))(le))
                    le.setFixedWidth(400)
                    le.setStyleSheet('font-size: 12px; color: #ffe;')
                    break
            else:
                lb = QLabel('見つかりません')
                hbl.addWidget(lb)
                lb.setFixedWidth(400)
                lb.setStyleSheet('color: #fab;')

            hbl.addStretch()

        kangkhaen(dic_chue)
        self.vbl.addStretch()
        self.btn_sang_hik.setEnabled(True)
Ejemplo n.º 2
0
class ClusterDialog(QDialog):
    
    editClusterName = None
    def __init__(self, lifeline, defaultName, parent = None):
        super(ClusterDialog, self).__init__(parent)

        self.lifeline = lifeline
        layout = QVBoxLayout(self)

        message = QLabel('Enter group name')
        layout.addWidget(message)

        self.editClusterName = QLineEdit(defaultName)
        self.editClusterName.setFixedHeight(30)
        self.editClusterName.setFixedWidth(400)
        self.editClusterName.textChanged.connect(self.validateCluster)
        layout.addWidget(self.editClusterName)

        self.validation_msg = QLabel(' ')
        layout.addWidget(self.validation_msg)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

        self.validateCluster()

    def validateCluster(self):
        cnt = 0
        for l in self.lifeline:
            if self.editClusterName.text() in l.getClassName() and not l.getFlagCluster() and not l.getClusterLifeline():
                cnt += 1

        available_flag = True
        for l in self.lifeline:
            if self.editClusterName.text() in l.getClassName() and l.getFlagCluster():
                available_flag = False
                break

        if available_flag:
            self.validation_msg.setText("group name includes %d life-lines" % (cnt))
        else:
            self.validation_msg.setText("group name is not available")

    def getClusterText(self):
        return self.editClusterName.text()
    
    @staticmethod
    def getClusterName(lifelines, defaultName, parent = None):
        dialog = ClusterDialog(lifelines,defaultName,parent)
        result = dialog.exec_()
        return (result, dialog.getClusterText())

         
Ejemplo n.º 3
0
    def __init__(self, on_serves_entered: CallbackType) -> None:
        self._on_serves_entered = on_serves_entered

        serves_amount_line_edit = QLineEdit("1")
        serves_amount_line_edit.setFixedWidth(30)
        serves_amount_line_edit.setValidator(QIntValidator())
        serves_amount_line_edit.setMaxLength(2)

        super().__init__("Количество порций:", serves_amount_line_edit)

        self._connect_slots()
Ejemplo n.º 4
0
class ClusterDialog(QDialog):
    
    editClusterName = None
    def __init__(self, lifeline, defaultName, parent = None):
        super(ClusterDialog, self).__init__(parent)

        self.lifeline = lifeline
        layout = QVBoxLayout(self)

        message = QLabel('Enter group name')
        layout.addWidget(message)

        self.editClusterName = QLineEdit(defaultName)
        self.editClusterName.setFixedHeight(30)
        self.editClusterName.setFixedWidth(400)
        self.editClusterName.textChanged.connect(self.validateCluster)
        layout.addWidget(self.editClusterName)

        self.validation_msg = QLabel(' ')
        layout.addWidget(self.validation_msg)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

        self.validateCluster()

    def validateCluster(self):
        cnt = 0
        for l in self.lifeline:
            if self.editClusterName.text() in l.getClassName() and not l.getFlagCluster() and not l.getClusterLifeline():
                cnt += 1

        available_flag = True
        for l in self.lifeline:
            if self.editClusterName.text() in l.getClassName() and l.getFlagCluster():
                available_flag = False
                break

        if available_flag:
            self.validation_msg.setText("group name includes %d life-lines" % (cnt))
        else:
            self.validation_msg.setText("group name is not available")

    def getClusterText(self):
        return self.editClusterName.text()
    
    @staticmethod
    def getClusterName(lifelines, defaultName, parent = None):
        dialog = ClusterDialog(lifelines,defaultName,parent)
        result = dialog.exec_()
        return (result, dialog.getClusterText())
Ejemplo n.º 5
0
    def __init__(self, food_names: List[str],
                 on_ingredient_entered: CallbackType,
                 on_ingredient_finalized: CallbackType) -> None:
        super().__init__()

        self._food_names = food_names
        self._on_ingredient_entered = on_ingredient_entered
        self._on_ingredient_finalized = on_ingredient_finalized

        # ingredient
        ingredient_label = QLabel("Продукт:")
        ingredient_line_edit = QLineEdit()

        # Completer for the ingredient line edit
        completer = QCompleter(self._food_names)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        ingredient_line_edit.setCompleter(completer)

        # ingredient mass line edit
        ingredient_mass_line_edit = QLineEdit()
        ingredient_mass_line_edit.setPlaceholderText("Масса (гр.)")
        ingredient_mass_line_edit.setFixedWidth(100)
        ingredient_mass_line_edit.setValidator(QIntValidator())
        ingredient_mass_line_edit.setMaxLength(4)

        # Button to add ingredient to the recipe

        ingredient_add_button = QPushButton("+")

        # Layout for ingredient_label / ingredient_line_edit
        ingredient_layout = QHBoxLayout()
        ingredient_layout.addWidget(ingredient_label)
        ingredient_layout.addWidget(ingredient_line_edit)
        ingredient_layout.addWidget(ingredient_mass_line_edit)
        ingredient_layout.addWidget(ingredient_add_button)

        self.setLayout(ingredient_layout)

        self._ingredient_line_edit = ingredient_line_edit
        self._ingredient_mass_line_edit = ingredient_mass_line_edit
        self._ingredient_add_button = ingredient_add_button

        self._connect_slots()
Ejemplo n.º 6
0
    def __init__(self, lookup_names: List,
                 on_item_added: CallbackType) -> None:
        super().__init__()

        recipe_search_label = QLabel("Блюдо:")

        recipe_search_line_edit = QLineEdit("")
        completer = QCompleter(lookup_names)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setFilterMode(Qt.MatchFlag.MatchContains)
        completer.setMaxVisibleItems(50)
        recipe_search_line_edit.setCompleter(completer)

        serves_amount_label = QLabel("Порций:")

        serves_amount_line_edit = QLineEdit(str(self.DEFAULT_SERVES_AMOUNT))
        serves_amount_line_edit.setFixedWidth(30)
        serves_amount_line_edit.setValidator(QIntValidator())
        serves_amount_line_edit.setMaxLength(2)

        add_push_button = QPushButton("+")

        # Widget layout
        layout = QHBoxLayout()
        layout.addWidget(recipe_search_label)
        layout.addWidget(recipe_search_line_edit)
        layout.addWidget(serves_amount_label)
        layout.addWidget(serves_amount_line_edit)
        layout.addWidget(add_push_button)
        layout.addStretch()

        self.setLayout(layout)

        # Init self data
        self._on_item_added = on_item_added
        self._recipe_search_line_edit = recipe_search_line_edit
        self._serves_amount_line_edit = serves_amount_line_edit
        self._add_push_button = add_push_button

        # Connect slots
        self._connect_slots()
Ejemplo n.º 7
0
class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        event_ids = [18218, 17412, 18308, 18106, 16981, 18995]
        self.layout = QVBoxLayout()
        self.setWindowIconText('Test')
        self.text = QLabel("Event ID:s")
        self.text.setAlignment(Qt.AlignLeft)
        self.layout.addWidget(self.text)

        self.event1 = QLineEdit()
        self.event1.setAlignment(Qt.AlignLeft)
        self.event1.setFixedWidth(120)
        self.event1.setText(str(event_ids[0]))
        self.layout.addWidget(self.event1)

        self.event2 = QLineEdit()
        self.event2.setAlignment(Qt.AlignLeft)
        self.event2.setFixedWidth(120)
        self.event2.setText(str(event_ids[1]))
        self.layout.addWidget(self.event2)

        self.event3 = QLineEdit()
        self.event3.setAlignment(Qt.AlignLeft)
        self.event3.setFixedWidth(120)
        self.event3.setText(str(event_ids[2]))
        self.layout.addWidget(self.event3)

        self.event4 = QLineEdit()
        self.event4.setAlignment(Qt.AlignLeft)
        self.event4.setFixedWidth(120)
        self.event4.setText(str(event_ids[3]))
        self.layout.addWidget(self.event4)

        self.event5 = QLineEdit()
        self.event5.setAlignment(Qt.AlignLeft)
        self.event5.setFixedWidth(120)
        self.event5.setText(str(event_ids[4]))
        self.layout.addWidget(self.event5)

        self.event6 = QLineEdit()
        self.event6.setAlignment(Qt.AlignLeft)
        self.event6.setFixedWidth(120)
        self.event6.setText(str(event_ids[5]))
        self.layout.addWidget(self.event6)

        self.output1 = QLabel("--Nothing analysed yet--")
        self.output1.setAlignment(Qt.AlignRight)
        self.layout.addWidget(self.output1)

        self.output2 = QLabel(" ")
        self.output2.setAlignment(Qt.AlignRight)
        self.layout.addWidget(self.output2)

        self.button = QPushButton("Extract and analyse events")
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)

        # Connecting the signal
        self.button.clicked.connect(self.magic)

    @Slot()
    def magic(self):
        self.output1.setText("Analysing...")
        eventlist = [
            self.event1.text(),
            self.event2.text(),
            self.event3.text(),
            self.event4.text(),
            self.event5.text(),
            self.event6.text()
        ]
        club_file, ind_file = extract_and_analyse(eventlist)
        self.output1.setText('Saved: ' + club_file)
        self.output2.setText('Saved: ' + ind_file)
Ejemplo n.º 8
0
class RightSide:
    def __init__(self, font):
        self._font = font

        self.layout = QVBoxLayout()

        self.stdout_info = QTextEdit()
        self.stdout_info.setFixedWidth(800)
        self.stdout_info.moveCursor(QtGui.QTextCursor.Start)
        self.stdout_info.ensureCursorVisible()
        self.stdout_info.setLineWrapColumnOrWidth(500)
        self.stdout_info.setLineWrapMode(QTextEdit.FixedPixelWidth)

        self.layout.addWidget(self.stdout_info)

        self._set_media_player()

        self._midi_path = os.path.abspath(
            os.path.join(str(Path(__file__).parent.parent.parent), 'results'))
        self._midi_file = None
        self.midi_player = MidiPlayer()
        self._toggle_pause = True
        self._already_playing = False

        self._play_default_stylesheet = None
        self._pause_default_stylesheet = None
        self._stop_default_stylesheet = None

        self.end_signal = 'NO END.'
        self.player_timer_thread = threading.Thread(
            target=self._update_media_player_timer)
        self.player_timer_thread.start()

    def update_stdout_text_window(self, msg):
        cursor = self.stdout_info.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(msg)
        self.stdout_info.setTextCursor(cursor)
        self.stdout_info.ensureCursorVisible()

    def _set_media_player(self):
        self._resources_path = os.path.abspath(
            os.path.join(str(Path(__file__).parent.parent.parent), 'resources',
                         'gui'))

        self._media_box = QHBoxLayout()

        self._play_button = QPushButton('PLAY')
        self._play_icon = QtGui.QPixmap(
            os.path.join(self._resources_path, 'play.png'))
        self._play_button.setIcon(self._play_icon)
        self._play_default_stylesheet = self._play_button.styleSheet()
        self._play_button.setEnabled(False)
        self._play_button.clicked.connect(lambda c: self._play_midi())

        self._pause_button = QPushButton('PAUSE')
        self._pause_icon = QtGui.QPixmap(
            os.path.join(self._resources_path, 'pause.png'))
        self._pause_button.setIcon(self._pause_icon)
        self._pause_default_stylesheet = self._pause_button.styleSheet()
        self._pause_button.setEnabled(False)
        self._pause_button.clicked.connect(lambda c: self._pause())

        self._stop_button = QPushButton('STOP')
        self._stop_icon = QtGui.QPixmap(
            os.path.join(self._resources_path, 'stop.png'))
        self._stop_button.setIcon(self._stop_icon)
        self._stop_button.setEnabled(False)
        self._stop_button.clicked.connect(lambda c: self._stop())
        self._stop_button.setStyleSheet(
            "QPushButton:pressed { background-color: red }")

        self._player_timer = QLineEdit('--/-- sec.')
        self._player_timer.setFixedWidth(200)
        self._player_timer.setEnabled(False)

        self._media_box.addWidget(self._play_button)
        self._media_box.addWidget(self._pause_button)
        self._media_box.addWidget(self._stop_button)
        self._media_box.addWidget(self._player_timer)
        self.layout.addLayout(self._media_box)

    def update_media_player(self, msg):
        self._midi_file = os.path.join(self._midi_path, msg[:-4] + '.mid')
        self.midi_player.load(self._midi_file)
        self._play_button.setEnabled(True)
        self._pause_button.setEnabled(True)
        self._stop_button.setEnabled(True)

    def _play_midi(self):
        self._play_button.setStyleSheet("background-color: green")
        self._pause_button.setStyleSheet(self._pause_default_stylesheet)

        self._toggle_pause = True
        if self._already_playing is False:
            self.midi_player.play()
            self._already_playing = True

    def _pause(self):
        self._play_button.setStyleSheet(self._play_default_stylesheet)
        self._pause_button.setStyleSheet("background-color: green")

        if self._toggle_pause is True:
            self.midi_player.pause()
            self._already_playing = False
        else:
            self.midi_player.unpause()
            self._already_playing = True

        self._toggle_pause = not self._toggle_pause

    def _stop(self):
        self._play_button.setStyleSheet(self._play_default_stylesheet)
        self._pause_button.setStyleSheet(self._pause_default_stylesheet)
        self._toggle_pause = True
        self.midi_player.stop()
        self._already_playing = False

    def _update_media_player_timer(self):
        while True:
            if self.end_signal == 'End.':
                break

            total = self.midi_player.song_duration
            if total != 0:
                current = self.midi_player.current_runtime
                if int(current) > math.floor(total):
                    current = total
                output = f'{current}/{total} sec.'
            else:
                output = '--/-- sec.'
            self._player_timer.setText(output)
Ejemplo n.º 9
0
class Separate(QDialog):
    videoPath = ''
    duration = 60000
    processToken = False
    voiceList = Signal(list)
    avgList = Signal(list)
    clrSep = Signal()
    tablePreset = Signal(list)
    autoFillToken = True
    autoSpanToken = True
    multipleThread = True

    def __init__(self):
        super().__init__()
        self.resize(800, 150)
        self.setWindowTitle('AI智能打轴 (测试版)')
        layout = QGridLayout()
        self.setLayout(layout)
        layout.addWidget(QLabel('前侧留白(ms)'), 0, 0, 1, 1)
        self.beforeEdit = QLineEdit('20')
        validator = QIntValidator()
        validator.setRange(0, 5000)
        self.beforeEdit.setValidator(validator)
        self.beforeEdit.setFixedWidth(50)
        layout.addWidget(self.beforeEdit, 0, 1, 1, 1)
        layout.addWidget(QLabel(''), 0, 2, 1, 1)
        layout.addWidget(QLabel('后侧留白(ms)'), 0, 3, 1, 1)
        self.afterEdit = QLineEdit('300')
        self.afterEdit.setValidator(validator)
        self.afterEdit.setFixedWidth(50)
        layout.addWidget(self.afterEdit, 0, 4, 1, 1)
        layout.addWidget(QLabel(''), 0, 5, 1, 1)
        self.autoFill = QPushButton('填充字符')
        self.autoFill.setStyleSheet('background-color:#3daee9')
        self.autoFill.clicked.connect(self.setAutoFill)
        layout.addWidget(self.autoFill, 0, 6, 1, 1)
        self.fillWord = QLineEdit('#AI自动识别#')
        layout.addWidget(self.fillWord, 0, 7, 1, 1)
        layout.addWidget(QLabel(''), 0, 8, 1, 1)
        self.autoSpan = QPushButton('自动合并')
        self.autoSpan.setStyleSheet('background-color:#3daee9')
        self.autoSpan.clicked.connect(self.setAutoSpan)
        layout.addWidget(self.autoSpan, 0, 9, 1, 1)
        self.multiCheck = QPushButton('启用多进程')
        self.multiCheck.setStyleSheet('background-color:#3daee9')
        self.multiCheck.clicked.connect(self.setMultipleThread)
        layout.addWidget(self.multiCheck, 0, 10, 1, 1)
        self.processBar = QProgressBar()
        layout.addWidget(self.processBar, 1, 0, 1, 10)
        self.checkButton = QPushButton('开始')
        self.checkButton.setFixedWidth(100)
        self.checkButton.clicked.connect(self.separateProcess)
        layout.addWidget(self.checkButton, 1, 10, 1, 1)

    def setDefault(self, videoPath, duration):
        self.videoPath = videoPath
        self.duration = duration

    def separateProcess(self):
        self.processToken = not self.processToken
        if self.videoPath:
            if self.processToken:
                self.processBar.setValue(0)
                self.checkButton.setText('初始化中')
                if not self.beforeEdit.text():
                    self.beforeEdit.setText('0')
                before = self.beforeEdit.text()
                if not self.afterEdit.text():
                    self.afterEdit.setText('0')
                after = self.afterEdit.text()
                if self.autoFillToken:
                    try:
                        fillWord = self.fillWord.text()
                    except:
                        fillWord = ''
                else:
                    fillWord = ''
                self.sepProc = separateQThread(self.videoPath, self.duration,
                                               before, after,
                                               self.multipleThread)
                self.clrSep.emit()  # 清空第一条字幕轴
                self.sepProc.position.connect(self.setTitle)  # 设置标题分析至第几分钟
                self.sepProc.percent.connect(self.setProgressBar)  # 设置滚动条进度
                self.sepProc.voiceList.connect(
                    self.sendVoiceList)  # 二次传球给主界面标记表格
                self.sepProc.avgList.connect(
                    self.sendAvgList)  # 平均音频响度 预留给后面画音频图
                self.tablePreset.emit([fillWord,
                                       self.autoSpanToken])  # 自动填充 填充文本 自动合并
                self.sepProc.finish.connect(self.sepFinished)
                self.sepProc.start()
            else:
                self.setWindowTitle('AI智能打轴 (测试版)')
                self.processBar.setValue(0)
                self.checkButton.setText('开始')
                self.checkButton.setStyleSheet('background-color:#31363b')
                #                 self.sepProc.separate._pool.terminate()
                #                 try:
                #                     p = psutil.Process(self.sepProc.p.pid)
                #                     for proc in p.children(True):
                #                         proc.kill()
                #                 except:
                #                     pass
                self.sepProc.terminate()
                self.sepProc.quit()
                self.sepProc.wait()

    def setTitle(self, pos):
        self.setWindowTitle('AI智能打轴 (已分析至第%s分钟)' % pos)

    def setProgressBar(self, percent):
        self.checkButton.setText('停止')
        self.checkButton.setStyleSheet('background-color:#3daee9')
        self.processBar.setValue(percent)

    def sendVoiceList(self, voiceList):
        self.voiceList.emit(voiceList)

    def sendAvgList(self, avgList):
        self.avgList.emit(avgList)

    def sepFinished(self, result):
        if result:
            self.processToken = not self.processToken
            self.setWindowTitle('AI智能打轴 (测试版)')
            self.processBar.setValue(100)
            self.checkButton.setText('开始')
            self.checkButton.setStyleSheet('background-color:#31363b')
            #             self.sepProc.separate._pool.terminate()
            #             try:
            #                 p = psutil.Process(self.sepProc.p.pid)
            #                 for proc in p.children(True):
            #                     proc.kill()
            #             except:
            #                 pass
            self.sepProc.terminate()
            self.sepProc.quit()
            self.sepProc.wait()

    def setAutoFill(self):
        self.autoFillToken = not self.autoFillToken
        if self.autoFillToken:
            self.autoFill.setStyleSheet('background-color:#3daee9')
            self.fillWord.setEnabled(True)
        else:
            self.autoFill.setStyleSheet('background-color:#31363b')
            self.fillWord.setEnabled(False)

    def setAutoSpan(self):
        self.autoSpanToken = not self.autoSpanToken
        if self.autoSpanToken:
            self.autoSpan.setStyleSheet('background-color:#3daee9')
        else:
            self.autoSpan.setStyleSheet('background-color:#31363b')

    def setMultipleThread(self):
        self.multipleThread = not self.multipleThread
        if self.multipleThread:
            self.multiCheck.setStyleSheet('background-color:#3daee9')
        else:
            self.multiCheck.setStyleSheet('background-color:#31363b')
Ejemplo n.º 10
0
    def ui_components(self):

        font = QFont("Roboto", 16)
        title_label = QLabel("Convert currency:", self)
        title_label.move(7, 27)
        title_label.setFont(font)
        title_label.adjustSize()
        to_be_converted = QLineEdit(self)
        to_be_converted.setPlaceholderText("Amount")
        to_be_converted.setFont(font)
        to_be_converted.move(7, 67)
        to_be_converted.setFixedWidth(230)
        valid = QDoubleValidator()
        to_be_converted.setValidator(valid)
        converted = QLineEdit(self)
        converted.setPlaceholderText("Converted Amount")
        converted.isEnabled = False
        converted.move(7, 107)
        converted.setFixedWidth(230)
        converted.setFont(font)
        converted.setValidator(valid)
        currency_list_1 = QComboBox(self)
        currency_list_1.addItem("USD")
        currency_list_1.addItem("TND")
        currency_list_1.addItem("EUR")
        currency_list_1.move(260, 66)
        currency_list_2 = QComboBox(self)
        currency_list_2.addItem("USD")
        currency_list_2.addItem("TND")
        currency_list_2.addItem("EUR")
        currency_list_2.move(260, 100)
        convert_btn = QPushButton("Convert", self)
        convert_btn.move(260, 140)
        menubar = QMenuBar(self)
        Info = menubar.addMenu("Info")
        exchange = Info.addAction("Exchange rates")
        exchange.triggered.connect(self.open_exchange_rates)

        def convertor():

            if str(currency_list_1.currentText()) == "USD" or str(
                    currency_list_2.currentText()) == "USD":
                # ============== USD AND TND ==================
                if str(currency_list_2.currentText()) == "TND":
                    rate_usd_tnd = Exchanges().usd_tnd()
                    converted_amount = float(
                        to_be_converted.text()) * float(rate_usd_tnd)
                    if to_be_converted != '':
                        converted.setText(str(converted_amount))

                if str(currency_list_1.currentText()) == "TND":
                    rate_usd_tnd = Exchanges().usd_tnd()
                    converted_amount = float(to_be_converted.text()) * float(
                        1 / rate_usd_tnd)
                    if to_be_converted != '':
                        converted.setText(str(converted_amount))

                # =============== EUR AND USD =================

                if str(currency_list_2.currentText()) == "EUR":
                    rate_usd_eur = Exchanges().usd_eur()
                    converted_amount = float(
                        to_be_converted.text()) * float(rate_usd_eur)
                    if to_be_converted != '':
                        converted.setText(str(converted_amount))

                if str(currency_list_1.currentText()) == "EUR":
                    rate_usd_eur = Exchanges().usd_eur()
                    converted_amount = float(to_be_converted.text()) * float(
                        1 / rate_usd_eur)
                    if to_be_converted != '':
                        converted.setText(str(converted_amount))
            if (currency_list_1.currentText()) == "TND" or (
                    currency_list_2.currentText()) == "TND":

                if str(currency_list_2.currentText()) == "EUR":
                    rate_tnd_eur = Exchanges().tnd_eur()
                    converted_amount = float(
                        to_be_converted.text()) * float(rate_tnd_eur)
                    if to_be_converted != '':
                        converted.setText(str(converted_amount))

                if str(currency_list_1.currentText()) == "EUR":
                    rate_tnd_eur = Exchanges().tnd_eur()
                    converted_amount = float(to_be_converted.text()) * float(
                        1 / rate_tnd_eur)
                    if to_be_converted != '':
                        converted.setText(str(converted_amount))

        convert_btn.clicked.connect(convertor)
Ejemplo n.º 11
0
class VOGView(AbstractView):
    def __init__(self,
                 name: str = "VOG_NONE",
                 log_handlers: [StreamHandler] = None):
        self._logger = getLogger(__name__)
        if log_handlers:
            for h in log_handlers:
                self._logger.addHandler(h)
        self._logger.debug("Initializing")
        super().__init__(name)
        """ Min size for the VOG window """
        self._subwindow_height = 222
        self._subwindow_width = 518
        """ min and max sizes for the configuration popup (width, height) """
        self._popup_min = (229, 409)
        self._popup_max = (300, 409)
        """ Set configuration value display area"""
        self._config_frame = EasyFrame()
        self._config_vertical_layout = QVBoxLayout(self._config_frame)
        self._config_label = QLabel(self._config_frame)
        self._config_label.setAlignment(Qt.AlignCenter)
        self._config_val_line_edit = QLineEdit(self._config_frame)
        self._config_val_line_edit.setAlignment(Qt.AlignCenter)

        self._config_vertical_layout.addWidget(self._config_label)
        self._config_vertical_layout.addWidget(self._config_val_line_edit)
        """ Set preset button selection area. """
        self._nhtsa_button = ClickAnimationButton()
        self._eblindfold_button = ClickAnimationButton()
        self._direct_control_button = ClickAnimationButton()
        """ Set open duration, close duration, and debounce time settings display area. """
        self._input_box_frame = EasyFrame()
        self._input_box_grid_layout = QGridLayout(self._input_box_frame)
        self._input_box_grid_layout.setContentsMargins(0, 6, 0, 6)

        self._open_dur_label = QLabel(self._input_box_frame)
        self._open_dur_line_edit = QLineEdit(self._input_box_frame)
        self._open_dur_line_edit.setFixedWidth(80)
        self._open_inf_check_box = QCheckBox(self._input_box_frame)

        self._close_dur_label = QLabel(self._input_box_frame)
        self._close_dur_line_edit = QLineEdit(self._input_box_frame)
        self._close_dur_line_edit.setFixedWidth(80)
        self._close_inf_check_box = QCheckBox(self._input_box_frame)

        self._debounce_label = QLabel(self._input_box_frame)
        self._debounce_time_line_edit = QLineEdit(self._input_box_frame)
        self._debounce_time_line_edit.setFixedWidth(80)

        self._input_box_grid_layout.addWidget(self._open_dur_label, 0, 0, 1, 1)
        self._input_box_grid_layout.addWidget(self._open_dur_line_edit, 0, 1,
                                              1, 1)
        self._input_box_grid_layout.addWidget(self._open_inf_check_box, 0, 2,
                                              1, 1)
        self._input_box_grid_layout.addWidget(self._close_dur_label, 1, 0, 1,
                                              1)
        self._input_box_grid_layout.addWidget(self._close_dur_line_edit, 1, 1,
                                              1, 1)
        self._input_box_grid_layout.addWidget(self._close_inf_check_box, 1, 2,
                                              1, 1)
        self._input_box_grid_layout.addWidget(self._debounce_label, 2, 0, 1, 1)
        self._input_box_grid_layout.addWidget(self._debounce_time_line_edit, 2,
                                              1, 1, 1)
        """ Set button mode setting display area. """
        self._button_mode_frame = EasyFrame()
        self._button_mode_horiz_layout = QGridLayout(self._button_mode_frame)
        self._button_mode_horiz_layout.setContentsMargins(0, 6, 0, 6)
        self._button_mode_label = QLabel(self._button_mode_frame)
        self._button_mode_selector = QComboBox(self._button_mode_frame)

        self._button_mode_selector.addItem("")
        self._button_mode_selector.addItem("")

        self._button_mode_horiz_layout.addWidget(self._button_mode_label, 0, 0,
                                                 1, 1)
        self._button_mode_horiz_layout.addWidget(self._button_mode_selector, 0,
                                                 1, 1, 1)
        """ Set control mode setting display area. """
        self._control_mode_label = QLabel(self._button_mode_frame)
        self._control_mode_selector = QComboBox(self._button_mode_frame)

        self._control_mode_selector.addItem("")
        self._control_mode_selector.addItem("")

        self._button_mode_horiz_layout.addWidget(self._control_mode_label, 1,
                                                 0, 1, 1)
        self._button_mode_horiz_layout.addWidget(self._control_mode_selector,
                                                 1, 1, 1, 1)
        """ Set upload button selection area. """
        self._upload_settings_button = ClickAnimationButton()
        """ Set manual control selection area. """
        self._manual_control_button_frame = EasyFrame()
        self._manual_control_button_layout = QHBoxLayout(
            self._manual_control_button_frame)

        self._manual_control_open_button = ClickAnimationButton()
        self._manual_control_close_button = ClickAnimationButton()

        self._manual_control_button_layout.addWidget(
            self._manual_control_open_button)
        self._manual_control_button_layout.addWidget(
            self._manual_control_close_button)
        self._manual_control_button_layout.setMargin(0)
        """ device settings display """
        self._dev_sets_frame = EasyFrame()

        self._dev_sets_layout = QVBoxLayout(self._dev_sets_frame)

        self.config_button = ClickAnimationButton()
        self.config_button.clicked.connect(self._config_button_handler)

        self._config_win = ConfigPopUp()
        self._config_win.setMinimumSize(self._popup_min[0], self._popup_min[1])
        self._config_win.setMaximumSize(self._popup_max[0], self._popup_max[1])
        self._config_win.setLayout(self._dev_sets_layout)
        """ Add widgets to layout. """
        self._dev_sets_layout.addWidget(self._config_frame)
        self._dev_sets_layout.addWidget(self._input_box_frame)
        self._dev_sets_layout.addWidget(self._button_mode_frame)
        self._dev_sets_layout.addWidget(self._nhtsa_button)
        self._dev_sets_layout.addWidget(self._eblindfold_button)
        self._dev_sets_layout.addWidget(self._direct_control_button)
        self._dev_sets_layout.addWidget(self._upload_settings_button)

        self.layout().addWidget(self.config_button, 0, 0,
                                Qt.AlignTop | Qt.AlignRight)
        self.config_button.setFixedSize(30, 25)

        self.layout().addWidget(self._manual_control_button_frame, 0, 0,
                                Qt.AlignBottom | Qt.AlignLeft)
        self._manual_control_open_button.setFixedSize(70, 25)
        self._manual_control_close_button.setFixedSize(70, 25)

        self.layout().setMargin(0)

        self._strings = dict()
        self._lang_enum = LangEnum.ENG
        self.setMinimumSize(self._subwindow_width, self._subwindow_height)
        self.resize(self._subwindow_width, self._subwindow_height)
        self._logger.debug("Initialized")

    def add_graph(self, graph) -> None:
        """
        Add Graph to view.
        :return None:
        """
        self._logger.debug("running")
        self.layout().addWidget(graph, 0, 0)
        self.config_button.raise_()
        self._manual_control_button_frame.raise_()
        self._logger.debug("done")

    def _config_button_handler(self) -> None:
        """
        handles the config button
        :return None:
        """
        self._logger.debug("running")
        self._config_win.exec_()
        self._logger.debug("done")

    def set_config_val_line_edit_handler(self, func: classmethod) -> None:
        """
        Sets the config val line handler.
        :param func: classmethod that handles the config val line.
        :return None:
        """
        self._logger.debug("running")
        self._config_val_line_edit.textChanged.connect(func)
        self._logger.debug("done")

    def set_nhtsa_button_handler(self, func: classmethod) -> None:
        """
        Sets NHTSA button press handler.
        :param func: classmethod that handles the NHTSA button.
        :return None:
        """
        self._logger.debug("running")
        self._nhtsa_button.clicked.connect(func)
        self._logger.debug("done")

    def set_eblindfold_button_handler(self, func: classmethod) -> None:
        """
        Sets eBlindfold button press handler.
        :param func: classmethod that handles the eBlindfold button.
        :return None:
        """
        self._logger.debug("running")
        self._eblindfold_button.clicked.connect(func)
        self._logger.debug("done")

    def set_direct_control_button_handler(self, func: classmethod) -> None:
        """
        Sets Direct Control button press handler.
        :param func: classmethod that handles the Direct Control button.
        :return None:
        """
        self._logger.debug("running")
        self._direct_control_button.clicked.connect(func)
        self._logger.debug("done")

    def set_open_dur_line_edit_handler(self, func: classmethod) -> None:
        """
        Sets open duration line edit handler.
        :param func: classmethod that handles the line edit.
        :return None:
        """
        self._logger.debug("running")
        self._open_dur_line_edit.textChanged.connect(func)
        self._logger.debug("done")

    def set_close_dur_line_edit_handler(self, func: classmethod) -> None:
        """
        Sets close duration line edit handler.
        :param func: classmethod that handles the line edit.
        :return None:
        """
        self._logger.debug("running")
        self._close_dur_line_edit.textChanged.connect(func)
        self._logger.debug("done")

    def set_open_inf_check_box_handler(self, func: classmethod) -> None:
        """
        Sets open INF checkbox handler.
        :param func: classmethod that handles the checkbox, requires bool param.
        :return None:
        """
        self._logger.debug("running")
        self._open_inf_check_box.stateChanged.connect(func)
        self._logger.debug("done")

    def set_close_inf_check_box_handler(self, func: classmethod) -> None:
        """
        Sets close INF checkbox handler.
        :param func: classmethod that handles the checkbox, requires bool param.
        :return None:
        """
        self._logger.debug("running")
        self._close_inf_check_box.stateChanged.connect(func)
        self._logger.debug("done")

    def set_debounce_time_line_edit_handler(self, func: classmethod) -> None:
        """
        Sets debounce time line edit handler.
        :param func: classmethod that handles the line edit.
        :return None:
        """
        self._logger.debug("running")
        self._debounce_time_line_edit.textChanged.connect(func)
        self._logger.debug("done")

    def set_button_mode_selector_handler(self, func: classmethod) -> None:
        """
        Sets button mode combo box handler.
        :param func: classmethod that handles the combo.
        :return None:
        """
        self._logger.debug("running")
        self._button_mode_selector.currentIndexChanged.connect(func)
        self._logger.debug("done")

    def set_control_mode_selector_handler(self, func: classmethod) -> None:
        """
        Sets button mode combo box handler.
        :param func: classmethod that handles the combo.
        :return None:
        """
        self._logger.debug("running")
        self._control_mode_selector.currentIndexChanged.connect(func)
        self._logger.debug("done")

    def set_upload_settings_button_handler(self, func: classmethod) -> None:
        """
        Sets upload settings button handler.
        :param func: classmethod that handles the button.
        :return None:
        """
        self._logger.debug("running")
        self._upload_settings_button.clicked.connect(func)
        self._logger.debug("done")

    def set_manual_control_open_button_handler(self,
                                               func: classmethod) -> None:
        """
        Sets manual open button handler.
        :param func: classmethod that handles the button.
        :return None:
        """
        self._logger.debug("running")
        self._manual_control_open_button.clicked.connect(func)
        self._logger.debug("done")

    def set_manual_control_close_button_handler(self,
                                                func: classmethod) -> None:
        """
        Sets manual close button handler.
        :param func: classmethod that handles the button.
        :return None:
        """
        self._logger.debug("running")
        self._manual_control_close_button.clicked.connect(func)
        self._logger.debug("done")

    @property
    def config_text(self) -> str:
        """
        Get the string value found in the config text box.
        :return str: string value in the text box.
        """
        return self._config_val_line_edit.text()

    @config_text.setter
    def config_text(self, val: str) -> None:
        """
        Set the string value found in the config text box.
        :param val: string value to set the config text box.
        :return None:
        """
        self._logger.debug("running")
        self._config_val_line_edit.setText(val)
        self._logger.debug("done")

    @property
    def open_duration(self) -> str:
        """
        Get the string value found in the open duration text box.
        :return str: string value in the text box.
        """
        return self._open_dur_line_edit.text()

    @open_duration.setter
    def open_duration(self, val: str) -> None:
        """
        Set the string value found in the open duration text box.
        :param val: string value to set the open duration text box.
        :return None:
        """
        self._logger.debug("running")
        self._open_dur_line_edit.setText(val)
        self._logger.debug("done")

    @property
    def close_duration(self) -> str:
        """
        Get the string value found in the close duration text box.
        :return str: string value in the text box.
        """
        return self._close_dur_line_edit.text()

    @close_duration.setter
    def close_duration(self, val: str) -> None:
        """
        Set the string value found in the close duration text box.
        :param val: string value to set the close duration text box.
        :return None:
        """
        self._logger.debug("running")
        self._close_dur_line_edit.setText(val)
        self._logger.debug("done")

    @property
    def debounce_val(self) -> str:
        """
        Get the string value found in the debounce time text box.
        :return str: string value in the text box.
        """
        return self._debounce_time_line_edit.text()

    @debounce_val.setter
    def debounce_val(self, val: str) -> None:
        """
        Set the string value found in the debounce time text box.
        :param val: string value to set the debounce text box.
        :return None:
        """
        self._logger.debug("running")
        self._debounce_time_line_edit.setText(val)
        self._logger.debug("done")

    @property
    def open_inf_check_box(self) -> bool:
        """
        Get the check box state.
        :return bool: returns true if the box is checked.
        """
        return self._open_inf_check_box.isChecked()

    @open_inf_check_box.setter
    def open_inf_check_box(self, val: bool) -> None:
        """
        Set the check box state.
        :param val: bool value to set the check box.
        :return None:
        """
        self._logger.debug("running")
        self._open_inf_check_box.setChecked(val)
        self._logger.debug("done")

    @property
    def close_inf_check_box(self) -> bool:
        """
        Get the check box state.
        :return bool: returns true if the box is checked.
        """
        return self._close_inf_check_box.isChecked()

    @close_inf_check_box.setter
    def close_inf_check_box(self, val: bool) -> None:
        """
        Set the check box state.
        :param val: bool value to set the check box.
        :return None:
        """
        self._logger.debug("running")
        self._close_inf_check_box.setChecked(val)
        self._logger.debug("done")

    @property
    def button_mode(self) -> int:
        """
        Get index of button mode.
        :return int: index of current button mode.
        """
        return self._button_mode_selector.currentIndex()

    @button_mode.setter
    def button_mode(self, val: int) -> None:
        """
        Set index of button mode.
        :return None:
        """
        self._logger.debug("running")
        self._button_mode_selector.setCurrentIndex(val)
        self._logger.debug("done")

    @property
    def control_mode(self) -> int:
        """
        Get index of button mode.
        :return int: index of current button mode.
        """
        return self._control_mode_selector.currentIndex()

    @control_mode.setter
    def control_mode(self, val: int) -> None:
        """
        Set index of button mode.
        :return None:
        """
        self._logger.debug("running")
        self._control_mode_selector.setCurrentIndex(val)
        self._logger.debug("done")

    def set_open_dur_err(self, err: bool) -> None:
        """
        Set this text entry to error style depending on err.
        :param err: If this text entry needs to be error styel
        :return None:
        """
        self._logger.debug("running")
        if err:
            self._open_dur_line_edit.setStyleSheet(tab_line_edit_error_style)
        else:
            self._open_dur_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self._logger.debug("done")

    def set_close_dur_err(self, err: bool) -> None:
        """
        Set this text entry to error style depending on err.
        :param err: If this text entry needs to be error styel
        :return None:
        """
        self._logger.debug("running")
        if err:
            self._close_dur_line_edit.setStyleSheet(tab_line_edit_error_style)
        else:
            self._close_dur_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self._logger.debug("done")

    def set_debounce_err(self, err: bool) -> None:
        """
        Set this text entry to error style depending on err.
        :param err: If this text entry needs to be error styel
        :return None:
        """
        self._logger.debug("running")
        if err:
            self._debounce_time_line_edit.setStyleSheet(
                tab_line_edit_error_style)
        else:
            self._debounce_time_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self._logger.debug("done")

    @property
    def language(self) -> LangEnum:
        """
        Get the current language setting
        :return LangEnum: The current language enumerator being used
        """
        return self._lang_enum

    @language.setter
    def language(self, lang: LangEnum) -> None:
        """
        Set the language for this view object and reload the text and tooltips.
        :param lang: the language to use.
        :return None:
        """
        self._logger.debug("running")
        self._strings = strings[lang]
        self._set_texts()
        self._set_tooltips()
        self._logger.debug("done")

    def set_upload_button(self, is_active: bool) -> None:
        """
        Set upload button activity to is_active.
        :param is_active: Whether this button should be active.
        :return None:
        """
        self._logger.debug("running")
        self._upload_settings_button.setEnabled(is_active)
        self._logger.debug("done")

    def _set_texts(self) -> None:
        """
        Set text fields of view object.
        :return None:
        """
        self._logger.debug("running")
        self._config_label.setText(self._strings[StringsEnum.CONFIG_LABEL])
        self._config_val_line_edit.setText(
            self._strings[StringsEnum.CONFIG_LABEL])
        self._nhtsa_button.setText(self._strings[StringsEnum.NHTSA_LABEL])
        self._eblindfold_button.setText(
            self._strings[StringsEnum.EBLIND_LABEL])
        self._direct_control_button.setText(
            self._strings[StringsEnum.DCON_LABEL])
        self._open_dur_label.setText(
            self._strings[StringsEnum.OPEN_DURATION_LABEL])
        self._open_inf_check_box.setText(self._strings[StringsEnum.INF_LABEL])
        self._close_dur_label.setText(
            self._strings[StringsEnum.CLOSE_DURATION_LABEL])
        self._close_inf_check_box.setText(self._strings[StringsEnum.INF_LABEL])
        self._debounce_label.setText(self._strings[StringsEnum.DEBOUNCE_LABEL])
        self._button_mode_label.setText(
            self._strings[StringsEnum.BUTTON_MODE_LABEL])
        self._button_mode_selector.setItemText(
            0, self._strings[StringsEnum.HOLD_VAL_LABEL])
        self._button_mode_selector.setItemText(
            1, self._strings[StringsEnum.CLICK_VAL_LABEL])
        self._control_mode_label.setText(
            self._strings[StringsEnum.CONTROL_MODE_LABEL])
        self._control_mode_selector.setItemText(
            0, self._strings[StringsEnum.LENS_VAL_LABEL])
        self._control_mode_selector.setItemText(
            1, self._strings[StringsEnum.TRIAL_VAL_LABEL])
        self._upload_settings_button.setText(
            self._strings[StringsEnum.UPLOAD_BUTTON_LABEL])
        self._manual_control_open_button.setText(
            self._strings[StringsEnum.MANUAL_OPEN_LABEL])
        self._manual_control_close_button.setText(
            self._strings[StringsEnum.MANUAL_CLOSE_LABEL])
        self.config_button.setText(self._strings[StringsEnum.CONFIG_TAB_LABEL])
        self.config_button.setText("...")
        self._config_win.setWindowTitle(
            self.get_name() + " " +
            self._strings[StringsEnum.CONFIG_TAB_LABEL])
        self._logger.debug("done")

    def _set_tooltips(self) -> None:
        """
        Set tooltip text fields of view object.
        :return None:
        """
        self._logger.debug("running")
        self._config_label.setToolTip(
            self._strings[StringsEnum.CONFIG_LABEL_TOOLTIP])
        self._config_val_line_edit.setToolTip(
            self._strings[StringsEnum.CONFIG_LABEL_TOOLTIP])
        self._open_dur_label.setToolTip(
            self._strings[StringsEnum.OPEN_DURATION_TOOLTIP])
        self._close_dur_label.setToolTip(
            self._strings[StringsEnum.CLOSE_DURATION_TOOLTIP])
        self._debounce_label.setToolTip(
            self._strings[StringsEnum.DEBOUNCE_TOOLTIP])
        self._button_mode_label.setToolTip(
            self._strings[StringsEnum.BUTTON_MODE_TOOLTIP])
        self._control_mode_label.setToolTip(
            self._strings[StringsEnum.CONTROL_MODE_TOOLTIP])
        self._upload_settings_button.setToolTip(
            self._strings[StringsEnum.UPLOAD_BUTTON_TOOLTIP])
        self._manual_control_open_button.setToolTip(
            self._strings[StringsEnum.MANUAL_OPEN_TOOLTIP])
        self._manual_control_close_button.setToolTip(
            self._strings[StringsEnum.MANUAL_CLOSE_TOOLTIP])
        self.config_button.setToolTip(
            self._strings[StringsEnum.CONFIG_TAB_TOOLTIP])
        self._logger.debug("done")
Ejemplo n.º 12
0
class SettingsEditionDialog(QDialog):

    languages = {"Français": "fr", "English": "en"}

    def __init__(self):
        QDialog.__init__(self)

        self.setWindowTitle(tr("btn_config"))
        self.setFixedSize(QSize(700, 670))

        # Retrieve current settings
        self.settings = AssetManager.getInstance().config_to_dico(
            AssetManager.getInstance().get_config_parser())
        self.__restart_needed = False
        self.__restore_required = False

        # Version
        self.lab_version = QLabel(self.settings['main']['version'])

        # Language
        self.combo_language = QComboBox()
        self.combo_language.addItems(list(self.languages.keys()))
        for lang in self.languages:  # Look for the current language to select it
            if self.languages[lang] == self.settings['main']['language']:
                self.combo_language.setCurrentText(lang)
                break

        # CSV separator
        self.csv_sep_edit = QLineEdit()
        self.csv_sep_edit.setMaxLength(2)
        self.csv_sep_edit.setFixedWidth(25)
        self.csv_sep_edit.setAlignment(Qt.AlignCenter)
        self.csv_sep_edit.setText(self.settings['main']['csv_separator'])

        # BDD path
        self.btn_bdd_path = QPushButton(self.settings['main']['bdd_path'])
        self.btn_bdd_path.clicked.connect(self.choose_bdd_path)

        # Port
        self.wepapp_port = QSpinBox()
        self.wepapp_port.setMinimum(1024)
        self.wepapp_port.setMaximum(65535)
        self.wepapp_port.setValue(int(self.settings['webapp']['port']))

        # Colors
        self.tile_color = ColorChooser(self.settings['colors']['tile'])
        self.hovered_tile_color = ColorChooser(
            self.settings['colors']['hovered_tile'])
        self.hovered_empty_tile_color = ColorChooser(
            self.settings['colors']['hovered_empty_tile'])
        self.dragged_tile_color = ColorChooser(
            self.settings['colors']['dragged_tile'])
        self.drag_selected_tile_color = ColorChooser(
            self.settings['colors']['drag_selected_tile'])
        self.selected_tile_color = ColorChooser(
            self.settings['colors']['selected_tile'])
        self.tile_text_color = ColorChooser(
            self.settings['colors']['tile_text'])
        self.room_bg_color = ColorChooser(self.settings['colors']['room_bg'])
        self.room_grid_color = ColorChooser(
            self.settings['colors']['room_grid'])
        self.main_bg_color = ColorChooser(self.settings['colors']['main_bg'])
        self.board_bg_color = ColorChooser(self.settings['colors']['board_bg'])

        self.attr_colors = ""  # Chosen colors
        self.attributes_colors_chooser = AttrColorsChooser(
            self.settings['colors']['attr_colors'].split())

        # Sizes (unmodifiable)
        self.unmodifiable = QLabel(tr("unmodifiable_data"))
        self.unmodifiable.setAlignment(Qt.AlignCenter)
        self.desk_size = QLineEdit(self.settings['size']['desk'])
        self.desk_size.setEnabled(False)
        self.desk_size.setFixedWidth(50)
        self.grid_rows = QLineEdit(self.settings['size']['default_room_rows'])
        self.grid_rows.setEnabled(False)
        self.grid_rows.setFixedWidth(50)
        self.grid_cols = QLineEdit(
            self.settings['size']['default_room_columns'])
        self.grid_cols.setEnabled(False)
        self.grid_cols.setFixedWidth(50)

        # --- Buttons ---

        # Confirm button
        self.ok_btn = QPushButton(tr("btn_save"))
        self.ok_btn.clicked.connect(self.accept)
        self.ok_btn.setFocus()

        # Cancel button
        self.cancel_btn = QPushButton(tr("btn_cancel"))
        self.cancel_btn.clicked.connect(self.reject)

        # Restore defaults button
        self.restore_btn = QPushButton(tr("btn_restore"))
        self.restore_btn.clicked.connect(self.__restore)

        self.__set_layout()

    def __set_layout(self) -> None:
        """
        Sets the dialog layout
        """
        # Main layout
        layout = QVBoxLayout()
        layout.setMargin(0)
        layout.addSpacing(5)

        # Main section
        main_layout = QFormLayout()
        main_layout.addRow(tr("app_version"), self.lab_version)
        main_layout.addRow(tr("language"), self.combo_language)
        main_layout.addRow(tr("csv_sep"), self.csv_sep_edit)
        main_layout.addRow(tr("bdd_path"), self.btn_bdd_path)

        # Web app
        widget_port = QWidget()
        layout_port = QHBoxLayout()
        layout_port.setMargin(0)
        layout_port.addWidget(self.wepapp_port)
        layout_port.addWidget(ShutDownToolTip())
        widget_port.setLayout(layout_port)
        main_layout.addRow(tr("web_port"), widget_port)

        layout.addLayout(main_layout)
        Separator(self.width(), layout)

        # Colors
        colors_layout1 = QFormLayout()
        colors_layout1.addRow(tr("tile"), self.tile_color)
        colors_layout1.addRow(tr("hovered_tile"), self.hovered_tile_color)
        colors_layout1.addRow(tr("hovered_empty_tile"),
                              self.hovered_empty_tile_color)
        colors_layout1.addRow(tr("dragged_tile"), self.dragged_tile_color)
        colors_layout1.addRow(tr("drag_selected_tile"),
                              self.drag_selected_tile_color)
        colors_layout1.addRow(tr("selected_tile"), self.selected_tile_color)

        colors_layout2 = QFormLayout()
        colors_layout2.addRow(tr("tile_text"), self.tile_text_color)
        colors_layout2.addRow(tr("room_bg"), self.room_bg_color)
        colors_layout2.addRow(tr("room_grid"), self.room_grid_color)
        colors_layout2.addRow(tr("main_bg"), self.main_bg_color)
        colors_layout2.addRow(tr("board_bg"), self.board_bg_color)

        colors_layout = QHBoxLayout()
        colors_layout.setMargin(0)
        colors_layout.addLayout(colors_layout1)
        colors_layout.addLayout(colors_layout2)

        layout.addLayout(colors_layout)
        layout.addSpacing(15)

        colors_layout3 = QFormLayout()
        colors_layout3.setMargin(0)
        colors_layout3.addRow(tr("attr_colors"),
                              self.attributes_colors_chooser)
        layout.addLayout(colors_layout3)

        Separator(self.width(), layout)

        # Unmodifiable data
        sizes_layout = QFormLayout()
        sizes_layout.setMargin(0)
        sizes_layout.addRow(tr("desk_size"), self.desk_size)
        sizes_layout.addRow(tr("grid_rows"), self.grid_rows)
        sizes_layout.addRow(tr("grid_cols"), self.grid_cols)

        layout.addWidget(self.unmodifiable, alignment=Qt.AlignCenter)
        layout.addSpacing(5)
        layout.addLayout(sizes_layout)

        Separator(self.width(), layout)

        # Buttons
        layout_buttons = QHBoxLayout()
        layout_buttons.addWidget(self.ok_btn)
        layout_buttons.addWidget(self.restore_btn)
        layout_buttons.addWidget(self.cancel_btn)

        layout.addLayout(layout_buttons)
        self.setLayout(layout)

        self.setStyleSheet(get_stylesheet("dialog2"))

    def __restore(self) -> None:
        """
        Restore default parameters before closing dialog
        """
        self.__restart_needed = True
        self.__restore_required = True
        self.accept()

    def __new_settings(self) -> dict:
        """
        Retrieves the new settings to use
        """
        settings = self.settings

        # Language
        language = self.languages[self.combo_language.currentText()]
        if language != settings['main']['language']:
            settings['main']['language'] = language
            self.__restart_needed = True

        # CSV separator
        settings['main']['csv_separator'] = self.csv_sep_edit.text()

        # BDD path
        if self.btn_bdd_path.text() != settings['main']['bdd_path']:
            if self.btn_bdd_path.text().endswith("sdc_db"):
                settings['main']['bdd_path'] = self.btn_bdd_path.text()
            else:
                settings['main']['bdd_path'] = ""
            self.__restart_needed = True

        # Port
        if str(self.wepapp_port.value()) != settings['webapp']['port']:
            settings['webapp']['port'] = str(self.wepapp_port.value())

        # Colors
        settings['colors']['tile'] = self.tile_color.get_color()
        settings['colors']['hovered_tile'] = self.hovered_tile_color.get_color(
        )
        settings['colors'][
            'hovered_empty_tile'] = self.hovered_empty_tile_color.get_color()
        settings['colors']['dragged_tile'] = self.dragged_tile_color.get_color(
        )
        settings['colors'][
            'drag_selected_tile'] = self.drag_selected_tile_color.get_color()
        settings['colors'][
            'selected_tile'] = self.selected_tile_color.get_color()
        settings['colors']['tile_text'] = self.tile_text_color.get_color()
        settings['colors']['room_grid'] = self.room_grid_color.get_color()

        if self.room_bg_color.get_color() != settings['colors']['room_bg']:
            settings['colors']['room_bg'] = self.room_bg_color.get_color()
            self.__restart_needed = True

        if self.main_bg_color.get_color() != settings['colors']['main_bg']:
            settings['colors']['main_bg'] = self.main_bg_color.get_color()
            self.__restart_needed = True

        if self.board_bg_color.get_color() != settings['colors']['board_bg']:
            settings['colors']['board_bg'] = self.board_bg_color.get_color()
            self.__restart_needed = True

        settings['colors']['attr_colors'] = self.attr_colors

        return settings

    def new_config(self) -> ConfigParser:
        """
        Retrieves the new config parser object
        """
        conf = ConfigParser()
        conf.read_dict(self.__new_settings())

        return conf

    def need_restart(self):
        return self.__restart_needed

    def restore_default(self) -> bool:
        return self.__restore_required

    def accept(self) -> None:
        """
        Performs actions before calling parent's accept method
        """
        self.attr_colors = self.attributes_colors_chooser.get_colors_to_str()
        super().accept()

    def choose_bdd_path(self) -> None:
        """
        Opens a file chooser to select the bdd path. Then sets the name as button text.
        """
        bdd_path = QFileDialog.getOpenFileName(self, tr("bdd_path"),
                                               self.btn_bdd_path.text())[0]

        if bdd_path:
            self.btn_bdd_path.setText(bdd_path)
Ejemplo n.º 13
0
class SyncConfig(QDialog):
    def __init__(self, instance, parent=None):
        super().__init__(parent)

        self.setWindowTitle("Configure BinSync")

        if binsync is None:
            QMessageBox(self).critical(None, 'Dependency error',
                                       "binsync is not installed. Please install binsync first.")
            self.close()

        # initialization
        self._instance = instance

        self._main_layout = QVBoxLayout()
        self._user_edit = None  # type:QLineEdit
        self._repo_edit = None  # type:QLineEdit
        self._remote_edit = None  # type:QLineEdit
        self._initrepo_checkbox = None  # type:QCheckBox

        self._init_widgets()

        self.setLayout(self._main_layout)

        self.show()

    #
    # Private methods
    #

    def _init_widgets(self):

        upper_layout = QGridLayout()

        # user label
        user_label = QLabel(self)
        user_label.setText("User name")

        self._user_edit = QLineEdit(self)
        self._user_edit.setText("user0_angrm")

        row = 0
        upper_layout.addWidget(user_label, row, 0)
        upper_layout.addWidget(self._user_edit, row, 1)
        row += 1

        # binsync label
        binsync_label = QLabel(self)
        binsync_label.setText("Git repo")

        # repo path
        self._repo_edit = QLineEdit(self)
        self._repo_edit.textChanged.connect(self._on_repo_textchanged)
        self._repo_edit.setFixedWidth(150)

        # repo path selection button
        repo_button = QPushButton(self)
        repo_button.setText("...")
        repo_button.clicked.connect(self._on_repo_clicked)
        repo_button.setFixedWidth(40)

        upper_layout.addWidget(binsync_label, row, 0)
        upper_layout.addWidget(self._repo_edit, row, 1)
        upper_layout.addWidget(repo_button, row, 2)
        row += 1

        # clone from a remote URL
        remote_label = QLabel(self)
        remote_label.setText("Remote URL")
        self._remote_edit = QLineEdit(self)
        self._remote_edit.setEnabled(False)

        upper_layout.addWidget(remote_label, row, 0)
        upper_layout.addWidget(self._remote_edit, row, 1)
        row += 1

        # initialize repo checkbox
        self._initrepo_checkbox = QCheckBox(self)
        self._initrepo_checkbox.setText("Initialize repo")
        self._initrepo_checkbox.setToolTip("I'm the first user of this sync repo and I'd like to initialize it as a new "
                                     "repo.")
        self._initrepo_checkbox.setChecked(False)
        self._initrepo_checkbox.setEnabled(False)

        upper_layout.addWidget(self._initrepo_checkbox, row, 1)
        row += 1

        # buttons
        ok_button = QPushButton(self)
        ok_button.setText("OK")
        ok_button.setDefault(True)
        ok_button.clicked.connect(self._on_ok_clicked)

        cancel_button = QPushButton(self)
        cancel_button.setText("Cancel")
        cancel_button.clicked.connect(self._on_cancel_clicked)

        buttons_layout = QHBoxLayout()
        buttons_layout.addWidget(ok_button)
        buttons_layout.addWidget(cancel_button)

        # main layout
        self._main_layout.addLayout(upper_layout)
        self._main_layout.addLayout(buttons_layout)

    #
    # Event handlers
    #

    def _on_ok_clicked(self):
        proj = self._instance.project
        user = self._user_edit.text()
        path = self._repo_edit.text()

        if not user:
            QMessageBox(self).critical(None, "Invalid user name",
                                       "User name cannot be empty."
                                       )
            return

        if not os.path.isdir(path):
            QMessageBox(self).critical(None, "Repo does not exist",
                                       "The specified sync repo does not exist."
                                       )
            return

        # TODO: Add a user ID to angr management
        if not self.is_git_repo(path):
            init_repo = self._initrepo_checkbox.isChecked()
            remote_url = self._remote_edit.text()
        else:
            init_repo = False
            remote_url = None

        self._instance.sync.connect(user, path, init_repo=init_repo, remote_url=remote_url)
        self._instance.workspace.view_manager.first_view_in_category('sync').reload()
        self.close()

    def _on_repo_clicked(self):
        dir = QFileDialog.getExistingDirectory(self, "Select sync repo", "",
                                               QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
        self._repo_edit.setText(QDir.toNativeSeparators(dir))

    def _on_repo_textchanged(self, new_text):
        # is it a git repo?
        if not self.is_git_repo(new_text.strip()):
            # no it's not
            # maybe we want to clone from the remote side?
            self._remote_edit.setEnabled(True)
            self._initrepo_checkbox.setEnabled(True)
        else:
            # yes it is!
            # we don't want to initialize it or allow cloning from the remote side
            self._remote_edit.setEnabled(False)
            self._initrepo_checkbox.setEnabled(False)

    def _on_cancel_clicked(self):
        self.close()

    #
    # Static methods
    #

    @staticmethod
    def is_git_repo(path):
        return os.path.isdir(os.path.join(path, ".git"))
Ejemplo n.º 14
0
class Ui_FE14CharacterEditor(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.search_bar = QLineEdit()
        self.search_bar.setPlaceholderText("Search...")
        self.search_bar.setFixedWidth(225)
        self.characters_list_view = QListView()
        self.characters_list_view.setContextMenuPolicy(
            QtCore.Qt.CustomContextMenu)
        self.characters_list_view.setFixedWidth(225)
        self.characters_list_layout = QVBoxLayout()
        self.characters_list_layout.addWidget(self.search_bar)
        self.characters_list_layout.addWidget(self.characters_list_view)

        self.character_details_box = QGroupBox(title="Character Details")
        self.portrait_display = QGraphicsView()
        self.portrait_display.setFixedSize(140, 140)
        self.character_details_form_contents_1 = QWidget()
        self.character_details_form_contents_2 = QWidget()
        self.character_details_layout = QHBoxLayout()
        self.character_details_layout.addWidget(self.portrait_display)
        self.character_details_layout.addWidget(
            self.character_details_form_contents_1)
        self.character_details_layout.addWidget(
            self.character_details_form_contents_2)
        self.character_details_box.setLayout(self.character_details_layout)
        self.character_details_box.setFixedHeight(200)

        self.tab_widget = QTabWidget()
        self.ids_tab = QWidget()
        self.classes_tab = QWidget()
        self.stats_tab = QScrollArea()
        self.skills_tab = QScrollArea()
        self.misc_tab = QScrollArea()
        self.portraits_tab = PortraitViewer()

        self.stats_contents = QWidget()
        self.stats_tab.setWidget(self.stats_contents)
        self.stats_tab.setWidgetResizable(True)
        self.stats_layout = QVBoxLayout()
        self.stats_layout.setAlignment(QtCore.Qt.AlignTop)
        self.stats_contents.setLayout(self.stats_layout)

        self.skills_contents = QWidget()
        self.skills_tab.setWidget(self.skills_contents)
        self.skills_tab.setWidgetResizable(True)

        self.misc_contents = QWidget()
        self.misc_tab.setWidget(self.misc_contents)
        self.misc_tab.setWidgetResizable(True)
        self.misc_layout = QVBoxLayout()
        self.misc_layout.setAlignment(QtCore.Qt.AlignTop)
        self.misc_contents.setLayout(self.misc_layout)

        self.tab_widget.addTab(self.ids_tab, "IDs")
        self.tab_widget.addTab(self.classes_tab, "Classes")
        self.tab_widget.addTab(self.stats_tab, "Stats")
        self.tab_widget.addTab(self.skills_tab, "Skills")
        self.tab_widget.addTab(self.misc_tab, "Misc.")
        self.tab_widget.addTab(self.portraits_tab, "Portraits")

        self.editor_layout = QVBoxLayout()
        self.editor_layout.addWidget(self.character_details_box)
        self.editor_layout.addWidget(self.tab_widget)

        self.main_layout = QHBoxLayout()
        self.main_layout.addLayout(self.characters_list_layout)
        self.visual_splitter = QFrame()
        self.visual_splitter.setFrameShape(QFrame.VLine)
        self.visual_splitter.setFrameShadow(QFrame.Sunken)
        self.main_layout.addWidget(self.visual_splitter)
        self.main_layout.addLayout(self.editor_layout)

        self.tool_bar = QToolBar()
        self.action_add = QAction(text="Add")
        self.action_remove = QAction(text="Remove")
        self.action_copy_to = QAction(text="Copy To")
        self.tool_bar.addActions(
            [self.action_add, self.action_remove, self.action_copy_to])

        self.addToolBar(self.tool_bar)

        self.resize(1000, 600)
        central_widget = QWidget()
        central_widget.setLayout(self.main_layout)
        self.setWindowTitle("Character Editor")
        self.setWindowIcon(QIcon("paragon.ico"))
        self.setCentralWidget(central_widget)
Ejemplo n.º 15
0
class Natang_mayammd(QWidget):
    '''
    mayaからmmdモデルへエクスポートするためのウィンドウ
    '''
    def __init__(self, parent):
        QWidget.__init__(self)
        self.parent = parent
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setWindowTitle('~ Maya > MMD ~')
        self.setStyleSheet('font-size: 15px; color: #ddf;')
        vbl = QVBoxLayout()
        self.setLayout(vbl)

        self.file_khatangton = os.path.join(os.path.dirname(__file__), 'asset',
                                            'khatangton2.txt')
        try:
            with open(self.file_khatangton, 'r', encoding='utf-8') as f:
                chue_tem_file = f.readline().split('=')[-1].strip()
                satsuan = f.readline().split('=')[-1].strip()
                chai_bs = int(f.readline().split('=')[-1].strip())
                chai_kraduk = int(f.readline().split('=')[-1].strip())
                chai_watsadu = int(f.readline().split('=')[-1].strip())
                lok_tex = int(f.readline().split('=')[-1].strip())
                thangmot = int(f.readline().split('=')[-1].strip())
                pit_mai = int(f.readline().split('=')[-1].strip())
        except:
            chue_tem_file = ''
            satsuan = '0.125'
            chai_bs = True
            chai_kraduk = True
            chai_watsadu = True
            lok_tex = False
            thangmot = False
            pit_mai = True

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addWidget(QLabel('ファイル'))
        self.le_chue_file = QLineEdit(chue_tem_file)
        hbl.addWidget(self.le_chue_file)
        self.le_chue_file.setFixedWidth(300)
        self.le_chue_file.textChanged.connect(self.chue_thuk_kae)
        self.btn_khon_file = QPushButton('...')
        hbl.addWidget(self.btn_khon_file)
        self.btn_khon_file.clicked.connect(self.khon_file)

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addWidget(QLabel('尺度'))
        self.le_satsuan = QLineEdit(satsuan)
        hbl.addWidget(self.le_satsuan)
        self.le_satsuan.setFixedWidth(100)
        self.le_satsuan.textEdited.connect(self.satsuan_thuk_kae)
        hbl.addWidget(QLabel('×'))
        hbl.addStretch()

        self.cb_chai_kraduk = QCheckBox('骨も作る')
        vbl.addWidget(self.cb_chai_kraduk)
        self.cb_chai_kraduk.setChecked(chai_kraduk)

        self.cb_chai_bs = QCheckBox('モーフも作る')
        vbl.addWidget(self.cb_chai_bs)
        self.cb_chai_bs.setChecked(chai_bs)

        self.cb_chai_watsadu = QCheckBox('材質を使う')
        vbl.addWidget(self.cb_chai_watsadu)
        self.cb_chai_watsadu.setChecked(chai_watsadu)

        self.cb_lok_tex = QCheckBox('テクスチャファイルをコピーする')
        vbl.addWidget(self.cb_lok_tex)
        self.cb_lok_tex.setChecked(lok_tex)

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addWidget(QLabel('使うポリゴン'))
        self.btng = QButtonGroup()
        self.rb_thangmot = QRadioButton('全部')
        hbl.addWidget(self.rb_thangmot)
        self.btng.addButton(self.rb_thangmot)
        self.rb_thilueak = QRadioButton('選択されている')
        hbl.addWidget(self.rb_thilueak)
        self.btng.addButton(self.rb_thilueak)
        hbl.addStretch()

        if (thangmot):
            self.rb_thangmot.setChecked(True)
        else:
            self.rb_thilueak.setChecked(True)

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addStretch()
        self.btn_roem_sang = QPushButton('作成開始')
        hbl.addWidget(self.btn_roem_sang)
        self.btn_roem_sang.clicked.connect(self.roem_sang)
        self.btn_roem_sang.setFixedSize(220, 50)
        self.chue_thuk_kae(self.le_chue_file.text())
        self.cb_pit = QCheckBox('終わったらこの\nウィンドウを閉じる')
        hbl.addWidget(self.cb_pit)
        self.cb_pit.setChecked(pit_mai)

    def khon_file(self):
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
        chue_file, ok = QFileDialog.getSaveFileName(filter='PMX (*.pmx)')
        if (ok):
            self.le_chue_file.setText(chue_file)
        self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
        self.show()

    def chue_thuk_kae(self, chue_file):
        sakun = chue_file.split('.')[-1]
        sang_dai = (sakun.lower() == 'pmx')
        self.btn_roem_sang.setEnabled(sang_dai)
        self.btn_roem_sang.setStyleSheet(
            ['text-decoration: line-through; color: #aab;', ''][sang_dai])

    def satsuan_thuk_kae(self, kha):
        try:
            float(kha)
        except:
            self.le_satsuan.setText('1')

    def roem_sang(self):
        chue_tem_file = self.le_chue_file.text()
        try:
            satsuan = float(self.le_satsuan.text())
        except:
            self.le_satsuan.setText('1')
            satsuan = 1.
        chai_watsadu = self.cb_chai_watsadu.isChecked()
        chai_bs = self.cb_chai_bs.isChecked()
        chai_kraduk = self.cb_chai_kraduk.isChecked()
        lok_tex = self.cb_lok_tex.isChecked()
        thangmot = self.btng.checkedButton() == self.rb_thangmot
        mayapaipmx.sang(chue_tem_file, satsuan, chai_kraduk, chai_bs,
                        chai_watsadu, lok_tex, thangmot)

        pit_mai = self.cb_pit.isChecked()
        with open(self.file_khatangton, 'w', encoding='utf-8') as f:
            f.write('ファイルの名前 = %s\n' % chue_tem_file)
            f.write('尺度 = %f\n' % satsuan)
            f.write('ブレンドシェープ = %d\n' % chai_bs)
            f.write('ジョイント = %d\n' % chai_kraduk)
            f.write('材質 = %d\n' % chai_watsadu)
            f.write('テクスチャのコピー = %d\n' % lok_tex)
            f.write('ポリゴン全部 = %d\n' % thangmot)
            f.write('閉じる = %d\n' % pit_mai)

        if (pit_mai):
            self.close()

    def keyPressEvent(self, e):
        if (e.key() == Qt.Key_Escape):
            self.close()

    def closeEvent(self, e):
        self.parent.natangyoi['mayammd'] = None
Ejemplo n.º 16
0
class Preferences(QDialog):
    def __init__(self, prefs, icon=None):
        super().__init__()
        self.prefs = prefs
        self.hotkey_format_regex = r'^\<ctrl\>\+\<alt\>(\+\<shift\>)?\+[a-zA-Z0-9]$'
        if icon:
            self.setWindowIcon(icon)

        # checkbox: Include Minimized
        include_minimized = QCheckBox()
        include_minimized.setFixedWidth(35)
        include_minimized.setChecked(self.prefs["include_minimized"]["value"])
        include_minimized.stateChanged.connect(
            lambda: self.include_minimized(include_minimized.isChecked()))
        include_minimized_descr = QLabel(
            self.prefs["include_minimized"]["description"])
        include_minimized_descr.setWordWrap(True)

        include_minimized_layout = QHBoxLayout()
        include_minimized_layout.addWidget(include_minimized)
        include_minimized_layout.addWidget(include_minimized_descr)

        include_minimized_groupbox = QGroupBox("Include Minimized")
        include_minimized_groupbox.setLayout(include_minimized_layout)

        # checkbox: snap to grid
        snap_to_grid = QCheckBox()
        snap_to_grid.setFixedWidth(35)
        snap_to_grid.setChecked(self.prefs["snap_to_grid"]["value"])
        snap_to_grid.stateChanged.connect(
            lambda: self.snap_to_grid(snap_to_grid.isChecked()))
        snap_to_grid_descr = QLabel(self.prefs["snap_to_grid"]["description"])
        snap_to_grid_descr.setWordWrap(True)

        snap_to_grid_layout = QHBoxLayout()
        snap_to_grid_layout.addWidget(snap_to_grid)
        snap_to_grid_layout.addWidget(snap_to_grid_descr)

        snap_to_grid_groupbox = QGroupBox("Snap To Grid")
        snap_to_grid_groupbox.setLayout(snap_to_grid_layout)

        # checkbox: fit into screen
        fit_into_screen = QCheckBox()
        fit_into_screen.setFixedWidth(35)
        fit_into_screen.setChecked(self.prefs["fit_into_screen"]["value"])
        fit_into_screen.stateChanged.connect(
            lambda: self.fit_into_screen(fit_into_screen.isChecked()))
        fit_into_screen_descr = QLabel(
            self.prefs["fit_into_screen"]["description"])
        fit_into_screen_descr.setWordWrap(True)

        fit_into_screen_layout = QHBoxLayout()
        fit_into_screen_layout.addWidget(fit_into_screen)
        fit_into_screen_layout.addWidget(fit_into_screen_descr)

        fit_into_screen_groupbox = QGroupBox("Fit Into Screen")
        fit_into_screen_groupbox.setLayout(fit_into_screen_layout)

        # doublespinBox: match cutoff
        match_cutoff = QDoubleSpinBox()
        match_cutoff.setFixedWidth(35)
        match_cutoff.setValue(self.prefs["match_cutoff"]["value"])
        match_cutoff.setRange(0.1, 1.0)
        match_cutoff.setSingleStep(0.1)
        match_cutoff.setDecimals(1)
        match_cutoff.valueChanged.connect(
            lambda: self.match_cutoff(match_cutoff.value()))
        match_cutoff_descr = QLabel(self.prefs["match_cutoff"]["description"])
        match_cutoff_descr.setWordWrap(True)

        match_cutoff_layout = QHBoxLayout()
        match_cutoff_layout.addWidget(match_cutoff)
        match_cutoff_layout.addWidget(match_cutoff_descr)

        match_cutoff_groupbox = QGroupBox("Match Cutoff")
        match_cutoff_groupbox.setLayout(match_cutoff_layout)

        # checkbox: enable hotkeys
        enable_hotkeys = QCheckBox()
        enable_hotkeys.setFixedWidth(35)
        enable_hotkeys.setChecked(self.prefs["enable_hotkeys"]["value"])
        enable_hotkeys.stateChanged.connect(
            lambda: self.enable_hotkeys(enable_hotkeys.isChecked()))
        enable_hotkeys_descr = QLabel(
            self.prefs["enable_hotkeys"]["description"])
        enable_hotkeys_descr.setWordWrap(True)

        enable_hotkeys_layout = QHBoxLayout()
        enable_hotkeys_layout.addWidget(enable_hotkeys)
        enable_hotkeys_layout.addWidget(enable_hotkeys_descr)

        # lineedit: hotkeys shortcuts
        hotkey_freeze_new_name = QLabel("Freeze New:")
        hotkey_freeze_new_name.setFixedWidth(75)
        self.hotkey_freeze_new_status = QLabel()
        self.hotkey_freeze_new = QLineEdit(
            self.prefs["hotkeys"]["value"]["freeze_new"])
        self.hotkey_freeze_new.setFixedWidth(140)
        self.hotkey_freeze_new.editingFinished.connect(
            lambda: self.hotkey_freeze_new_update(self.hotkey_freeze_new.text(
            )))
        self.hotkey_freeze_new.cursorPositionChanged.connect(
            self.hotkey_freeze_new_status.clear)

        hotkey_freeze_new_layout = QHBoxLayout()
        hotkey_freeze_new_layout.addWidget(hotkey_freeze_new_name)
        hotkey_freeze_new_layout.addWidget(self.hotkey_freeze_new)
        hotkey_freeze_new_layout.addWidget(self.hotkey_freeze_new_status)

        hotkey_freeze_all_name = QLabel("Freeze All:")
        hotkey_freeze_all_name.setFixedWidth(75)
        self.hotkey_freeze_all_status = QLabel()
        self.hotkey_freeze_all = QLineEdit(
            self.prefs["hotkeys"]["value"]["freeze_all"])
        self.hotkey_freeze_all.setFixedWidth(140)
        self.hotkey_freeze_all.editingFinished.connect(
            lambda: self.hotkey_freeze_all_update(self.hotkey_freeze_all.text(
            )))
        self.hotkey_freeze_all.cursorPositionChanged.connect(
            self.hotkey_freeze_all_status.clear)

        hotkey_freeze_all_layout = QHBoxLayout()
        hotkey_freeze_all_layout.addWidget(hotkey_freeze_all_name)
        hotkey_freeze_all_layout.addWidget(self.hotkey_freeze_all)
        hotkey_freeze_all_layout.addWidget(self.hotkey_freeze_all_status)

        hotkey_restore_name = QLabel("Restore:")
        hotkey_restore_name.setFixedWidth(75)
        self.hotkey_restore_status = QLabel()
        self.hotkey_restore = QLineEdit(
            self.prefs["hotkeys"]["value"]["restore"])
        self.hotkey_restore.setFixedWidth(140)
        self.hotkey_restore.editingFinished.connect(
            lambda: self.hotkey_restore_update(self.hotkey_restore.text()))
        self.hotkey_restore.cursorPositionChanged.connect(
            self.hotkey_restore_status.clear)

        hotkey_restore_layout = QHBoxLayout()
        hotkey_restore_layout.addWidget(hotkey_restore_name)
        hotkey_restore_layout.addWidget(self.hotkey_restore)
        hotkey_restore_layout.addWidget(self.hotkey_restore_status)

        self.hotkeys_statusbar = QLabel()
        self.hotkeys_statusbar.setWordWrap(True)
        self.hotkeys_statusbar.setText(hotkeys_statusbar_map[
            self.prefs['enable_hotkeys']['value']]['text'])
        self.hotkeys_statusbar.setStyleSheet(hotkeys_statusbar_map[
            self.prefs['enable_hotkeys']['value']]['style'])

        close_button = QPushButton("Close")
        close_button.setMaximumWidth(75)
        close_button.clicked.connect(self.close)

        hotkeys_statusbar_layout = QHBoxLayout()
        hotkeys_statusbar_layout.addWidget(self.hotkeys_statusbar)
        hotkeys_statusbar_layout.addWidget(close_button)

        hotkeys_layout = QVBoxLayout()
        hotkeys_layout.addLayout(hotkey_freeze_new_layout)
        hotkeys_layout.addLayout(hotkey_freeze_all_layout)
        hotkeys_layout.addLayout(hotkey_restore_layout)

        self.hotkeys_groupbox = QGroupBox()
        self.hotkeys_groupbox.setFlat(True)
        self.hotkeys_groupbox.setDisabled(
            not self.prefs["enable_hotkeys"]["value"])
        self.hotkeys_groupbox.setLayout(hotkeys_layout)

        enable_hotkeys_outer_layout = QVBoxLayout()
        enable_hotkeys_outer_layout.addLayout(enable_hotkeys_layout)
        enable_hotkeys_outer_layout.addWidget(self.hotkeys_groupbox)

        enable_hotkeys_groupbox = QGroupBox("Enable Hotkeys")
        enable_hotkeys_groupbox.setLayout(enable_hotkeys_outer_layout)

        # Create main layout and add widgets
        main_layout = QVBoxLayout()
        main_layout.addWidget(include_minimized_groupbox)
        main_layout.addWidget(snap_to_grid_groupbox)
        main_layout.addWidget(fit_into_screen_groupbox)
        main_layout.addWidget(match_cutoff_groupbox)
        main_layout.addWidget(enable_hotkeys_groupbox)
        main_layout.addWidget(self.hotkeys_groupbox)
        #main_layout.addWidget(hotkeys_statusbar_groupbox)
        main_layout.addLayout(hotkeys_statusbar_layout)
        self.setLayout(main_layout)

    def include_minimized(self, isChecked):
        print(f'include_minimized: {isChecked}')
        self.prefs["include_minimized"]["value"] = isChecked

    def snap_to_grid(self, isChecked):
        print(f'snap_to_grid: {isChecked}')
        self.prefs["snap_to_grid"]["value"] = isChecked

    def fit_into_screen(self, isChecked):
        print(f'fit_into_screen: {isChecked}')
        self.prefs["fit_into_screen"]["value"] = isChecked

    def match_cutoff(self, value):
        rounded_value = round(value, 1)
        print(f'match_cutoff: {rounded_value}')
        self.prefs["match_cutoff"]["value"] = rounded_value

    def enable_hotkeys(self, isChecked):
        print(f'enable_hotkeys: {isChecked}')
        self.prefs["enable_hotkeys"]["value"] = isChecked
        self.hotkeys_groupbox.setDisabled(not isChecked)
        self.hotkeys_statusbar.setText(
            hotkeys_statusbar_map[isChecked]['text'])
        self.hotkeys_statusbar.setStyleSheet(
            hotkeys_statusbar_map[isChecked]['style'])

    def hotkey_freeze_new_update(self, text):
        print(f'hotkey_freeze_new: {text}')
        if re.match(self.hotkey_format_regex, text):
            self.prefs["hotkeys"]["value"]["freeze_new"] = text
            self.hotkey_freeze_new_status.setText(f'Updated!')
            self.hotkey_freeze_new_status.setStyleSheet("color: green;")
        else:
            self.hotkey_freeze_new.setText(
                self.prefs["hotkeys"]["value"]["freeze_new"])
            self.hotkey_freeze_new_status.setText(
                'Failed to update: unsupported format')
            self.hotkey_freeze_new_status.setStyleSheet("color: red;")

    def hotkey_freeze_all_update(self, text):
        print(f'hotkey_freeze_all: {text}')
        if re.match(self.hotkey_format_regex, text):
            self.prefs["hotkeys"]["value"]["freeze_all"] = text
            self.hotkey_freeze_all_status.setText(f'Updated!')
            self.hotkey_freeze_all_status.setStyleSheet("color: green;")
        else:
            self.hotkey_freeze_all.setText(
                self.prefs["hotkeys"]["value"]["freeze_all"])
            self.hotkey_freeze_all_status.setText(
                'Failed to update: unsupported format')
            self.hotkey_freeze_all_status.setStyleSheet("color: red;")

    def hotkey_restore_update(self, text):
        print(f'hotkey_restore: {text}')
        if re.match(self.hotkey_format_regex, text):
            self.prefs["hotkeys"]["value"]["restore"] = text
            self.hotkey_restore_status.setText(f'Updated!')
            self.hotkey_restore_status.setStyleSheet("color: green;")
        else:
            self.hotkey_restore.setText(
                self.prefs["hotkeys"]["value"]["restore"])
            self.hotkey_restore_status.setText(
                'Failed to update: unsupported format')
            self.hotkey_restore_status.setStyleSheet("color: red;")
Ejemplo n.º 17
0
class VideoPlayer(QWidget):
    def __init__(self, aPath, parent=None):
        super(VideoPlayer, self).__init__(parent)

        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAcceptDrops(True)
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback)
        self.mediaPlayer.mediaStatusChanged.connect(self.printMediaData)
        self.mediaPlayer.setVolume(80)
        self.videoWidget = QVideoWidget(self)

        self.lbl = QLineEdit('00:00:00')
        self.lbl.setReadOnly(True)
        self.lbl.setFixedWidth(70)
        self.lbl.setUpdatesEnabled(True)
        self.lbl.setStyleSheet(stylesheet(self))
        self.lbl.selectionChanged.connect(lambda: self.lbl.setSelection(0, 0))

        self.elbl = QLineEdit('00:00:00')
        self.elbl.setReadOnly(True)
        self.elbl.setFixedWidth(70)
        self.elbl.setUpdatesEnabled(True)
        self.elbl.setStyleSheet(stylesheet(self))
        self.elbl.selectionChanged.connect(
            lambda: self.elbl.setSelection(0, 0))

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedWidth(32)
        self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setStyleSheet(stylesheet(self))
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True)

        self.clip = QApplication.clipboard()
        self.process = QProcess(self)
        self.process.readyRead.connect(self.dataReady)
        self.process.finished.connect(self.playFromURL)

        self.myurl = ""

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(5, 0, 5, 0)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.lbl)
        controlLayout.addWidget(self.positionSlider)
        controlLayout.addWidget(self.elbl)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.videoWidget)
        layout.addLayout(controlLayout)

        self.setLayout(layout)

        self.myinfo = "©2016\nAxel Schneider\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \
                "LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \
                "SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes"

        self.widescreen = True

        #### shortcuts ####
        self.shortcut = QShortcut(QKeySequence("q"), self)
        self.shortcut.activated.connect(self.handleQuit)
        self.shortcut = QShortcut(QKeySequence("u"), self)
        self.shortcut.activated.connect(self.playFromURL)

        self.shortcut = QShortcut(QKeySequence("y"), self)
        self.shortcut.activated.connect(self.getYTUrl)

        self.shortcut = QShortcut(QKeySequence("o"), self)
        self.shortcut.activated.connect(self.openFile)
        self.shortcut = QShortcut(QKeySequence(" "), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence("f"), self)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence("i"), self)
        self.shortcut.activated.connect(self.handleInfo)
        self.shortcut = QShortcut(QKeySequence("s"), self)
        self.shortcut.activated.connect(self.toggleSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self)
        self.shortcut.activated.connect(self.volumeUp)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self)
        self.shortcut.activated.connect(self.volumeDown)
        self.shortcut = QShortcut(
            QKeySequence(Qt.ShiftModifier + Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider10)
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left),
                                  self)
        self.shortcut.activated.connect(self.backSlider10)

        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)

        print("QT5 Player started")
        print("press 'o' to open file (see context menu for more)")
        self.suspend_screensaver()

    def mouseDoubleClickEvent(self, event):
        self.handleFullscreen()

    def playFromURL(self):
        self.mediaPlayer.pause()
        self.myurl = self.clip.text()
        self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()
        self.hideSlider()
        print(self.myurl)

    def getYTUrl(self):
        cmd = "youtube-dl -g -f best " + self.clip.text()
        print("grabbing YouTube URL")
        self.process.start(cmd)

    def dataReady(self):
        self.myurl = str(self.process.readAll(), encoding='utf8').rstrip()  ###
        self.myurl = self.myurl.partition("\n")[0]
        print(self.myurl)
        self.clip.setText(self.myurl)
        self.playFromURL()

    def suspend_screensaver(self):
        'suspend linux screensaver'
        proc = subprocess.Popen(
            'gsettings set org.gnome.desktop.screensaver idle-activation-enabled false',
            shell=True)
        proc.wait()

    def resume_screensaver(self):
        'resume linux screensaver'
        proc = subprocess.Popen(
            'gsettings set org.gnome.desktop.screensaver idle-activation-enabled true',
            shell=True)
        proc.wait()

    def openFile(self):
        fileName, _ = QFileDialog.getOpenFileName(
            self, "Open Movie",
            QDir.homePath() + "/Videos",
            "Media (*.webm *.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v *.3gp *.mp3 *.m4a *.wav *.ogg *.flac *.m3u *.m3u8)"
        )

        if fileName != '':
            self.loadFilm(fileName)
            print("File loaded")

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()

    def mediaStateChanged(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPlay))

    def positionChanged(self, position):
        self.positionSlider.setValue(position)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.mediaPlayer.position())
        self.lbl.setText(mtime.toString())

    def durationChanged(self, duration):
        self.positionSlider.setRange(0, duration)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

    def setPosition(self, position):
        self.mediaPlayer.setPosition(position)

    def handleError(self):
        self.playButton.setEnabled(False)
        print("Error: ", self.mediaPlayer.errorString())

    def handleQuit(self):
        self.mediaPlayer.stop()
        self.resume_screensaver()
        print("Goodbye ...")
        app.quit()

    def contextMenuRequested(self, point):
        menu = QMenu()
        actionFile = menu.addAction(QIcon.fromTheme("video-x-generic"),
                                    "open File (o)")
        actionclipboard = menu.addSeparator()
        actionURL = menu.addAction(QIcon.fromTheme("browser"),
                                   "URL from Clipboard (u)")
        actionclipboard = menu.addSeparator()
        actionYTurl = menu.addAction(QIcon.fromTheme("youtube"),
                                     "URL from YouTube (y)")
        actionclipboard = menu.addSeparator()
        actionToggle = menu.addAction(QIcon.fromTheme("next"),
                                      "show / hide Slider (s)")
        actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"),
                                    "Fullscreen (f)")
        action169 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "16 : 9")
        action43 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "4 : 3")
        actionSep = menu.addSeparator()
        actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "Info (i)")
        action5 = menu.addSeparator()
        actionQuit = menu.addAction(QIcon.fromTheme("application-exit"),
                                    "Exit (q)")

        actionFile.triggered.connect(self.openFile)
        actionQuit.triggered.connect(self.handleQuit)
        actionFull.triggered.connect(self.handleFullscreen)
        actionInfo.triggered.connect(self.handleInfo)
        actionToggle.triggered.connect(self.toggleSlider)
        actionURL.triggered.connect(self.playFromURL)
        actionYTurl.triggered.connect(self.getYTUrl)
        action169.triggered.connect(self.screen169)
        action43.triggered.connect(self.screen43)
        menu.exec_(self.mapToGlobal(point))

    def wheelEvent(self, event):
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mscale = event.angleDelta().y() / 5
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth + mscale,
                             round((mwidth + mscale) / 1.778))
        else:
            self.setGeometry(mleft, mtop, mwidth + mscale,
                             round((mwidth + mscale) / 1.33))
        #elif self.positionSlider.hasFocus():
        #    self.positionSlider.value = self.positionSlider.value + 5

    def screen169(self):
        self.widescreen = True
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.778
        self.setGeometry(mleft, mtop, mwidth, round(mwidth / mratio))

    def screen43(self):
        self.widescreen = False
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.33
        self.setGeometry(mleft, mtop, mwidth, round(mwidth / mratio))

    def handleFullscreen(self):
        if self.windowState() & Qt.WindowFullScreen:
            QApplication.setOverrideCursor(Qt.ArrowCursor)
            self.showNormal()
            print("no Fullscreen")
        else:
            self.showFullScreen()
            QApplication.setOverrideCursor(Qt.BlankCursor)
            print("Fullscreen entered")

    def handleInfo(self):
        msg = QMessageBox.about(self, "QT5 Player", self.myinfo)

    def toggleSlider(self):
        if self.positionSlider.isVisible():
            self.hideSlider()
        else:
            self.showSlider()

    def hideSlider(self):
        self.playButton.hide()
        self.lbl.hide()
        self.positionSlider.hide()
        self.elbl.hide()
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.778))
        else:
            self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.33))

    def showSlider(self):
        self.playButton.show()
        self.lbl.show()
        self.positionSlider.show()
        self.elbl.show()
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.55))
        else:
            self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.33))

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60)

    def forwardSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000 * 60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60)

    def backSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000 * 60)

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def mousePressEvent(self, evt):
        self.oldPos = evt.globalPos()

    def mouseMoveEvent(self, evt):
        delta = QPoint(evt.globalPos() - self.oldPos)
        self.move(self.x() + delta.x(), self.y() + delta.y())
        self.oldPos = evt.globalPos()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasText():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        print("drop")
        if event.mimeData().hasUrls():
            url = event.mimeData().urls()[0].toString()
            print("url = ", url)
            self.mediaPlayer.stop()
            self.mediaPlayer.setMedia(QMediaContent(QUrl(url)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
        elif event.mimeData().hasText():
            mydrop = event.mimeData().text()
            ### YouTube url
            if "youtube" in mydrop:
                print("is YouTube", mydrop)
                self.clip.setText(mydrop)
                self.getYTUrl()
            else:
                ### normal url
                print("generic url = ", mydrop)
                self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop)))
                self.playButton.setEnabled(True)
                self.mediaPlayer.play()
                self.hideSlider()

    def loadFilm(self, f):
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()

    def printMediaData(self):
        if self.mediaPlayer.mediaStatus() == 6:
            if self.mediaPlayer.isMetaDataAvailable():
                res = str(self.mediaPlayer.metaData("Resolution")).partition(
                    "PyQt5.QtCore.QSize(")[2].replace(", ",
                                                      "x").replace(")", "")
                print("%s%s" % ("Video Resolution = ", res))
                if int(res.partition("x")[0]) / int(
                        res.partition("x")[2]) < 1.5:
                    self.screen43()
                else:
                    self.screen169()
            else:
                print("no metaData available")

    def openFileAtStart(self, filelist):
        matching = [s for s in filelist if ".myformat" in s]
        if len(matching) > 0:
            self.loadFilm(matching)
Ejemplo n.º 18
0
class inputField(QWidget):
    def __init__(self,
                 label,
                 text=None,
                 value_type=VALUETYPE.STRING,
                 ipRegex=None,
                 input_width=50,
                 parent=None,
                 callback=None,
                 runner=None):
        QWidget.__init__(self, parent)
        self.parent = parent
        self.__label = label
        self.input_width = input_width

        self.__ipRegex = ipRegex
        if value_type != VALUETYPE.STRING:
            self.__text = str(text)
            if not self.__ipRegex:
                self.__ipRegex = QRegExp("^[1-9]\\d{,3}$")
        else:
            self.__text = text

        self.callback = callback
        self.__runner = runner

        self.gui_init()

    def gui_init(self):

        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        label = QLabel(self.__label, self)
        layout.addWidget(label, 0, 0, Qt.AlignCenter)

        self.__edit = QLineEdit(self.__text, self)
        self.__edit.setFixedWidth(self.input_width)
        if self.__ipRegex:
            ipValidator = QRegExpValidator(self.__ipRegex)
            self.__edit.setValidator(ipValidator)
        layout.addWidget(self.__edit, 0, 1, Qt.AlignCenter)

        self.__edit.textChanged.connect(self.__changed__)

        if self.callback:
            self.__edit.textEdited.connect(partial(self.callback))

        if self.__runner:
            run_but = QPushButton(self)
            run_but.setText(self.parent.qapp.tr("Run"))
            layout.addWidget(run_but, 0, 3, Qt.AlignCenter)

            run_but.pressed.connect(self.__runner__)

    def __runner__(self):
        self.__runner(self.__text)

    def __changed__(self, text):
        if not text:
            if self.__text != "-":
                self.__edit.setText(self.__text)
            else:
                self.__edit.setText("0")
        else:
            self.__text = text

    def getText(self):
        return self.__text

    def setText(self, text):
        self.__edit.setText(text)
Ejemplo n.º 19
0
class SpotExtractor(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle("Spot Extractor")

        menuBar = self.buildMenuBar()
        widget = QWidget(self)
        layout = QGridLayout(widget)

        # Main Image Window
        self.scrollArea = QScrollArea()
        self.imageLabel = ImageLabel(self)
        self.scrollArea.setWidget(self.imageLabel)

        # Text Label for Lot Name
        self.lotNameTextField = QLineEdit()
        self.lotNameTextField.setFixedWidth(300)

        # Spot List
        self.spotList = SpotListWidget(self)

        # Image Box Layout
        imageGroupBox = QGroupBox("Image")
        imageLayout = QHBoxLayout()
        imageLayout.addWidget(self.scrollArea)
        imageGroupBox.setLayout(imageLayout)

        # Spot List Box Layout
        rightGroupBox = QGroupBox()
        rightGroupBox.setMaximumWidth(300)
        rightGroupLayout = QVBoxLayout()

        lotNameGroupBox = QGroupBox("Lot Name")
        lotNameLayout = QHBoxLayout()
        lotNameLayout.addWidget(self.lotNameTextField)
        lotNameGroupBox.setLayout(lotNameLayout)

        spotsGroupBox = QGroupBox("Spot List")
        spotsLayout = QHBoxLayout()
        spotsLayout.addWidget(self.spotList)
        spotsGroupBox.setLayout(spotsLayout)

        rightGroupLayout.addWidget(lotNameGroupBox)
        rightGroupLayout.addWidget(spotsGroupBox)
        rightGroupBox.setLayout(rightGroupLayout)

        # Control Buttons Box Layout
        horizontalGroupBox = QGroupBox("Control Buttons")
        controlButtonLayout = QHBoxLayout()
        checkAllButton = QPushButton("Check All")
        uncheckAllButton = QPushButton("Uncheck All")
        deleteCheckedButton = QPushButton("Delete Checked")
        checkAllButton.clicked.connect(self.checkAll)
        uncheckAllButton.clicked.connect(self.uncheckAll)
        deleteCheckedButton.clicked.connect(self.deleteAllChecked)
        controlButtonLayout.addWidget(checkAllButton)
        controlButtonLayout.addWidget(uncheckAllButton)
        controlButtonLayout.addWidget(deleteCheckedButton)
        horizontalGroupBox.setLayout(controlButtonLayout)

        layout.addWidget(imageGroupBox, 0, 0)
        layout.addWidget(rightGroupBox, 0, 1)
        layout.addWidget(horizontalGroupBox, 1, 0, 1, 2)

        self.setMenuBar(menuBar)
        self.setLayout(layout)
        self.setCentralWidget(widget)

    def buildMenuBar(self):
        menuBar = QMenuBar(self)

        fileMenu = QMenu("File")
        loadImageAction = QAction("Load Image", self)
        loadDataAction = QAction("Load Lot Data", self)
        saveDataAction = QAction("Save Lot Data", self)
        exitAction = QAction("Exit", self)

        # Set Trigger for each Action
        loadImageAction.triggered.connect(self.loadImage)
        loadDataAction.triggered.connect(self.loadData)
        saveDataAction.triggered.connect(self.saveData)
        exitAction.triggered.connect(QtGui.qApp.quit)

        # Add actions to menu
        fileMenu.addAction(loadImageAction)
        fileMenu.addAction(loadDataAction)
        fileMenu.addAction(saveDataAction)
        fileMenu.addAction(exitAction)

        menuBar.addMenu(fileMenu)
        return menuBar

    def loadImage(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "Load Image",
            "",
            "PNG Files (*.png);;JPEG Files (*.jpg)",
            options=options)
        if fileName:
            mat = cv.imread(fileName, cv.IMREAD_UNCHANGED)
            self.imageLabel.setImage(mat)

    def loadData(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,
                                                  "Load JSON Data",
                                                  "",
                                                  "JSON Files (*.json)",
                                                  options=options)
        if fileName:
            f = open(fileName, "r")
            j = json.load(f)
            self.lotNameTextField.setText(j["lotName"])
            for spot in j["spots"]:
                p1 = int(spot["topLeft"][0]), int(spot["topLeft"][1])
                p2 = int(spot["topRight"][0]), int(spot["topRight"][1])
                p3 = int(spot["bottomLeft"][0]), int(spot["bottomLeft"][1])
                p4 = int(spot["bottomRight"][0]), int(spot["bottomRight"][1])
                realID = int(spot["realID"])
                id = int(spot["spotID"])
                s = Spot([p1, p2, p3, p4], realID, id)
                self.spotList.addSpot(s)
            self.imageLabel.resetOriginal()
            self.imageLabel.drawSpots()
            self.imageLabel.updateView()

    def saveData(self):
        lotData["spots"].clear()
        lotData["lotName"] = self.lotNameTextField.text()
        for i in range(len(self.spotList)):
            s = self.spotList.spots[i]
            spotData = {
                "spotID": i,
                "realID": s.realID,
                "topLeft": s.points[0],
                "topRight": s.points[1],
                "bottomLeft": s.points[2],
                "bottomRight": s.points[3],
            }
            lotData["spots"].append(spotData)

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(self,
                                                  "Save JSON Data",
                                                  "",
                                                  "JSON Files (*.json)",
                                                  options=options)
        if fileName:
            jsonData = json.dumps(lotData, indent=2)
            if not fileName.endswith(".json"):
                fileName = fileName + ".json"
            f = open(fileName, "w")
            f.write(jsonData)
            f.flush()
            f.close()

    def checkAll(self):
        for i in range(len(self.spotList)):
            self.spotList.item(i).setCheckState(Qt.Checked)
        self.imageLabel.resetOriginal()
        self.imageLabel.drawSpots()
        self.imageLabel.updateView()

    def uncheckAll(self):
        for i in range(len(self.spotList)):
            self.spotList.item(i).setCheckState(Qt.Unchecked)
        self.imageLabel.resetOriginal()
        self.imageLabel.updateView()

    def deleteAllChecked(self):
        for i in range(len(self.spotList) - 1, -1, -1):
            if self.spotList.item(i).checkState() == Qt.Checked:
                self.spotList.removeSpot(i)
        self.imageLabel.resetOriginal()
        self.imageLabel.drawSpots()
        self.imageLabel.updateView()
Ejemplo n.º 20
0
class Natang_mmdmaya(QWidget):
    '''
    mmdモデルからmayaへインポートするためのウィンドウ
    '''
    def __init__(self, parent):
        QWidget.__init__(self)
        self.setAcceptDrops(True)
        self.parent = parent
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setWindowTitle('~ MMD > Maya ~')
        self.setStyleSheet('font-size: 15px; color: #ddf;')
        vbl = QVBoxLayout()
        self.setLayout(vbl)

        self.file_khatangton = os.path.join(os.path.dirname(__file__), 'asset',
                                            'khatangton1.txt')
        try:
            with open(self.file_khatangton, 'r', encoding='utf-8') as f:
                chue_tem_file = f.readline().split('=')[-1].strip()
                satsuan = f.readline().split('=')[-1].strip()
                yaek_poly = int(f.readline().split('=')[-1].strip())
                ao_bs = int(f.readline().split('=')[-1].strip())
                ao_kraduk = int(f.readline().split('=')[-1].strip())
                watsadu = int(f.readline().split('=')[-1].strip())
                pit_mai = int(f.readline().split('=')[-1].strip())
        except:
            chue_tem_file = ''
            satsuan = '8'
            yaek_poly = 0
            ao_bs = 1
            ao_kraduk = 1
            watsadu = 4
            pit_mai = 1

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addWidget(QLabel('ファイル'))
        self.le_chue_file = QLineEdit(chue_tem_file)
        hbl.addWidget(self.le_chue_file)
        self.le_chue_file.setFixedWidth(300)
        self.le_chue_file.textChanged.connect(self.chue_thuk_kae)
        self.btn_khon_file = QPushButton('...')
        hbl.addWidget(self.btn_khon_file)
        self.btn_khon_file.clicked.connect(self.khon_file)

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addWidget(QLabel('尺度'))
        self.le_satsuan = QLineEdit(satsuan)
        hbl.addWidget(self.le_satsuan)
        self.le_satsuan.setFixedWidth(100)
        self.le_satsuan.textEdited.connect(self.satsuan_thuk_kae)
        hbl.addWidget(QLabel('×'))
        hbl.addStretch()

        self.cb_yaek_poly = QCheckBox('材質ごとにポリゴンを分割する')
        vbl.addWidget(self.cb_yaek_poly)

        self.cb_ao_kraduk = QCheckBox('骨も作る')
        vbl.addWidget(self.cb_ao_kraduk)

        self.cb_ao_bs = QCheckBox('ブレンドシェープも作る')
        vbl.addWidget(self.cb_ao_bs)

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addWidget(QLabel('材質'))
        self.cbb_watsadu = QComboBox()
        hbl.addWidget(self.cbb_watsadu)
        self.cbb_watsadu.addItem('無い')
        self.cbb_watsadu.addItem('blinn')
        self.cbb_watsadu.addItem('phong')
        self.cbb_watsadu.addItem('lambert')
        self.cbb_watsadu.addItem('standardSurface')
        hbl.addStretch()

        hbl = QHBoxLayout()
        vbl.addLayout(hbl)
        hbl.addStretch()
        self.btn_roem_sang = QPushButton('作成開始')
        hbl.addWidget(self.btn_roem_sang)
        self.btn_roem_sang.clicked.connect(self.roem_sang)
        self.btn_roem_sang.setFixedSize(220, 50)
        self.chue_thuk_kae(self.le_chue_file.text())
        self.cb_pit = QCheckBox('終わったらこの\nウィンドウを閉じる')
        hbl.addWidget(self.cb_pit)

        self.cb_yaek_poly.setChecked(yaek_poly)
        self.cb_ao_kraduk.setChecked(ao_kraduk)
        self.cb_ao_bs.setChecked(ao_bs)
        self.cbb_watsadu.setCurrentIndex(watsadu)
        self.cb_yaek_poly.toggled.connect(
            lambda: self.chue_thuk_kae(self.le_chue_file.text()))
        self.cb_pit.setChecked(pit_mai)

    def chue_thuk_kae(self, chue_file):  # ファイルの名前が更新されたら
        sakun = chue_file.split('.')[-1]
        sang_dai = (sakun.lower() in ['pmd', 'pmx', 'x'])
        self.btn_roem_sang.setEnabled(sang_dai)
        self.btn_roem_sang.setStyleSheet(
            ['text-decoration: line-through; color: #aab;', ''][sang_dai])
        dai = chue_file[-2:] != '.x' and not self.cb_yaek_poly.isChecked()
        self.cb_ao_kraduk.setEnabled(dai)
        self.cb_ao_bs.setEnabled(dai)
        self.cb_ao_kraduk.setStyleSheet(
            ['text-decoration: line-through; color: #aab;', ''][dai])
        self.cb_ao_bs.setStyleSheet(
            ['text-decoration: line-through; color: #aab;', ''][dai])

    def khon_file(self):  # 読み込むファイルをブラウスする
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
        chue_file, ok = QFileDialog.getOpenFileName(
            filter='PMD/PMX/X (*.pmd *.pmx *.x)')
        if (ok):
            self.le_chue_file.setText(chue_file)
        self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
        self.show()

    def dragEnterEvent(self, e):
        if (e.mimeData().hasUrls()):  # ファイルがドラッグされたら使える
            e.accept()

    def dropEvent(self, e):
        self.le_chue_file.setText(
            e.mimeData().urls()[0].toLocalFile())  # ドラッグされたファイルの名前を取得する

    def satsuan_thuk_kae(self, kha):  # 尺度が更新されたら
        try:
            float(kha)
        except:
            self.le_satsuan.setText('1')

    def roem_sang(self):  # ボタンがクリックされたら、作成は開始
        chue_tem_file = self.le_chue_file.text()
        try:
            satsuan = float(self.le_satsuan.text())
        except:
            self.le_satsuan.setText('1')
            satsuan = 1.
        yaek_poly = self.cb_yaek_poly.isChecked()
        ao_bs = not yaek_poly and self.cb_ao_bs.isChecked()
        ao_kraduk = not yaek_poly and self.cb_ao_kraduk.isChecked()
        watsadu = self.cbb_watsadu.currentIndex()
        # ここでmayaのシーンの中でモデルを作る
        pmxpaimaya.sang(chue_tem_file, satsuan, yaek_poly, ao_bs, ao_kraduk,
                        watsadu)

        pit_mai = self.cb_pit.isChecked()  # 今回使った設定を保存しておく
        with open(self.file_khatangton, 'w', encoding='utf-8') as f:
            f.write('ファイルの名前 = %s\n' % chue_tem_file)
            f.write('尺度 = %f\n' % satsuan)
            f.write('ポリゴンの分割 = %d\n' % yaek_poly)
            f.write('ブレンドシェープ = %d\n' % ao_bs)
            f.write('ジョイント = %d\n' % ao_kraduk)
            f.write('材質 = %d\n' % watsadu)
            f.write('閉じる = %d\n' % pit_mai)

        if (pit_mai):  # 終わったらこのウィンドウを閉じる
            self.close()

    def keyPressEvent(self, e):  # escが押されたら閉じる
        if (e.key() == Qt.Key_Escape):
            self.close()

    def closeEvent(self, e):
        self.parent.natangyoi['mmdmaya'] = None
Ejemplo n.º 21
0
class NewWindow2(QMainWindow):
    def __init__(self):
        super(NewWindow2, self).__init__()

        self.latlong = "0"
        self.textEdit = QTextEdit()
        self.mainWidget = QWidget()
        self.mainLayout = QVBoxLayout()
        font0 = QFont("Arial", 12)
        font0.setBold(True)
        font01 = QFont("Arial", 12)
        font02 = QFont("Arial", 12)
        self.text1 = QLabel("<b>Domyślne Współrzędne:</b><br/>"
                            "Szerokość: 51° 06' 00''<br/>"
                            "Długość: 17° 01' 00''<br/>"
                            "(Współrzędne geograficzne Wrocławia)")
        self.solarpanelcordinates = QLabel('WSPÓŁRZĘDNE PANELU SŁONECZNEGO: ')
        self.solarpanelcordinates.setFont(font0)
        # self.solarpanelcordinates.setFrameStyle(QFrame.Box | QFrame.Sunken)
        # self.solarpanelcordinates.setMidLineWidth(6)
        #self.text1.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.text1.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.text1.setFont(font01)
        self.text1.setFrameStyle(QFrame.Box | QFrame.Raised)
        self.text1.setMidLineWidth(6)
        self.result4 = QLabel('')
        self.result4.setFont(font02)
        self.result4.setMidLineWidth(3)
        self.result5 = QLabel('')
        self.result5.setFont(font02)
        self.result6 = QLabel('')
        self.result6.setFont(font02)
        self.result7 = QLabel('')
        self.result7.setFont(font02)
        self.result8 = QLabel('')
        self.result8.setFont(font02)
        self.result9 = QLabel('')
        self.result9.setFont(font02)
        self.mainLayout.addWidget(self.text1)
        self.mainLayout.addWidget(self.solarpanelcordinates)
        self.mainLayout.addWidget(self.result4)
        self.mainLayout.addWidget(self.result5)
        self.mainLayout.addWidget(self.result6)
        self.mainLayout.addWidget(self.result7)
        self.mainLayout.addWidget(self.result8)
        self.mainLayout.addWidget(self.result9)
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)

        self.createActions()
        self.createMenus()
        #self.createToolBars()
        self.createStatusBar()
        self.createDockWindows()
        self.setWindowTitle("Nowe Okno")
        self.rad = 0
        self.o = 0
        self.timer = QTimer()
        self.timer.timeout.connect(self.dLocation)
        self.timerIsUp = False
        self.timer2 = QTimer()
        self.timer2.timeout.connect(self.update)
        self.timer2.start(1000)
        self.newLetter()
        self.s = ephem.Sun()
        self.o = ephem.Observer()
        # zmienna = []
        # i=0
        # with open('Breslau.txt', 'r') as f:
        #     for line in f:
        #         zmienna.append(line)
        #         i=i+1
        #     print(zmienna)
        #     f = self.nameEdit.text()
        #     f = self.latitudeEdit.text()
        #     f = self.longitudeEdit.text()
        #     f = self.dateandtimeEdit.text()
        #     print(self.nameEdit.text())
        #     print(self.latitudeEdit.text())
        #     print(self.longitudeEdit.text())
        #     print(self.dateandtimeEdit.text())

# class MainWindow(QMainWindow):
#     def __init__(self):
#         super(MainWindow, self).__init__()
#
#         self.latlong = "0"
#         self.textEdit = QTextEdit()
#         self.setCentralWidget(self.textEdit)
#         self.createActions()
#         self.createMenus()
#         #self.createToolBars()
#         self.createStatusBar()
#         self.createDockWindows()
#         self.setWindowTitle("Panel Słoneczny")
#         self.rad = 0
#         self.o = 0
#         self.timer = QTimer()
#         self.timer.timeout.connect(self.dLocation)
#         self.timerIsUp = False
#         self.timer2 = QTimer()
#         self.timer2.timeout.connect(self.update)
#         self.timer2.start(1000)
#         self.newLetter()
#         self.s = ephem.Sun()
#         self.o = ephem.Observer()

    def newWindow(self):
        self.newWin = NewWindow()
        self.newWin.show()

    def newWindow2(self):
        self.newWin2 = NewWindow2()
        self.newWin2.show()

    def newLetter(self):

        self.textEdit.clear()
        self.text2 = QLabel("<b>Domyślne Współrzędne:</b><br/>"
                            "Szerokość: 51° 06' 00''<br/>"
                            "Długość: 17° 01' 00''<br/>"
                            "(Współrzędne geograficzne Wrocławia)")

        cursor = self.textEdit.textCursor()
        cursor.movePosition(QTextCursor.Start)
        topFrame = cursor.currentFrame()
        topFrameFormat = topFrame.frameFormat()
        topFrameFormat.setPadding(16)
        topFrame.setFrameFormat(topFrameFormat)
        textFormat = QTextCharFormat()
        boldFormat = QTextCharFormat()
        boldFormat.setFontWeight(QFont.Bold)
        italicFormat = QTextCharFormat()
        italicFormat.setFontItalic(True)

        tableFormat = QTextTableFormat()
        tableFormat.setBorder(1)
        tableFormat.setCellPadding(16)
        tableFormat.setAlignment(Qt.AlignRight)
        cursor.insertTable(1, 1, tableFormat)
        cursor.insertText("Domyślne Współrzędne: ", boldFormat)
        self.text2.setText(self.nameEdit.text())
        cursor.insertText
        #self.text1.setText(self.nameEdit.text())
        cursor.insertBlock()
        cursor.insertBlock()
        cursor.insertText("Szerokość: 51° 06' 00''", textFormat)
        cursor.insertBlock()
        cursor.insertBlock()
        cursor.insertText("Długość: 17° 01' 00''")
        cursor.insertBlock()
        cursor.insertBlock()
        cursor.insertText("(Współrzędne geograficzne Wrocławia)")
        cursor.setPosition(topFrame.lastPosition())
#         cursor.insertText(QDate.currentDate().toString("Dziś jest: d MMMM yyyy:"),
#                 textFormat)
#         cursor.insertText(QTime.currentTime().toString("  hh:mm:ss"), textFormat)
# #        cursor.insertText(QTimer.timer("  hh:mm:ss", 1000), textFormat)
#         cursor.insertBlock()
#         cursor.insertBlock()
#         cursor.insertText("Wrocław: ", textFormat)
#         cursor.insertText("17.03 deg; 51.10 deg", textFormat)
#         cursor.insertText(",", textFormat)
#         for i in range(3):
#             cursor.insertBlock()
#         cursor.insertText("Text", textFormat)

    def dLocation(self):
        self.s = ephem.Sun()
        self.s.compute(epoch=ephem.now())
        if self.nameEdit.text():
            self.text1.setText(self.nameEdit.text())
            font03 = QFont("Arial", 16)
            font03.setBold(True)
            self.text1.setFont(font03)
            if not self.dateandtimeEdit.text():
                self.o.date = ephem.now()  # 00:22:07 EDT 06:22:07 UT+1
        else:
            if self.dateandtimeEdit.text():
                self.o.date = self.dateandtimeEdit.text()
                self.text1.setText("<b>Obliczenia dla:</b><br/> " +
                                   self.dateandtimeEdit.text())
                font03 = QFont("Arial", 16)
                font03.setBold(True)
                self.text1.setFont(font03)
            else:
                self.o.date = ephem.now()  # 00:22:07 EDT 06:22:07 UT+1
        #self.o.date = ephem.now()  # 00:22:07 EDT 06:22:07 UT+1
        self.s.compute(self.o)
        hour_angle = self.o.sidereal_time() - self.s.ra
        t = ephem.hours(hour_angle +
                        ephem.hours('12:00')).norm  # .norm for 0..24
        self.rad = str(ephem.hours(hour_angle + ephem.hours('12:00')).norm)
        # self.result.setText("R.A.: " + str(self.s.a_ra) + "                DEC.: " + str(self.s.a_dec))
        # self.result2.setText("HOUR ANGLE: " + str(self.rad) + " SIDERAL TIME: " + str(self.o.sidereal_time()))
        # self.result3.setText("SUN Altitude: " + str(self.s.alt) + "       SUN Azimuth: " + str(self.s.az))
        self.result4.setText("R.A.: " + str(self.s.a_ra))
        self.result5.setText("DEC.: " + str(self.s.a_dec))
        self.result6.setText("HOUR ANGLE: " + str(self.rad))
        self.result7.setText("SIDERAL TIME: " + str(self.o.sidereal_time()))
        self.result8.setText("SUN Altitude: " + str(self.s.alt))
        self.result9.setText("SUN Azimuth: " + str(self.s.az))

    def update(self):
        time = QTime.currentTime()
        self.clock.setText(QTime.currentTime().toString("hh:mm:ss"))

    def about(self):
        QMessageBox.about(
            self, "O Programie",
            "<p align=justify>Program <b><i>''Panel Słoneczny''</b></i> pozwala na wyliczenie współrzędnych Słońca, "
            "na podstawie których należy ustawić Panel. Domyślnie program startuje dla "
            "szerokości i&nbsp;długości geograficznej Wrocławia z obecną dla użytkownika datą i godziną. "
            "Użytkownik może podać swoją szerokość i długość geograficzną oraz swój czas i datę wpisując "
            "w odpowiednie pola swoje dane. W polach Szerokość i Długość należy podać w stopniach dziesiętnych "
            "W polu ''Data i Czas'' własne dane należy wpisywać zgodnie ze schematem: "
            "rok/mies/dzień godz:min:sek (np.: 2019/02/04 14:02:03). Pisanie zer przed godzinami, minutami i sekundami "
            "dla liczb poniżej dziesięciu nie jest wymagane (2019/02/04 14:02:03 = 2019/2/4 14:2:3)<p/>"
        )

    def about2(self):
        QMessageBox.about(
            self, "Symbole i skróty",
            "<p align=justify><b><i>Rektascensja (R.A.)</b></i> – (Right Ascension; wznoszenie proste) jest kątem dwuściennym "
            "pomiędzy płaszczyzną koła godzinnego przechodzącego przez punkt Barana, a&nbsp;płaszczyzną koła godzinnego "
            "danego ciała niebieskiego). <br/>"
            "<b><i>Deklinacja (DEC.)</b></i> - kąt zawarty między płaszczyzną równika niebieskiego,"
            "a prostą łączącą punkt na sferze niebieskiej, a środkiem sfery niebieskiej. "
            "Deklinacja zmienia się w zakresie od 90° (biegun północny) przez 0° (równik niebieski) do -90° (biegun południowy).<br/> "
            "<b><i>Kąt Godzinny (HOUR ANGLE)</b></i> - kąt dwuścienny zawarty pomiędzy płaszczyzną lokalnego południka "
            "i płaszczyzną koła godzinnego danego obiektu. Kąt godzinny odmierza się w kierunku zgodnym "
            "z dziennym ruchem sfery niebieskiej, a przyjmuje on wartości (0h,24h) lub (0°,360°) "
            "Kąt godzinny zależy od miejsca obserwacji (ulokowania panela) i od lokalnego czasu.<br/> "
            "<b><i>Czas Gwiazdowy (SIDERAL TIME)</b></i> - czyli kąt godzinny punktu Barana. ( Jeden z&nbsp;dwóch punktów "
            "przecięcia się ekliptyki z równikiem niebieskim. Moment przejścia Słońca przez punkt Barana "
            "oznacza początek astronomicznej wiosny na półkuli północnej. Dlatego nazywany jest także punktem "
            "równonocy wiosennej.)<br/> "
            "<b><i>Wysokość Słońca (nad horyzontem; SUN Altitude)</b></i> - na daną chwilę wyliczona wysokość Słońca, "
            "jeżeli jest ujemna to znaczy, że słońce jest pod horyzontem.<br/> "
            "<b><i>Azymut Słońca (SUN Azimuth)</b></i> - kąt dwuścienny, w programie liczy się w kierunku na wschód "
            "(stojąc twarzą do północy w prawo; w Astronomii jest tak samo, tzn. w prawo, ale zaczyna od południka)."
            "Azymut geograficzny i astronomiczny różni się o 180°.<p/> ")

    def createActions(self):
        # self.newLetterAct = QAction(QIcon.fromTheme('document-new', QIcon(':/images/new.png')), "&New Letter",
        #         self, shortcut=QKeySequence.New,
        #         statusTip="Create a new form letter", triggered=self.newLetter())

        self.newWindowAct = QAction(QIcon.fromTheme('document-new',
                                                    QIcon(':/images/new.png')),
                                    "&Nowe Okno",
                                    self,
                                    shortcut=QKeySequence.New,
                                    statusTip="Create a new form letter",
                                    triggered=self.newWindow2)
        self.saveAct = QAction(QIcon.fromTheme('document-save',
                                               QIcon(':/images/save.png')),
                               "&Zapisz",
                               self,
                               shortcut=QKeySequence.Save,
                               statusTip="Zapisz obecne współrzędne",
                               triggered=self.save)
        self.loadAct = QAction(QtGui.QIcon(':/images/open.png'),
                               "&Wczytaj",
                               self,
                               shortcut=QtGui.QKeySequence.Open,
                               statusTip="Wczytaj współrzędne z pliku",
                               triggered=self.load)
        self.aboutAct = QAction("&O Programie",
                                self,
                                statusTip="Pokazuje pomoc dla programu",
                                triggered=self.about)
        self.aboutAct2 = QAction(
            "&Symbole i skróty",
            self,
            statusTip=
            "Pokazuje objaśnienia używanych w programie skrótów i symboli",
            triggered=self.about2)
        self.quitAct = QAction("&Zamknij",
                               self,
                               shortcut="Ctrl+Q",
                               statusTip="Zamyka aplikację",
                               triggered=self.close)
        self.DefaultAct = QAction(
            QIcon.fromTheme('document-default', QIcon(':/images/def.png')),
            "&Rozpocznij dla domyślnej lokacji",
            self,
            statusTip="Rozpoczyna obliczenia dla domyślnej lokacji (Wrocław)",
            triggered=self.handleButton2)

    def createToolBars(self):
        self.fileToolBar = self.addToolBar("File")
        self.fileToolBar.addAction(self.newLetterAct)

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu("&Plik")
        self.fileMenu.addAction(self.newWindowAct)
        self.fileMenu.addAction(self.saveAct)
        self.fileMenu.addAction(self.loadAct)
        self.fileMenu.addAction(self.DefaultAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.quitAct)
        self.fileMenu.addSeparator()
        self.editMenu = self.menuBar().addMenu("&Edycja")
        self.viewMenu = self.menuBar().addMenu("&Widok")
        self.menuBar().addSeparator()
        self.helpMenu = self.menuBar().addMenu("&Pomoc")
        self.helpMenu.addAction(self.aboutAct)
        self.helpMenu.addAction(self.aboutAct2)

    def createStatusBar(self):
        self.statusBar().showMessage("Gotowy", 3000)

    def saving(self):
        cursor = self.textEdit.textCursor()
        self.nameEdit.text()
        cursor.insertBlock()
        self.latitudeEdit.text()
        cursor.insertBlock()
        self.longitudeEdit.text()
        cursor.insertBlock()
        self.dateandtimeEdit.text()

    def save(self):
        filename, _ = QFileDialog.getSaveFileName(self, "Zapisywanie jako",
                                                  '.',
                                                  "Dokumenty textowe(*.txt)")
        if not filename:
            return

        file = QFile(filename)
        if not file.open(QFile.WriteOnly | QFile.Text):
            QMessageBox.warning(
                self, "Panel Słoneczny", "nie mógł zapisać pliku %s:\n%s." %
                (filename, file.errorString()))
            return

        out = QTextStream(file)
        #QApplication.setOverrideCursor(Qt.WaitCursor)
        #out << self.textEdit.toPlainText()
        out << self.nameEdit.text() + "\n" + self.latitudeEdit.text(
        ) + "\n" + self.longitudeEdit.text(
        ) + "\n" + self.dateandtimeEdit.text()
        #out << "self.text1.setText("+self.nameEdit.text()+")"
        #QApplication.restoreOverrideCursor()

        self.statusBar().showMessage("Zapisano w '%s'" % filename, 2000)

    def load(self):
        filename, _ = QFileDialog.getOpenFileName(self)

        if not filename:
            return

        file = QFile(filename)
        if not file.open(QFile.ReadOnly | QFile.Text):
            QMessageBox.warning(
                self, "Panel Słoneczny", "nie mógł wczytać pliku %s:\n%s." %
                (filename, file.errorString()))
            return

        inf = QTextStream(file)
        #QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
        self.textEdit.setPlainText(inf.readAll())
        #with open(file, 'r') as input:
        with open('Breslau.txt', 'r') as f:
            # f = self.nameEdit.text()
            # f = self.latitudeEdit.text()
            # f = self.longitudeEdit.text()
            # f = self.dateandtimeEdit.text()
            # print(self.nameEdit.text())
            # print(self.latitudeEdit.text())
            # print(self.longitudeEdit.text())
            # print(self.dateandtimeEdit.text())
            # for line in f:
            #      print (line, end='')
            f_name = f.readline()
            #f_name = self.nameEdit.text()
            self.text1.setText(f_name)
            f_lat = f.readline()
            f_lat = self.latitudeEdit.text()
            f_lon = f.readline()
            f_lon = self.longitudeEdit.text()
            f_dnt = f.readline()
            f_dnt = self.dateandtimeEdit.text()

            # for line in f:
            #     if 'name' in line:
            #         self.text1.setText(line)
            #if 'lat' in line:

        #self.text1.setText(self.textEdit.setPlainText(inf.readAll()))
        #self.text1.setText(self.nameEdit.text())

        #QApplication.restoreOverrideCursor()

        #self.setCurrentFile(filename)

        self.statusBar().showMessage("Wczytano plik", 2000)

    def createDockWindows(self):
        # dock = QDockWidget('n', self)
        # dock.setFeatures(dock.NoDockWidgetFeatures)
        # dock.DockWidgetMovable = False
        # dock.setAllowedAreas(Qt.TopDockWidgetArea)
        # self.addDockWidget(Qt.TopDockWidgetArea, dock)

        dock = QDockWidget("Program", self)
        dock.setFeatures(dock.NoDockWidgetFeatures)
        dock.DockWidgetMovable = False
        dock.setAllowedAreas(Qt.LeftDockWidgetArea)
        self.multiWidget = QWidget()
        font1 = QFont("Courier New", 10)
        self.title = QLabel("SOLAR PANEL Program")
        font2 = QFont("Courier New", 10)
        font2.setBold(True)
        self.author = QLabel("Tomasz Dróżdż")
        self.author.setFont(font2)
        self.other = QLabel("Politechnika Wrocławska")
        self.other2 = QLabel("Automatyka i Robotyka")
        self.vLayout = QVBoxLayout()
        self.vLayout.addWidget(self.title)
        self.vLayout.addWidget(self.author)
        self.vLayout.addWidget(self.other)
        self.vLayout.addWidget(self.other2)
        self.multiWidget.setLayout(self.vLayout)
        dock.setWidget(self.multiWidget)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)

        dock = QDockWidget("Zegar", self)
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.multiWidget2 = QWidget()
        font3 = QFont("Arial", 13)
        font4 = QFont("Arial", 20)
        self.date = QLabel(QDate.currentDate().toString("d MMMM yyyy:  "))
        self.clock = QLabel(QTime.currentTime().toString("hh:mm:ss"))
        self.date.setFont(font3)
        self.clock.setFont(font4)
        font4.setBold(True)
        self.vLayout2 = QVBoxLayout()
        self.vLayout2.addWidget(self.date)
        self.vLayout2.addWidget(self.clock)
        self.multiWidget2.setLayout(self.vLayout2)
        dock.setWidget(self.multiWidget2)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        self.viewMenu.addAction(dock.toggleViewAction())

        dock = QDockWidget("Współrzędne Geograficzne Panelu: ", self)
        s = ephem.Sun()
        s.compute(epoch=ephem.now())
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.multiWidget3 = QWidget()
        font5 = QFont("Arial", 12)
        font6 = QFont("Arial", 17)
        self.vLayout3 = QGridLayout()
        self.result = QLabel(self.latlong)
        self.name = QLabel('Nazwa')
        self.latitude = QLabel('Szerokość')
        self.longitude = QLabel('Długość')
        self.dateandtime = QLabel('Data i Czas')
        # self.result = QLabel('')
        # self.result2 = QLabel('')
        # self.result3 = QLabel('')
        self.solarpanelcor = QLabel('WSPÓŁRZĘDNE PANELU SŁONECZNEGO: ')
        self.nameEdit = QLineEdit()
        self.nameEdit.setFixedHeight(28)
        self.nameEdit.setFixedWidth(386)
        self.nameEdit.setStatusTip(
            "Wprowadź nazwę dla konfiguracji współrzędnych i czasu")
        self.latitudeEdit = QLineEdit()
        self.latitudeEdit.setFixedHeight(28)
        self.latitudeEdit.setFixedWidth(386)
        self.latitudeEdit.setStatusTip(
            "Wprowadzona szerokość powinna być w stopniach dziesiętnych (np.: 51.100000)"
        )
        self.longitudeEdit = QLineEdit()
        self.longitudeEdit.setFixedHeight(28)
        self.longitudeEdit.setFixedWidth(386)
        self.longitudeEdit.setStatusTip(
            "Wprowadzona długość powinna być w stopniach dziesiętnych (np.: 17.03333)"
        )
        self.dateandtimeEdit = QLineEdit()
        self.dateandtimeEdit.setFixedHeight(28)
        self.dateandtimeEdit.setFixedWidth(386)
        self.dateandtimeEdit.setStatusTip(
            "Wprowadzona data powinna być w formacie: rok/mies/dzień<spacja>godz:min:sek (np.: 2022/12/4 8:12:7)"
        )
        self.button = QPushButton('Wylicz współrzędne / Przerwij liczenie',
                                  self)
        self.button.clicked.connect(self.handleButton4)
        self.name.setFont(font5)
        self.latitude.setFont(font5)
        self.longitude.setFont(font5)
        self.dateandtime.setFont(font5)
        self.button.setFont(font6)
        self.button.setStatusTip("Rozpoczyna Obliczenia")
        # self.button.addAction(self.buttonAct)
        # self.solarpanelcor.setFont(font5)
        # self.result.setFont(font6)
        # self.result2.setFont(font6)
        # self.result3.setFont(font6)
        self.vLayout3.addWidget(self.name)
        self.vLayout3.addWidget(self.nameEdit)
        self.vLayout3.addWidget(self.latitude)
        self.vLayout3.addWidget(self.latitudeEdit)
        self.vLayout3.addWidget(self.longitude)
        self.vLayout3.addWidget(self.longitudeEdit)
        self.vLayout3.addWidget(self.dateandtime)
        self.vLayout3.addWidget(self.dateandtimeEdit)
        self.vLayout3.addWidget(self.button)
        # self.vLayout3.addWidget(self.solarpanelcor)
        # self.vLayout3.addWidget(self.result)
        # self.vLayout3.addWidget(self.result2)
        # self.vLayout3.addWidget(self.result3)
        self.multiWidget3.setLayout(self.vLayout3)
        dock.setWidget(self.multiWidget3)
        self.addDockWidget(Qt.RightDockWidgetArea, dock)
        self.viewMenu.addAction(dock.toggleViewAction())

    def handleButton2(self):
        self.button.setStatusTip("Przerywa liczenie")
        if self.timerIsUp == False:
            self.o.lon, self.o.lat = '17.03333', '51.100000'  # Współrzędne Wrocławia
            self.text1.setText("Wrocław")
            font03 = QFont("Arial", 16)
            font03.setBold(True)
            self.text1.setFont(font03)
            self.timer.start(1000)
            self.timerIsUp = True
        else:
            self.timer.stop()
            self.timerIsUp = False
            self.button.setStatusTip("Rozpoczyna Obliczenia")

    # def handleButton2(self):
    #     print(self.nameEdit.text())
    #     print(self.latitudeEdit.text())
    #     print(self.longitudeEdit.text())
    #     print(self.dateandtimeEdit.text())

    def handleButton3(self):
        self.button.setStatusTip("Przerywa liczenie")
        if self.timerIsUp == False:
            if self.latitudeEdit.text() and self.longitudeEdit.text():
                self.o.lat = self.latitudeEdit.text()
                self.o.lon = self.longitudeEdit.text()
            if self.nameEdit.text():
                self.text1.setText(self.nameEdit.text())
                font03 = QFont("Arial", 16)
                font03.setBold(True)
                self.text1.setFont(font03)
            else:
                self.text1.setText("Wrocław")
                font03 = QFont("Arial", 16)
                font03.setBold(True)
                self.text1.setFont(font03)
                self.o.lon, self.o.lat = '17.03333', '51.100000'  # Współrzędne Wrocławia
            self.timer.start(1000)
            self.timerIsUp = True
        else:
            self.timer.stop()
            self.timerIsUp = False
            self.button.setStatusTip("Rozpoczyna Obliczenia")

    def handleButton4(self):
        self.button.setStatusTip("Przerywa liczenie")
        if self.timerIsUp == False:
            #zastąpic wlasna logika
            # if self.latitudeEdit.text() and self.longitudeEdit.text():
            #     self.o.lat = self.latitudeEdit.text()
            #     self.o.lon = self.longitudeEdit.text()
            if self.nameEdit.text():
                self.text1.setText(self.nameEdit.text())
                font03 = QFont("Arial", 16)
                font03.setBold(True)
                self.text1.setFont(font03)
            else:
                if self.latitudeEdit.text() and self.longitudeEdit.text():
                    self.o.lat = self.latitudeEdit.text()
                    self.o.lon = self.longitudeEdit.text()
                    self.text1.setText("<b>Obliczenia dla:</b><br/> " +
                                       "Szerokość: " +
                                       self.latitudeEdit.text() + "°" + "  " +
                                       "Długość: " +
                                       self.longitudeEdit.text() + "°")
                    font03 = QFont("Arial", 16)
                    #font03.setBold(True)
                    self.text1.setFont(font03)
                else:
                    self.text1.setText("Wrocław")
                    font03 = QFont("Arial", 16)
                    font03.setBold(True)
                    self.text1.setFont(font03)
                    self.o.lon, self.o.lat = '17.03333', '51.100000'  # Współrzędne Wrocławia
            self.timer.start(1000)
            self.timerIsUp = True
        else:
            self.timer.stop()
            self.timerIsUp = False
            self.button.setStatusTip("Rozpoczyna Obliczenia")
Ejemplo n.º 22
0
class SendWidget(QWidget):

    tokens_file = 'tokens.json'

    def __init__(self, parent=None):
        super(SendWidget, self).__init__(parent)

        self.token_name = 'Ethereum'

        self.setupSenderSection()
        self.setupDestinationSection()
        self.setupTokenSection()
        self.setupProgressSection()
        self.setupSendButtonSection()
        self.setupFeeSection()

        self.send_thread = SendThread()
        self.send_thread.send_transaction.connect(self.sendTransactionFinished)
        self.send_token_thread = SendTokenThread()
        self.send_token_thread.send_token_transaction.connect(
            self.sendTransactionFinished)

        layout = QGridLayout()

        layout.addLayout(self.sender_layout, 0, 0)
        layout.addLayout(self.destination_layout, 0, 1)
        layout.addLayout(self.progress_layout, 1, 0, 1, 2, Qt.AlignCenter)
        layout.addLayout(self.token_layout, 2, 0)
        layout.addLayout(self.send_layout, 2, 1)
        layout.addLayout(self.slider_layout, 3, 0)

        self.setLayout(layout)

    def setupSenderSection(self):
        accounts = blockchain.get_accounts()

        sender_label = QLabel("Sender")
        sender_label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        self.balance_label = QLabel("Balance: ")
        self.balance_label.setSizePolicy(QSizePolicy.Maximum,
                                         QSizePolicy.Maximum)

        self.avatar = QLabel()

        self.sender_combo_box = QComboBox()
        self.sender_items = []
        for account, balance in accounts:
            self.sender_items.append(account)
        self.sender_combo_box.addItems(self.sender_items)
        self.sender_combo_box.setSizePolicy(QSizePolicy.Maximum,
                                            QSizePolicy.Maximum)
        self.sender_combo_box.currentTextChanged.connect(self.filterSender)

        first_account = self.sender_items[0]
        self.filterSender(first_account)
        self.setAvatar(first_account, self.avatar)

        self.sender_layout = QVBoxLayout()
        sender_wrapper_layout = QHBoxLayout()
        sender_right_layout = QVBoxLayout()
        sender_right_layout.addWidget(sender_label)
        sender_right_layout.addWidget(self.sender_combo_box)
        sender_right_layout.addWidget(self.balance_label)
        sender_wrapper_layout.addWidget(self.avatar)
        sender_wrapper_layout.addLayout(sender_right_layout)
        sender_wrapper_layout.addStretch()

        self.sender_layout.addLayout(sender_wrapper_layout)
        self.sender_layout.addStretch()

    def setupDestinationSection(self):
        self.destination_layout = QVBoxLayout()

        destination_label = QLabel("Destination")
        destination_label.setSizePolicy(QSizePolicy.Maximum,
                                        QSizePolicy.Maximum)

        self.destination_line_edit = QLineEdit()
        self.destination_line_edit.setFixedWidth(380)
        self.destination_line_edit.setSizePolicy(QSizePolicy.Maximum,
                                                 QSizePolicy.Maximum)

        self.destination_layout.addWidget(destination_label)
        self.destination_layout.addWidget(self.destination_line_edit)
        self.destination_layout.addStretch()

    def setupTokenSection(self):
        token_label = QLabel("Token")
        token_label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        token_combo_box = QComboBox()

        tokens = blockchain.get_tokens()
        first_token = 'Ethereum'
        items = [first_token]
        self.token_address = {
            'Ethereum': '0xcccccccccccccccccccccccccccccccccccccccc'
        }
        self.token_informations = {}

        for address, token_from_json in tokens.items():
            token_information = blockchain.get_token_named_tuple(
                token_from_json, address)
            self.token_informations[token_information.name] = token_information
            self.token_address[
                token_information.name] = token_information.address
            items.append(token_information.name)

        self.amount_label = QLabel("Amount (in ethers)")

        token_combo_box.addItems(items)
        token_combo_box.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        token_combo_box.currentTextChanged.connect(self.filterToken)

        self.token_avatar = QLabel()

        self.filterToken(first_token)
        token_address = self.token_address[first_token]
        self.setAvatar(token_address, self.token_avatar)

        self.token_layout = QVBoxLayout()
        token_wrapper_layout = QHBoxLayout()
        token_right_layout = QVBoxLayout()
        token_right_layout.addWidget(token_label)
        token_right_layout.addWidget(token_combo_box)
        token_wrapper_layout.addWidget(self.token_avatar)
        token_wrapper_layout.addLayout(token_right_layout)
        token_wrapper_layout.addStretch()
        self.token_layout.addLayout(token_wrapper_layout)

    def setupProgressSection(self):
        self.progress_layout = QHBoxLayout()
        progress_vertical_layout = QVBoxLayout()
        progress_wrapper_layout = QHBoxLayout()
        self.progress_label = QLabel()
        movie = QMovie('icons/ajax-loader.gif')
        self.progress_label.setMovie(movie)
        movie.start()
        self.progress_label.setSizePolicy(QSizePolicy.Maximum,
                                          QSizePolicy.Maximum)
        self.progress_description_label = QLabel()
        self.progress_description_label.setText(
            "Transaction is being confirmed. Please wait!")
        self.progress_description_label.setSizePolicy(QSizePolicy.Maximum,
                                                      QSizePolicy.Maximum)
        progress_wrapper_layout.addWidget(self.progress_label)
        progress_wrapper_layout.addWidget(self.progress_description_label)
        progress_vertical_layout.addLayout(progress_wrapper_layout, 1)
        self.progress_layout.addLayout(progress_vertical_layout)
        self.sendTransactionFinished()

    def setupSendButtonSection(self):
        self.send_layout = QVBoxLayout()
        self.amount_line_edit = QLineEdit()
        self.send_button = QPushButton("Send")
        self.send_button.setSizePolicy(QSizePolicy.Maximum,
                                       QSizePolicy.Maximum)
        self.send_button.clicked.connect(self.sendButtonClicked)
        pal = self.send_button.palette()
        pal.setColor(QPalette.Button, QColor(Qt.green))
        self.send_button.setAutoFillBackground(True)
        self.send_button.setPalette(pal)
        self.send_button.update()
        self.send_layout.addWidget(self.amount_label)
        self.send_layout.addWidget(self.amount_line_edit)
        self.send_layout.addWidget(self.send_button)

    def setupFeeSection(self):
        self.slider_layout = QVBoxLayout()
        fee_label = QLabel("Fee")
        self.fee_slider = QSlider(Qt.Horizontal)
        self.fee_slider.setRange(1, 10)
        self.fee_slider.setValue(3)
        self.fee_slider.valueChanged.connect(self.feeSliderChanged)
        self.gwei_label = QLabel()
        self.feeSliderChanged(3)
        self.slider_layout.addWidget(fee_label)
        self.slider_layout.addWidget(self.fee_slider)
        self.slider_layout.addWidget(self.gwei_label)

    def filterToken(self, token_name):
        address = self.token_address[token_name]
        token_information = None
        if token_name != 'Ethereum':
            token_information = self.token_informations[token_name]
            self.amount_label.setText("Amount")
        else:
            self.amount_label.setText("Amount (in ethers)")
        self.updateBalanceLabel(token_name, self.sender_account,
                                token_information)
        self.setAvatar(address, self.token_avatar)
        self.token_name = token_name

    def filterSender(self, account_address):
        self.sender_account = account_address
        token_information = None
        if self.token_name != 'Ethereum':
            token_information = self.token_informations[self.token_name]
        self.updateBalanceLabel(self.token_name, account_address,
                                token_information)
        self.setAvatar(account_address, self.avatar)

    def updateBalanceLabel(self,
                           token_name,
                           account_address,
                           token_information=None):
        if token_name == 'Ethereum':
            self.balance_label.setText("Balance: %.5f ethers" %
                                       blockchain.get_balance(account_address))
        else:
            self.balance_label.setText("Balance: %d coins" %
                                       blockchain.get_token_balance(
                                           account_address, token_information))

    def setAvatar(self, code, avatar):
        img_filename = render_avatar(code)
        pixmap = QPixmap(img_filename)
        avatar.setPixmap(pixmap)

    def feeSliderChanged(self, value):
        self.gwei_label.setText("%d GWei" % value)
        self.fee = value

    def sendButtonClicked(self):
        password, ok = QInputDialog.getText(self, "Create A New Transaction",
                                            "Password:", QLineEdit.Password)
        if ok and password != '':
            self.progress_label.setVisible(True)
            self.progress_description_label.setVisible(True)
            tx = SendTransaction(sender=self.sender_account,
                                 password=password,
                                 destination=self.destination_line_edit.text(),
                                 amount=self.amount_line_edit.text(),
                                 fee=self.fee)
            token_information = None
            if self.token_name != 'Ethereum':
                token_information = self.token_informations[self.token_name]
                self.send_token_thread.prepareTransaction(
                    tx, token_information)
                self.send_token_thread.start()
            else:
                self.send_thread.prepareTransaction(tx)
                self.send_thread.start()

    def sendTransactionFinished(self):
        self.progress_label.setVisible(False)
        self.progress_description_label.setVisible(False)
Ejemplo n.º 23
0
class NewWindow(QMainWindow):
    def __init__(self):
        super(NewWindow, self).__init__()
        # def setupUi(self, NewWindow):

        self.latlong = "0"
        self.textEdit = QTextEdit()
        self.mainWidget = QWidget()

        self.mainLayout = QVBoxLayout()
        font0 = QFont("Arial", 12)
        font0.setBold(True)
        font01 = QFont("Arial", 12)
        font02 = QFont("Arial", 12)
        self.text1 = QLabel("<b>Domyślne Współrzędne:</b><br/>"
                            "Szerokość: 51° 06' 00''<br/>"
                            "Długość: 17° 01' 00''<br/>"
                            "(Współrzędne geograficzne Wrocławia)")
        self.solarpanelcordinates = QLabel('WSPÓŁRZĘDNE PANELU SŁONECZNEGO: ')
        self.solarpanelcordinates.setFont(font0)
        # self.solarpanelcordinates.setFrameStyle(QFrame.Box | QFrame.Sunken)
        # self.solarpanelcordinates.setMidLineWidth(6)
        self.text1.setFont(font01)
        self.text1.setFrameStyle(QFrame.Box | QFrame.Raised)
        self.text1.setMidLineWidth(6)
        self.result4 = QLabel('')
        self.result4.setFont(font02)
        self.result4.setMidLineWidth(3)
        self.result5 = QLabel('')
        self.result5.setFont(font02)
        self.result6 = QLabel('')
        self.result6.setFont(font02)
        self.result7 = QLabel('')
        self.result7.setFont(font02)
        self.result8 = QLabel('')
        self.result8.setFont(font02)
        self.result9 = QLabel('')
        self.result9.setFont(font02)
        self.mainLayout.addWidget(self.text1)
        self.mainLayout.addWidget(self.solarpanelcordinates)
        self.mainLayout.addWidget(self.result4)
        self.mainLayout.addWidget(self.result5)
        self.mainLayout.addWidget(self.result6)
        self.mainLayout.addWidget(self.result7)
        self.mainLayout.addWidget(self.result8)
        self.mainLayout.addWidget(self.result9)
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)

        #self.createActions()
        #self.createMenus()
        #self.createToolBars()
        #self.createStatusBar()
        self.createDockWindows()
        self.setWindowTitle("Nowe Okno")
        self.rad = 0
        self.o = 0
        self.timer = QTimer()
        self.timer.timeout.connect(self.dLocation)
        self.timerIsUp = False
        self.timer2 = QTimer()
        self.timer2.timeout.connect(self.update)
        self.timer2.start(1000)
        #self.newLetter()
        self.s = ephem.Sun()
        self.o = ephem.Observer()

    def createStatusBar(self):
        self.statusBar().showMessage("Gotowy")

    def dLocation(self):
        self.s = ephem.Sun()
        self.s.compute(epoch=ephem.now())
        if self.dateandtimeEdit.text():
            self.o.date = self.dateandtimeEdit.text()
        else:
            self.o.date = ephem.now()  # 00:22:07 EDT 06:22:07 UT+1
        self.s.compute(self.o)
        hour_angle = self.o.sidereal_time() - self.s.ra
        t = ephem.hours(hour_angle +
                        ephem.hours('12:00')).norm  # .norm for 0..24
        self.rad = str(ephem.hours(hour_angle + ephem.hours('12:00')).norm)
        # self.result.setText("R.A.: " + str(self.s.a_ra) + "                DEC.: " + str(self.s.a_dec))
        # self.result2.setText("HOUR ANGLE: " + str(self.rad) + " SIDERAL TIME: " + str(self.o.sidereal_time()))
        # self.result3.setText("SUN Altitude: " + str(self.s.alt) + "       SUN Azimuth: " + str(self.s.az))
        self.result4.setText("R.A.: " + str(self.s.a_ra))
        self.result5.setText("DEC.: " + str(self.s.a_dec))
        self.result6.setText("HOUR ANGLE: " + str(self.rad))
        self.result7.setText("SIDERAL TIME: " + str(self.o.sidereal_time()))
        self.result8.setText("SUN Altitude: " + str(self.s.alt))
        self.result9.setText("SUN Azimuth: " + str(self.s.az))

    def createDockWindows(self):
        dock = QDockWidget("Współrzędne Geograficzne Panelu: ", self)
        s = ephem.Sun()
        s.compute(epoch=ephem.now())
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.multiWidget3 = QWidget()
        font5 = QFont("Arial", 12)
        font6 = QFont("Arial", 17)
        self.vLayout3 = QGridLayout()
        self.result = QLabel(self.latlong)
        self.latitude = QLabel('Szerokość')
        self.longitude = QLabel('Długość')
        self.dateandtime = QLabel('Data i Czas')
        self.solarpanelcor = QLabel('WSPÓŁRZĘDNE PANELU SŁONECZNEGO: ')
        self.latitudeEdit = QLineEdit()
        self.latitudeEdit.setFixedHeight(28)
        self.latitudeEdit.setFixedWidth(386)
        self.latitudeEdit.setStatusTip(
            "Wprowadzona szerokość powinna być w stopniach dziesiętnych (np.: 51.100000)"
        )
        self.longitudeEdit = QLineEdit()
        self.longitudeEdit.setFixedHeight(28)
        self.longitudeEdit.setFixedWidth(386)
        self.longitudeEdit.setStatusTip(
            "Wprowadzona długość powinna być w stopniach dziesiętnych (np.: 17.03333)"
        )
        self.dateandtimeEdit = QLineEdit()
        self.dateandtimeEdit.setFixedHeight(28)
        self.dateandtimeEdit.setFixedWidth(386)
        self.dateandtimeEdit.setStatusTip(
            "Wprowadzona data powinna być w formacie: rok/mies/dzień<spacja>godz:min:sek (np.: 2022/12/4 8:12:7)"
        )
        self.button = QPushButton('Wylicz współrzędne / Przerwij liczenie',
                                  self)
        self.button.clicked.connect(self.handleButton3)
        self.latitude.setFont(font5)
        self.longitude.setFont(font5)
        self.dateandtime.setFont(font5)
        self.button.setFont(font6)
        self.button.setStatusTip("Rozpoczyna Obliczenia")
        self.vLayout3.addWidget(self.latitude)
        self.vLayout3.addWidget(self.latitudeEdit)
        self.vLayout3.addWidget(self.longitude)
        self.vLayout3.addWidget(self.longitudeEdit)
        self.vLayout3.addWidget(self.dateandtime)
        self.vLayout3.addWidget(self.dateandtimeEdit)
        self.vLayout3.addWidget(self.button)
        self.multiWidget3.setLayout(self.vLayout3)
        dock.setWidget(self.multiWidget3)
        self.addDockWidget(Qt.RightDockWidgetArea, dock)
        # self.viewMenu.addAction(dock.toggleViewAction())

    def handleButton3(self):
        self.button.setStatusTip("Przerywa liczenie")
        if self.timerIsUp == False:
            if self.latitudeEdit.text() and self.longitudeEdit.text():
                self.o.lat = self.latitudeEdit.text()
                self.o.lon = self.longitudeEdit.text()
            else:
                self.o.lon, self.o.lat = '17.03333', '51.100000'  # Współrzędne Wrocławia
            self.timer.start(1000)
            self.timerIsUp = True
        else:
            self.timer.stop()
            self.timerIsUp = False
            self.button.setStatusTip("Rozpoczyna Obliczenia")
Ejemplo n.º 24
0
class AbstractReferenceSelector(ABC, QWidget, metaclass=SelectorMeta):
    changed = Signal()

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.completer = None
        self.p_selected_id = 0

        self.layout = QHBoxLayout()
        self.layout.setMargin(0)
        self.name = QLineEdit()
        self.name.setText("")
        self.layout.addWidget(self.name)
        self.details = QLabel()
        self.details.setText("")
        self.details.setVisible(False)
        self.layout.addWidget(self.details)
        self.button = QPushButton("...")
        self.button.setFixedWidth(self.button.fontMetrics().width("XXXX"))
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)

        self.setFocusProxy(self.name)

        self.button.clicked.connect(self.on_button_clicked)

        if self.details_field:
            self.name.setFixedWidth(self.name.fontMetrics().width("X") * 15)
            self.details.setVisible(True)
        self.completer = QCompleter(self.dialog.model.completion_model)
        self.completer.setCompletionColumn(
            self.dialog.model.completion_model.fieldIndex(self.selector_field))
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.name.setCompleter(self.completer)
        self.completer.activated[QModelIndex].connect(self.on_completion)

    def getId(self):
        return self.p_selected_id

    def setId(self, selected_id):
        if self.p_selected_id == selected_id:
            return
        self.p_selected_id = selected_id
        self.name.setText(
            self.dialog.model.getFieldValue(selected_id, self.selector_field))
        if self.details_field:
            self.details.setText(
                self.dialog.model.getFieldValue(selected_id,
                                                self.details_field))

    selected_id = Property(int, getId, setId, notify=changed, user=True)

    def on_button_clicked(self):
        ref_point = self.mapToGlobal(self.name.geometry().bottomLeft())
        self.dialog.setGeometry(ref_point.x(), ref_point.y(),
                                self.dialog.width(), self.dialog.height())
        res = self.dialog.exec_(enable_selection=True,
                                selected=self.selected_id)
        if res:
            self.selected_id = self.dialog.selected_id
            self.changed.emit()

    @Slot(QModelIndex)
    def on_completion(self, index):
        model = index.model()
        self.selected_id = model.data(model.index(index.row(), 0),
                                      Qt.DisplayRole)
        self.changed.emit()

    def isCustom(self):
        return True
Ejemplo n.º 25
0
class UIMainWindow(object):
    """Container class to hold all UI-related creation methods. Must be sublcassed.
    """

    def create_ui(self):
        """Setup main UI elements, dock widgets, UI-related elements, etc.
        """

        log.debug('Loading UI')

        # Undo Stack
        self.undo_stack = QUndoStack(self)
        self.undo_stack.setUndoLimit(100)

        # Object navigation history
        self.obj_history = deque([], config.MAX_OBJ_HISTORY)

        app = QApplication.instance()
        base_font = QFont()
        base_font.fromString(self.prefs['base_font'])
        app.setFont(base_font)

        # Object class table widget
        # classTable = QTableView(self)
        classTable = classtable.TableView(self)
        classTable.setObjectName("classTable")
        classTable.setAlternatingRowColors(True)
        classTable.setFrameShape(QFrame.StyledPanel)
        classTable_font = QFont()
        classTable_font.fromString(self.prefs['class_table_font'])
        classTable.setFont(classTable_font)
        fm = classTable.fontMetrics()
        classTable.setWordWrap(True)
        classTable.setEditTriggers(QAbstractItemView.EditKeyPressed |
                                   QAbstractItemView.DoubleClicked |
                                   QAbstractItemView.AnyKeyPressed |
                                   QAbstractItemView.SelectedClicked)
        # classTable.horizontalHeader().setMovable(True)
        # classTable.verticalHeader().setMovable(False)
        classTable.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
        classTable.verticalHeader().setSectionResizeMode(QHeaderView.Interactive)
        classTable.horizontalHeader().setDefaultSectionSize(self.prefs['default_column_width'])
        classTable.verticalHeader().setDefaultSectionSize(fm.height() + 0)
        classTable.setSelectionMode(QAbstractItemView.ExtendedSelection)
        classTable.setContextMenuPolicy(Qt.CustomContextMenu)
        classTable.customContextMenuRequested.connect(self.custom_table_context_menu)

        # Create table model and proxy layers for transposing and filtering
        self.classTableModel = classtable.IDFObjectTableModel(classTable)
        self.transposeableModel = classtable.TransposeProxyModel(self.classTableModel)
        self.transposeableModel.setSourceModel(self.classTableModel)
        self.sortableModel = classtable.SortFilterProxyModel(self.transposeableModel)
        self.sortableModel.setSourceModel(self.transposeableModel)

        # Assign model to table (enable sorting FIRST)
        # table.setSortingEnabled(True) # Disable for now, CRUD actions won't work!
        classTable.setModel(self.sortableModel)

        # Connect some signals
        selection_model = classTable.selectionModel()
        selection_model.selectionChanged.connect(self.table_selection_changed)
        scroll_bar = classTable.verticalScrollBar()
        scroll_bar.valueChanged.connect(self.scroll_changed)

        # These are currently broken
        # classTable.horizontalHeader().sectionMoved.connect(self.moveObject)
        # classTable.verticalHeader().sectionMoved.connect(self.moveObject)

        # Object class tree widget
        classTreeDockWidget = QDockWidget("Object Classes and Counts", self)
        classTreeDockWidget.setObjectName("classTreeDockWidget")
        classTreeDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)

        classTree = QTreeView(classTreeDockWidget)
        classTree.setUniformRowHeights(True)
        classTree.setAllColumnsShowFocus(True)
        classTree.setRootIsDecorated(False)
        classTree.setExpandsOnDoubleClick(True)
        classTree.setIndentation(15)
        classTree.setAnimated(True)
        classTree_font = QFont()
        classTree_font.fromString(self.prefs['class_tree_font'])
        classTree.setFont(classTree_font)
        classTree.setAlternatingRowColors(True)
        classTree.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        palette = classTree.palette()
        palette.setColor(QPalette.Highlight, Qt.darkCyan)
        classTree.setPalette(palette)

        class_tree_window = QWidget(classTreeDockWidget)
        class_tree_dock_layout_v = QVBoxLayout()
        class_tree_dock_layout_h = QHBoxLayout()
        class_tree_dock_layout_v.setContentsMargins(0, 8, 0, 0)
        class_tree_dock_layout_h.setContentsMargins(0, 0, 0, 0)

        class_tree_filter_edit = QLineEdit(classTreeDockWidget)
        class_tree_filter_edit.setPlaceholderText("Filter Classes")
        class_tree_filter_edit.textChanged.connect(self.treeFilterRegExpChanged)

        class_tree_filter_cancel = QPushButton("Clear", classTreeDockWidget)
        class_tree_filter_cancel.setMaximumWidth(45)
        class_tree_filter_cancel.clicked.connect(self.clearTreeFilterClicked)

        class_tree_dock_layout_h.addWidget(class_tree_filter_edit)
        class_tree_dock_layout_h.addWidget(class_tree_filter_cancel)
        class_tree_dock_layout_v.addLayout(class_tree_dock_layout_h)
        class_tree_dock_layout_v.addWidget(classTree)
        class_tree_window.setLayout(class_tree_dock_layout_v)

        classTreeDockWidget.setWidget(class_tree_window)
        classTreeDockWidget.setContentsMargins(0,0,0,0)

        # Comments widget
        commentDockWidget = QDockWidget("Comments", self)
        commentDockWidget.setObjectName("commentDockWidget")
        commentDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        commentView = UndoRedoTextEdit(commentDockWidget, self)
        commentView.setLineWrapMode(QTextEdit.FixedColumnWidth)
        commentView.setLineWrapColumnOrWidth(499)
        commentView.setFrameShape(QFrame.StyledPanel)
        commentView_font = QFont()
        commentView_font.fromString(self.prefs['comments_font'])
        commentView.setFont(commentView_font)
        commentDockWidget.setWidget(commentView)

        # Info and help widget
        infoDockWidget = QDockWidget("Info", self)
        infoDockWidget.setObjectName("infoDockWidget")
        infoDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        infoView = QTextEdit(infoDockWidget)
        infoView.setFrameShape(QFrame.StyledPanel)
        infoView.setReadOnly(True)
        infoDockWidget.setWidget(infoView)

        # Node list and jump menu widget
        refDockWidget = QDockWidget("Field References", self)
        refDockWidget.setObjectName("refDockWidget")
        refDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        ref_model = reftree.ReferenceTreeModel(None, refDockWidget)
        refView = QTreeView(refDockWidget)
        refView.setModel(ref_model)
        refView.setUniformRowHeights(True)
        refView.setRootIsDecorated(False)
        refView.setIndentation(15)
        refView.setColumnWidth(0, 160)
        refView.setFrameShape(QFrame.StyledPanel)
        refDockWidget.setWidget(refView)
        refView.doubleClicked.connect(self.ref_tree_double_clicked)

        # Logging and debugging widget
        logDockWidget = QDockWidget("Log Viewer", self)
        logDockWidget.setObjectName("logDockWidget")
        logDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        logView = QPlainTextEdit(logDockWidget)
        logView.setLineWrapMode(QPlainTextEdit.NoWrap)
        logView.setReadOnly(True)
        logView_font = QFont()
        logView_font.fromString(self.prefs['base_font'])
        logView.setFont(logView_font)
        logView.ensureCursorVisible()
        logDockWidget.setWidget(logView)

        # Undo view widget
        undoDockWidget = QDockWidget("Undo History", self)
        undoDockWidget.setObjectName("undoDockWidget")
        undoDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas)
        undoView = QUndoView(self.undo_stack)
        undoDockWidget.setWidget(undoView)

        # Define corner docking behaviour
        self.setDockNestingEnabled(True)
        self.setCorner(Qt.TopLeftCorner,
                       Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner,
                       Qt.RightDockWidgetArea)
        self.setCorner(Qt.BottomLeftCorner,
                       Qt.LeftDockWidgetArea)
        self.setCorner(Qt.BottomRightCorner,
                       Qt.RightDockWidgetArea)

        # Assign main widget and dock widgets to QMainWindow
        self.setCentralWidget(classTable)
        self.addDockWidget(Qt.LeftDockWidgetArea, classTreeDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, commentDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, infoDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, refDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, undoDockWidget)

        # Store widgets for access by other objects
        self.classTable = classTable
        self.commentView = commentView
        self.infoView = infoView
        self.classTree = classTree
        self.logView = logView
        self.undoView = undoView
        self.refView = refView
        self.filterTreeBox = class_tree_filter_edit

        # Store docks for access by other objects
        self.commentDockWidget = commentDockWidget
        self.infoDockWidget = infoDockWidget
        self.classTreeDockWidget = classTreeDockWidget
        self.logDockWidget = logDockWidget
        self.undoDockWidget = undoDockWidget
        self.refDockWidget = refDockWidget

        # Perform other UI-related initialization tasks
        self.center()
        self.setUnifiedTitleAndToolBarOnMac(True)
        self.setWindowIcon(QIcon(':/images/logo.png'))

        # Status bar setup
        self.statusBar().showMessage('Status: Ready')
        self.unitsLabel = QLabel()
        self.unitsLabel.setAlignment(Qt.AlignCenter)
        self.unitsLabel.setMinimumSize(self.unitsLabel.sizeHint())
        self.unitsLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.statusBar().addPermanentWidget(self.unitsLabel)
        self.pathLabel = QLabel()
        self.pathLabel.setAlignment(Qt.AlignCenter)
        self.pathLabel.setMinimumSize(self.pathLabel.sizeHint())
        self.pathLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.statusBar().addPermanentWidget(self.pathLabel)
        self.versionLabel = QLabel()
        self.versionLabel.setAlignment(Qt.AlignCenter)
        self.versionLabel.setMinimumSize(self.versionLabel.sizeHint())
        self.versionLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.statusBar().addPermanentWidget(self.versionLabel)
        self.progressBarIDF = QProgressBar()
        self.progressBarIDF.setAlignment(Qt.AlignCenter)
        self.progressBarIDF.setMaximumWidth(200)
        self.statusBar().addPermanentWidget(self.progressBarIDF)

        self.clipboard = QApplication.instance().clipboard()
        self.obj_clipboard = []

        self.setStyleSheet("""
            QToolTip {
               background-color: gray;
               color: white;
               border: black solid 1px
            } 
            # QMenu {
            #     background-color: rgbf(0.949020, 0.945098, 0.941176);
            #     color: rgb(255,255,255);
            # }
            # QMenu::item::selected {
            #     background-color: rgbf(0.949020, 0.945098, 0.941176);
            # }
            """)

    def create_tray_menu(self):
        """Creates an icon and menu for the system tray
        """

        # Menu for the system tray
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.minimizeAction)
        self.trayIconMenu.addAction(self.maximizeAction)
        self.trayIconMenu.addAction(self.restoreAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.exitAct)

        # System tray itself
        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)
        self.trayIcon.setIcon(QIcon(':/images/logo.png'))
        self.trayIcon.setToolTip('IDF+')
        self.trayIcon.show()

    def create_actions(self):
        """Creates appropriate actions for use in menus and toolbars.
        """

        self.newAct = QAction(QIcon(':/images/new1.png'), "&New", self,
                                    shortcut=QKeySequence.New,
                                    statusTip="Create a new file",
                                    iconVisibleInMenu=True,
                                    triggered=self.new_file)

        self.openAct = QAction(QIcon(':/images/open.png'), "&Open...", self,
                                     shortcut=QKeySequence.Open,
                                     statusTip="Open an existing file",
                                     iconVisibleInMenu=True,
                                     triggered=self.open_file)

        self.saveAct = QAction(QIcon(':/images/save.png'), "&Save", self,
                                     shortcut=QKeySequence.Save,
                                     statusTip="Save the document to disk",
                                     iconVisibleInMenu=True,
                                     triggered=self.save)

        self.saveFormatAct = QAction(QIcon(':/images/save.png'), "&Format && Save",
                                     self, shortcut=QKeySequence('Ctrl+Shift+F'),
                                     statusTip="Format File and Save to disk",
                                     iconVisibleInMenu=True,
                                     triggered=self.format_save)

        self.saveAsAct = QAction(QIcon(':/images/saveas.png'), "Save &As...", self,
                                       shortcut=QKeySequence.SaveAs,
                                       statusTip="Save the document under a new name",
                                       iconVisibleInMenu=True,
                                       triggered=self.save_as)

        self.exitAct = QAction(QIcon(':/images/quit.png'), "E&xit", self,
                                     shortcut=QKeySequence('Ctrl+Q'),
                                     iconVisibleInMenu=True,
                                     statusTip="Exit the application",
                                     triggered=self.closeAllWindows)

        self.cutObjAct = QAction(QIcon(':/images/cut.png'), "Cu&t Object", self,
                                       shortcut=QKeySequence.Cut,
                                       statusTip="Cut current selection's contents to clipboard",
                                       iconVisibleInMenu=True,
                                       triggered=self.cutObject,
                                       iconText='Cut Obj')

        self.copyAct = QAction(QIcon(':/images/copy.png'),
                                     "&Copy Selected Values", self,
                                     statusTip="Copy current selection's contents to clipboard",
                                     iconVisibleInMenu=True,
                                     triggered=self.copySelected)

        self.pasteAct = QAction(QIcon(':/images/paste.png'),
                                      "&Paste Selected Values", self,
                                      statusTip="Paste clipboard into current selection",
                                      iconVisibleInMenu=True,
                                      triggered=self.pasteSelected)

        self.pasteExtAct = QAction(QIcon(':/images/paste.png'),
                                      "&Paste from External", self,
                                      shortcut=QKeySequence('Ctrl+Shift+v'),
                                      statusTip="Paste from external program",
                                      iconVisibleInMenu=True,
                                      triggered=self.paste_from_external)

        self.transposeAct = QAction("Transpose", self,
                                          shortcut=QKeySequence('Ctrl+t'),
                                          statusTip="Transpose rows and columns in object display",
                                          triggered=self.transpose_table)

        self.newObjAct = QAction(QIcon(':/images/new2.png'), "New Object", self,
                                       shortcut=QKeySequence('Ctrl+Shift+n'),
                                       statusTip="Create new object in current class",
                                       iconVisibleInMenu=True,
                                       triggered=self.newObject,
                                       iconText='New Obj')

        self.copyObjAct = QAction(QIcon(':/images/copy.png'), "Copy Object", self,
                                        shortcut=QKeySequence.Copy,
                                        statusTip="Copy the current Object(s)",
                                        iconVisibleInMenu=True,
                                        triggered=self.copyObject,
                                        iconText='Copy Obj')

        self.pasteObjAct = QAction(QIcon(':/images/paste.png'), "Paste Object", self,
                                         shortcut=QKeySequence.Paste,
                                         statusTip="Paste the currently copies Object(s)",
                                         iconVisibleInMenu=True,
                                         triggered=self.pasteObject,
                                         iconText='Paste Obj')

        self.dupObjAct = QAction(QIcon(':/images/copy.png'), "Duplicate Object", self,
                                       shortcut=QKeySequence('Shift+Ctrl+d'),
                                       statusTip="Duplicate the current Object(s)",
                                       iconVisibleInMenu=True,
                                       triggered=self.duplicateObject,
                                       iconText='Dup Obj')

        self.delObjAct = QAction(QIcon(':/images/delete.png'), "Delete Object", self,
                                       shortcut=QKeySequence.Delete,
                                       statusTip="Delete the current Object(s)",
                                       iconVisibleInMenu=True,
                                       triggered=self.deleteObject,
                                       iconText='Del Obj')

        self.undoAct = QAction(QIcon(':/images/undo.png'), "&Undo", self,
                                     shortcut=QKeySequence.Undo,
                                     statusTip="Undo previous action",
                                     iconVisibleInMenu=True,
                                     triggered=self.undo_stack.undo)

        self.redoAct = QAction(QIcon(':/images/redo.png'), "&Redo", self,
                                     shortcut=QKeySequence.Redo,
                                     statusTip="Redo previous action",
                                     iconVisibleInMenu=True,
                                     triggered=self.undo_stack.redo)

        self.groupAct = QAction("Hide Groups in Class Tree", self,
                                      shortcut=QKeySequence('Ctrl+g'),
                                      triggered=self.toggle_groups,
                                      checkable=True)

        # self.navForwardAct = QAction("Forward", self,
        #         shortcut=QKeySequence('Ctrl+Plus'),
        #         statusTip="Go forward to the next object",
        #         triggered=self.navForward)
        #
        # self.navBackAct = QAction("Back", self,
        #         shortcut=QKeySequence('Ctrl+Minus'),
        #         statusTip="Go back to the previous object",
        #         triggered=self.navBack)

        self.showInFolderAct = QAction(QIcon(':/images/new.png'), "&Show in folder",
                                             self, shortcut=QKeySequence('Ctrl+Shift+t'),
                                             statusTip="Open location of current file",
                                             iconVisibleInMenu=True)
        self.showInFolderAct.triggered.connect(lambda: self.show_in_folder())

        self.epDocGettingStartedAction = QAction("EnergyPlus Getting Started", self,
                                                       triggered=self.energy_plus_docs)

        self.epDocIORefAction = QAction("EnergyPlus I/O Reference", self,
                                              triggered=self.energy_plus_docs)

        self.epDocOutputDetailsAction = QAction("EnergyPlus Output Details and Examples",
                                                      self, triggered=self.energy_plus_docs)

        self.epDocEngineeringRefAction = QAction("EnergyPlus Engineering Reference", self,
                                                       triggered=self.energy_plus_docs)

        self.epDocAuxiliaryProgsAction = QAction("EnergyPlus Auxiliary Programs", self,
                                                       triggered=self.energy_plus_docs)

        self.epDocEMSGuideAction = QAction("EnergyPlus EMS Application Guide", self,
                                                 triggered=self.energy_plus_docs)

        self.epDocComplianceAction = QAction("Using EnergyPlus for Compliance", self,
                                                   triggered=self.energy_plus_docs)

        self.epDocInterfaceAction = QAction("External Interface Application Guide", self,
                                                  triggered=self.energy_plus_docs)

        self.epDocTipsTricksAction = QAction("Tips and Tricks Using EnergyPlus", self,
                                                   triggered=self.energy_plus_docs)

        self.epDocPlantGuideAction = QAction("EnergyPlus Plant Application Guide", self,
                                                   triggered=self.energy_plus_docs)

        self.epDocAcknowledgmentsAction = QAction("EnergyPlus Acknowledgments", self,
                                                        triggered=self.energy_plus_docs)

        self.openInEditorAct = QAction(QIcon(':/images/new.png'),
                                             "&Open in text editor", self,
                                             shortcut=QKeySequence('Ctrl+e'),
                                             statusTip="Open current file in default editor",
                                             iconVisibleInMenu=True,
                                             triggered=self.open_in_text_editor)

        self.helpAct = QAction("&EnergyPlus Help (Online)", self,
                                     statusTip="Show the EnergyPlus' help",
                                     triggered=self.energyplus_help)

        self.aboutAct = QAction("&About IDF+", self,
                                      statusTip="Show the application's About box",
                                      triggered=self.about)

        self.clearRecentAct = QAction("Clear Recent", self,
                                            statusTip="Clear recent files",
                                            triggered=self.clear_recent)

        self.minimizeAction = QAction("Mi&nimize", self,
                                            triggered=self.hide)

        self.maximizeAction = QAction("Ma&ximize", self,
                                            triggered=self.showMaximized)

        self.restoreAction = QAction("&Restore", self,
                                           triggered=self.showNormal)

        self.showPrefsAction = QAction("&Preferences", self,
                                             triggered=self.show_prefs_dialog)

        self.showSearchAction = QAction("&Search && Replace", self,
                                              shortcut=QKeySequence('Ctrl+f'),
                                              triggered=self.show_search_dialog)

        self.findThisAct = QAction("Find This", self,
                                         triggered=self.find_this)

        self.jumpFilterGeometry = QAction("Include Geometry", self,
                                                triggered=self.jump_to_filter_geometry,
                                                checkable=True)

        self.setIPUnitsAction = QAction("&IP Units", self,
                                              triggered=self.toggle_units,
                                              checkable=True)

        self.setSIUnitsAction = QAction("&SI Units", self,
                                              triggered=self.toggle_units,
                                              checkable=True)

        self.classWithObjsAction = QAction("Show Only Classes With Objects", self,
                                                 shortcut=QKeySequence('Ctrl+l'),
                                                 statusTip="Show Only Classes With Objects",
                                                 triggered=self.toggle_full_tree,
                                                 checkable=True)

        self.fillRightAction = QAction("Fill right", self,
                                             shortcut=QKeySequence('Ctrl+d'),
                                             statusTip="Fill right",
                                             triggered=self.fill_right)

        self.logDockWidgetAct = self.logDockWidget.toggleViewAction()
        self.transposeAct.setEnabled(False)
        self.setSIUnitsAction.setChecked(True)
        self.undoAct.setEnabled(False)
        self.redoAct.setEnabled(False)
        self.saveAct.setEnabled(False)
        self.undo_stack.canUndoChanged.connect(self.toggle_can_undo)
        self.undo_stack.canRedoChanged.connect(self.toggle_can_redo)
        self.logDockWidgetAct.toggled.connect(self.start_log_watcher)

    def toggle_can_undo(self):
        if self.undo_stack.canUndo():
            new_state = True
        else:
            new_state = False
        self.undoAct.setEnabled(new_state)
        self.set_dirty(new_state)

    def toggle_can_redo(self):
        if self.undo_stack.canRedo():
            new_state = True
        else:
            new_state = False
        self.redoAct.setEnabled(new_state)

    def create_menus(self):
        """Create all required items for menus.
        """

        # File Menu
        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenuActions = (self.newAct, self.openAct, self.saveAct,
                                self.saveAsAct, self.saveFormatAct, None, self.exitAct)
        self.update_file_menu()
        self.fileMenu.aboutToShow.connect(self.update_file_menu)

        # Edit Menu
        self.editMenu = self.menuBar().addMenu("&Edit")
        self.editMenu.addAction(self.undoAct)
        self.editMenu.addAction(self.redoAct)
        self.editMenu.addSeparator().setText('Objects')
        self.editMenu.addAction(self.newObjAct)
        self.editMenu.addAction(self.dupObjAct)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.cutObjAct)
        self.editMenu.addAction(self.copyObjAct)
        self.editMenu.addAction(self.pasteObjAct)
        self.editMenu.addAction(self.pasteExtAct)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.delObjAct)
        self.editMenu.addSeparator().setText('Values')
        self.editMenu.addAction(self.copyAct)
        self.editMenu.addAction(self.pasteAct)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.fillRightAction)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.showSearchAction)

        # Tools Menu
        self.toolsMenu = self.menuBar().addMenu("&Tools")
        self.toolsMenu.addAction(self.showInFolderAct)
        self.toolsMenu.addAction(self.openInEditorAct)
        self.toolsMenu.addSeparator()
        self.toolsMenu.addAction(self.showPrefsAction)

        # View Menu
        self.viewMenu = self.menuBar().addMenu("&View")
        action_group = QActionGroup(self)
        self.viewMenu.addAction(action_group.addAction(self.setSIUnitsAction))
        self.viewMenu.addAction(action_group.addAction(self.setIPUnitsAction))
        self.viewMenu.addSeparator().setText('Dockable Widgets')
        self.viewMenu.addAction(self.classTreeDockWidget.toggleViewAction())
        self.viewMenu.addAction(self.infoView.parent().toggleViewAction())
        self.viewMenu.addAction(self.commentView.parent().toggleViewAction())
        self.viewMenu.addAction(self.logDockWidgetAct)
        self.viewMenu.addAction(self.undoView.parent().toggleViewAction())
        self.viewMenu.addSeparator().setText('Toolbars')
        self.viewMenu.addAction(self.fileToolBar.toggleViewAction())
        self.viewMenu.addAction(self.editToolBar.toggleViewAction())
        # self.viewMenu.addAction(self.navToolBar.toggleViewAction())
        self.viewMenu.addAction(self.filterToolBar.toggleViewAction())
        self.viewMenu.addSeparator()
        self.viewMenu.addAction(self.classWithObjsAction)
        self.viewMenu.addAction(self.groupAct)
        self.viewMenu.addSeparator()
        self.viewMenu.addAction(self.transposeAct)

        # Jump Menu
        self.jumpToMenu = self.menuBar().addMenu("&Jump")
        self.update_jump_menu()
        self.jumpToMenu.aboutToShow.connect(self.update_jump_menu)
        self.jumpFilterGeometry.setEnabled(False)

        # Help Menu
        self.helpMenu = self.menuBar().addMenu("&Help")
        self.helpMenu.addAction(self.helpAct)
        self.helpMenu.addAction(self.aboutAct)
        self.helpMenu.addSeparator()
        self.helpMenu.addAction(self.epDocGettingStartedAction)
        self.helpMenu.addAction(self.epDocIORefAction)
        self.helpMenu.addAction(self.epDocOutputDetailsAction)
        self.helpMenu.addAction(self.epDocEngineeringRefAction)
        self.helpMenu.addAction(self.epDocAuxiliaryProgsAction)
        self.helpMenu.addAction(self.epDocEMSGuideAction)
        self.helpMenu.addAction(self.epDocComplianceAction)
        self.helpMenu.addAction(self.epDocInterfaceAction)
        self.helpMenu.addAction(self.epDocTipsTricksAction)
        self.helpMenu.addAction(self.epDocPlantGuideAction)
        self.helpMenu.addAction(self.epDocAcknowledgmentsAction)

    def create_tool_bars(self):
        """Creates the necessary toolbars.
        """

        # File Toolbar
        self.fileToolBar = self.addToolBar("File Toolbar")
        self.fileToolBar.setObjectName('fileToolbar')
        self.fileToolBar.addAction(self.newAct)
        self.fileToolBar.addAction(self.openAct)
        self.fileToolBar.addAction(self.saveAct)
        self.fileToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        # Edit Toolbar
        self.editToolBar = self.addToolBar("Edit Toolbar")
        self.editToolBar.setObjectName('editToolbar')
        self.editToolBar.addAction(self.undoAct)
        self.editToolBar.addAction(self.redoAct)
        self.editToolBar.addAction(self.newObjAct)
        self.editToolBar.addAction(self.dupObjAct)
        self.editToolBar.addAction(self.delObjAct)
        self.editToolBar.addAction(self.cutObjAct)
        self.editToolBar.addAction(self.copyObjAct)
        self.editToolBar.addAction(self.pasteObjAct)
        self.editToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        # Object history navigation toolbar
        # self.navToolBar = self.addToolBar("Navigation Toolbar")
        # self.navToolBar.setObjectName('viewToolBar')
        # self.navToolBar.addAction(self.navForwardAct)
        # self.navToolBar.addAction(self.navBackAct)
        # self.navToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        # Object filter toolbar
        self.filterToolBar = self.addToolBar("Filter Toolbar")
        self.filterToolBar.setObjectName('filterToolBar')
        self.filterBox = QLineEdit()
        self.filterBox.setPlaceholderText("Filter Objects")
        self.filterBox.setMaximumWidth(160)
        self.filterBox.setFixedWidth(160)
        # filterLabel = QLabel("Filter Obj:", self)
        # filterLabel.setBuddy(self.filterBox)
        # self.filterToolBar.addWidget(filterLabel)
        self.filterBox.textChanged.connect(self.tableFilterRegExpChanged)
        self.filterBox.textChanged.connect(self.treeFilterRegExpChanged)
        clearFilterButton = QPushButton('Clear')
        clearFilterButton.setMaximumWidth(45)
        clearFilterButton.clicked.connect(self.clearFilterClicked)
        self.filterToolBar.addWidget(self.filterBox)
        self.filterToolBar.addWidget(clearFilterButton)
        self.caseSensitivity = QCheckBox('Case Sensitive')
        self.caseSensitivity.stateChanged.connect(self.caseSensitivityChanged)
        self.filterToolBar.addWidget(self.caseSensitivity)
        self.filterToolBar.addSeparator()
        self.filterToolBar.addAction(self.transposeAct)

    def create_shortcuts(self):
        """Creates keyboard shortcuts.
        """

        # QShortcut(QKeySequence('Ctrl+l'), self).activated.connect(self.toggle_full_tree)
        # QShortcut(QKeySequence('Ctrl+d'), self).activated.connect(self.fill_right)
        # QShortcut(QKeySequence('Ctrl+d'), self).activated.connect(self.fill_right)

#    def createAction(self, text, slot=None, shortcut=None, icon=None,
#                     tip=None, checkable=False, signal="triggered()"):
#        action = QAction(text, self)
#        if icon is not None:
#            action.setIcon(QIcon(":/%s.png" % icon))
#        if shortcut is not None:
#            action.setShortcut(shortcut)
#        if tip is not None:
#            action.setToolTip(tip)
#            action.setStatusTip(tip)
#        if slot is not None:
#            self.connect(action, QtCore.SIGNAL(signal), slot)
#        if checkable:
#            action.setCheckable(True)
#        return action
#

    def custom_table_context_menu(self, position):

        # Create a menu and populate it with actions
        menu = QMenu(self)
        menu.addAction(self.undoAct)
        menu.addAction(self.redoAct)
        menu.addSeparator()
        menu.addAction(self.copyObjAct)
        menu.addAction(self.dupObjAct)
        menu.addAction(self.delObjAct)
        menu.addAction(self.newObjAct)
        menu.addAction(self.cutObjAct)
        menu.addSeparator()
        menu.addMenu(self.jumpToMenu)
        menu.addSeparator()
        menu.addAction(self.findThisAct)
        menu.popup(self.classTable.viewport().mapToGlobal(position))
        self.mouse_position = position

    def reset_progress_bar(self):
        self.progressBarIDF.hide()

    def center(self):
        """Called to center the window on the screen on startup.
        """

        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def show_prefs_dialog(self):
        """Handles showing the settings dialog and setting its values.
        """

        dlg = PrefsDialog(self, self.prefs)
        if dlg.exec_():
            # Refresh the table view to take into account any new prefs
            self.load_table_view(self.current_obj_class)

            # Clear the idd cache if requested
            if self.prefs.get('clear_idd_cache', False) == True:
                self.clear_idd_cache()

            # Update preferences if various flags apply
            if not self.idf:
                return
            options_dict = dict()
            if self.prefs.get('apply_default_save_behaviour', False) == True:
                options_dict.update({'sort_order': self.prefs.get('sort_order'),
                                     'special_formatting': self.prefs.get('special_formatting')})
            # if self.prefs.get('apply_default_units_behaviour', False) == True:
            #     options_dict.update({'save_units': self.prefs.get('save_units')})
            # if self.prefs.get('apply_default_hidden_class_behaviour', False) == True:
            #     options_dict.update({'save_hidden_classes': self.prefs.get('save_hidden_classes')})
            if options_dict:
                self.idf.set_options(options_dict)
                self.set_dirty(True)

    def show_search_dialog(self):
        """Opens the search dialog.
        """

        SearchReplaceDialog(self).show()

    def find_this(self):
        """Searches for fields with similar content.
        """

        index = self.classTable.indexAt(self.mouse_position)
        text = self.classTable.model().data(index, Qt.EditRole)
        if text:
            SearchReplaceDialog(self, initial_query=text).show()
Ejemplo n.º 26
0
class MainWindow(QMainWindow):
    def __init__(self, application, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.printer_thread = WorkerThread()
        self.printer_thread.message.connect(self.standardOutputWritten)
        self.printer_thread.start()

        self.app = application
        self.app.setStyle("Fusion")

        self.__set_interface()
        self.__set_layouts()
        self.__set_stylesheet()
        self.__set_connections()
        self.__set_params()

    def closeEvent(self, event):
        self.printer_thread.stop()

    def __set_interface(self):
        self.button_width = 0.35
        self.button_height = 0.05

        self.setWindowTitle("GSI-RADS")
        self.__getScreenDimensions()

        self.setGeometry(self.left, self.top, self.width, self.height)
        self.setMaximumWidth(self.width)
        #self.setMaximumHeight(self.height)
        self.setMinimumWidth(self.width)
        self.setMinimumHeight(self.height)
        self.move(self.width / 2, self.height / 2)

        self.menu_bar = QMenuBar(self)
        self.menu_bar.setNativeMenuBar(
            False
        )  # https://stackoverflow.com/questions/25261760/menubar-not-showing-for-simple-qmainwindow-code-qt-creator-mac-os
        self.file_menu = self.menu_bar.addMenu('File')
        self.import_dicom_action = QAction(
            QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/database-icon.png')), 'Import DICOM',
            self)
        self.import_dicom_action.setShortcut('Ctrl+D')
        self.file_menu.addAction(self.import_dicom_action)
        self.quit_action = QAction('Quit', self)
        self.quit_action.setShortcut("Ctrl+Q")
        self.file_menu.addAction(self.quit_action)

        self.settings_menu = self.menu_bar.addMenu('Settings')
        self.settings_seg_menu = self.settings_menu.addMenu("Segmentation...")
        self.settings_seg_preproc_menu = self.settings_seg_menu.addMenu(
            "Preprocessing...")
        self.settings_seg_preproc_menu_p1_action = QAction(
            "Brain-masking off (P1)", checkable=True)
        self.settings_seg_preproc_menu_p2_action = QAction(
            "Brain-masking on (P2)", checkable=True)
        self.settings_seg_preproc_menu_p2_action.setChecked(True)
        self.settings_seg_preproc_menu.addAction(
            self.settings_seg_preproc_menu_p1_action)
        self.settings_seg_preproc_menu.addAction(
            self.settings_seg_preproc_menu_p2_action)

        self.help_menu = self.menu_bar.addMenu('Help')
        self.readme_action = QAction(
            QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/readme-icon.jpeg')), 'Tutorial', self)
        self.readme_action.setShortcut("Ctrl+R")
        self.help_menu.addAction(self.readme_action)
        self.about_action = QAction(
            QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/about-icon.png')), 'About', self)
        self.about_action.setShortcut("Ctrl+A")
        self.help_menu.addAction(self.about_action)
        self.help_action = QAction(
            QIcon.fromTheme("help-faq"), "Help", self
        )  # Default icons can be found here: https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html#guidelines
        self.help_action.setShortcut("Ctrl+J")
        self.help_menu.addAction(self.help_action)

        self.input_image_lineedit = QLineEdit()
        self.input_image_lineedit.setFixedWidth(self.width *
                                                (0.93 - self.button_width / 2))
        self.input_image_lineedit.setFixedHeight(self.height *
                                                 self.button_height)
        self.input_image_lineedit.setReadOnly(True)
        self.input_image_pushbutton = QPushButton('Input MRI')
        self.input_image_pushbutton.setFixedWidth(self.height *
                                                  self.button_width)
        self.input_image_pushbutton.setFixedHeight(self.height *
                                                   self.button_height)

        self.input_segmentation_lineedit = QLineEdit()
        self.input_segmentation_lineedit.setReadOnly(True)
        self.input_segmentation_lineedit.setFixedWidth(
            self.width * (0.93 - self.button_width / 2))
        self.input_segmentation_lineedit.setFixedHeight(self.height *
                                                        self.button_height)
        self.input_segmentation_pushbutton = QPushButton('Input segmentation')
        self.input_segmentation_pushbutton.setFixedWidth(self.height *
                                                         self.button_width)
        self.input_segmentation_pushbutton.setFixedHeight(self.height *
                                                          self.button_height)

        self.output_folder_lineedit = QLineEdit()
        self.output_folder_lineedit.setReadOnly(True)
        self.output_folder_lineedit.setFixedWidth(
            self.width * (0.93 - self.button_width / 2))
        self.output_folder_lineedit.setFixedHeight(self.height *
                                                   self.button_height)
        self.output_folder_pushbutton = QPushButton('Output destination')
        self.output_folder_pushbutton.setFixedWidth(self.height *
                                                    self.button_width)
        self.output_folder_pushbutton.setFixedHeight(self.height *
                                                     self.button_height)

        self.run_button = QPushButton('Run diagnosis')
        self.run_button.setFixedWidth(self.height * self.button_width)
        self.run_button.setFixedHeight(self.height * self.button_height)

        self.main_display_tabwidget = QTabWidget()

        self.tutorial_textedit = QPlainTextEdit()
        self.tutorial_textedit.setReadOnly(True)
        self.tutorial_textedit.setFixedWidth(self.width * 0.97)
        self.tutorial_textedit.setPlainText(
            "HOW TO USE THE SOFTWARE: \n"
            "  1) Click 'Input MRI...' to select from your file explorer the MRI scan to process (unique file).\n"
            "  1*) Alternatively, Click File > Import DICOM... if you wish to process an MRI scan as a DICOM sequence.\n"
            "  2) Click 'Output destination' to choose a directory where to save the results \n"
            "  3) (OPTIONAL) Click 'Input segmentation' to choose a tumor segmentation mask file, if nothing is provided the internal model with generate the segmentation automatically \n"
            "  4) Click 'Run diagnosis' to perform the analysis. The human-readable version will be displayed in the interface.\n"
            " \n"
            "NOTE: \n"
            "The output folder is populated automatically with the following: \n"
            "  * The diagnosis results in human-readable text (report.txt) and Excel-ready format (report.csv).\n"
            "  * The automatic segmentation masks of the brain and the tumor in the original patient space (input_brain_mask.nii.gz and input_tumor_mask.nii.gz).\n"
            "  * The input volume and tumor segmentation mask in MNI space in the sub-directory named \'registration\'.\n"
        )
        self.main_display_tabwidget.addTab(self.tutorial_textedit, 'Tutorial')
        self.prompt_lineedit = QPlainTextEdit()
        self.prompt_lineedit.setReadOnly(True)
        self.prompt_lineedit.setFixedWidth(self.width * 0.97)
        self.main_display_tabwidget.addTab(self.prompt_lineedit, 'Logging')
        self.results_textedit = QPlainTextEdit()
        self.results_textedit.setReadOnly(True)
        self.results_textedit.setFixedWidth(self.width * 0.97)
        self.main_display_tabwidget.addTab(self.results_textedit, 'Results')

        self.sintef_logo_label = QLabel()
        self.sintef_logo_label.setPixmap(
            QPixmap(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/sintef-logo.png')))
        self.sintef_logo_label.setFixedWidth(0.95 * (self.width / 3))
        self.sintef_logo_label.setFixedHeight(
            1 * (self.height * self.button_height))
        self.sintef_logo_label.setScaledContents(True)
        self.stolavs_logo_label = QLabel()
        self.stolavs_logo_label.setPixmap(
            QPixmap(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/stolavs-logo.png')))
        self.stolavs_logo_label.setFixedWidth(0.95 * (self.width / 3))
        self.stolavs_logo_label.setFixedHeight(
            1 * (self.height * self.button_height))
        self.stolavs_logo_label.setScaledContents(True)
        self.amsterdam_logo_label = QLabel()
        self.amsterdam_logo_label.setPixmap(
            QPixmap(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'images/amsterdam-logo.png')))
        self.amsterdam_logo_label.setFixedWidth(0.95 * (self.width / 3))
        self.amsterdam_logo_label.setFixedHeight(
            1 * (self.height * self.button_height))
        self.amsterdam_logo_label.setScaledContents(True)

    def __set_layouts(self):
        self.input_volume_hbox = QHBoxLayout()
        self.input_volume_hbox.addStretch(1)
        self.input_volume_hbox.addWidget(self.input_image_lineedit)
        self.input_volume_hbox.addWidget(self.input_image_pushbutton)
        self.input_volume_hbox.addStretch(1)

        self.input_seg_hbox = QHBoxLayout()
        self.input_seg_hbox.addStretch(1)
        self.input_seg_hbox.addWidget(self.input_segmentation_lineedit)
        self.input_seg_hbox.addWidget(self.input_segmentation_pushbutton)
        self.input_seg_hbox.addStretch(1)

        self.output_dir_hbox = QHBoxLayout()
        self.output_dir_hbox.addStretch(1)
        self.output_dir_hbox.addWidget(self.output_folder_lineedit)
        self.output_dir_hbox.addWidget(self.output_folder_pushbutton)
        self.output_dir_hbox.addStretch(1)

        self.run_action_hbox = QHBoxLayout()
        self.run_action_hbox.addStretch(1)
        self.run_action_hbox.addWidget(self.run_button)
        self.run_action_hbox.addStretch(1)

        self.dump_area_hbox = QHBoxLayout()
        self.dump_area_hbox.addStretch(1)
        self.dump_area_hbox.addWidget(self.main_display_tabwidget)
        self.dump_area_hbox.addStretch(1)

        self.logos_hbox = QHBoxLayout()
        self.logos_hbox.addStretch(1)
        self.logos_hbox.addWidget(self.sintef_logo_label)
        self.logos_hbox.addWidget(self.stolavs_logo_label)
        self.logos_hbox.addWidget(self.amsterdam_logo_label)
        self.logos_hbox.addStretch(1)

        self.main_vbox = QVBoxLayout()
        self.main_vbox.addWidget(self.menu_bar)
        #self.main_vbox.addStretch(1)
        self.main_vbox.addLayout(self.input_volume_hbox)
        self.main_vbox.addLayout(self.output_dir_hbox)
        self.main_vbox.addLayout(self.input_seg_hbox)
        self.main_vbox.addLayout(self.run_action_hbox)
        #self.main_vbox.addStretch(1)
        self.main_vbox.addLayout(self.dump_area_hbox)
        self.main_vbox.addLayout(self.logos_hbox)
        #self.main_vbox.addStretch(1)

        self.central_label = QLabel()
        self.central_label.setLayout(self.main_vbox)
        self.setCentralWidget(self.central_label)

    def __set_stylesheet(self):
        self.central_label.setStyleSheet(
            'QLabel{background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(207, 209, 207, 255), stop:1 rgba(230, 229, 230, 255));}'
        )
        self.menu_bar.setStyleSheet(get_stylesheet('QMenuBar'))
        self.input_image_lineedit.setStyleSheet(get_stylesheet('QLineEdit'))
        self.input_image_pushbutton.setStyleSheet(
            get_stylesheet('QPushButton'))
        self.input_segmentation_lineedit.setStyleSheet(
            get_stylesheet('QLineEdit'))
        self.input_segmentation_pushbutton.setStyleSheet(
            get_stylesheet('QPushButton'))
        self.output_folder_lineedit.setStyleSheet(get_stylesheet('QLineEdit'))
        self.output_folder_pushbutton.setStyleSheet(
            get_stylesheet('QPushButton'))

        self.results_textedit.setStyleSheet(get_stylesheet('QTextEdit'))
        self.prompt_lineedit.setStyleSheet(get_stylesheet('QTextEdit'))

        self.run_button.setStyleSheet(get_stylesheet('QPushButton'))

    def __set_connections(self):
        self.run_button.clicked.connect(self.diagnose_main_wrapper)
        self.input_image_pushbutton.clicked.connect(
            self.run_select_input_image)
        self.input_segmentation_pushbutton.clicked.connect(
            self.run_select_input_segmentation)
        self.output_folder_pushbutton.clicked.connect(
            self.run_select_output_folder)

        self.readme_action.triggered.connect(self.readme_action_triggered)
        self.about_action.triggered.connect(self.about_action_triggered)
        self.quit_action.triggered.connect(self.quit_action_triggered)
        self.import_dicom_action.triggered.connect(
            self.import_dicom_action_triggered)
        self.help_action.triggered.connect(self.help_action_triggered)
        self.settings_seg_preproc_menu_p1_action.triggered.connect(
            self.settings_seg_preproc_menu_p1_action_triggered)
        self.settings_seg_preproc_menu_p2_action.triggered.connect(
            self.settings_seg_preproc_menu_p2_action_triggered)

    def __set_params(self):
        self.input_image_filepath = ''
        self.input_annotation_filepath = ''
        self.output_folderpath = ''

    def __getScreenDimensions(self):
        screen = self.app.primaryScreen()
        size = screen.size()

        self.left = size.width() / 2
        self.top = size.height() / 2
        self.width = 0.4 * size.width()
        self.height = 0.4 * size.height()

    def readme_action_triggered(self):
        popup = QMessageBox()
        popup.setWindowTitle('Tutorial')
        popup.setText(
            "HOW TO USE THE SOFTWARE: \n"
            "  1) Click 'Input MRI...' to select from your file explorer the MRI scan to process (unique file).\n"
            "  1*) Alternatively, Click File > Import DICOM... if you wish to process an MRI scan as a DICOM sequence.\n"
            "  2) Click 'Output destination' to choose a directory where to save the results \n"
            "  3) (OPTIONAL) Click 'Input segmentation' to choose a tumor segmentation mask file, if nothing is provided the internal model with generate the segmentation automatically \n"
            "  4) Click 'Run diagnosis' to perform the analysis. The human-readable version will be displayed in the interface.\n"
            " \n"
            "NOTE: \n"
            "The output folder is populated automatically with the following: \n"
            "  * The diagnosis results in human-readable text (report.txt) and Excel-ready format (report.csv).\n"
            "  * The automatic segmentation masks of the brain and the tumor in the original patient space (input_brain_mask.nii.gz and input_tumor_mask.nii.gz).\n"
            "  * The input volume and tumor segmentation mask in MNI space in the sub-directory named \'registration\'.\n"
        )
        popup.exec_()

    def about_action_triggered(self):
        popup = QMessageBox()
        popup.setWindowTitle('About')
        popup.setText(
            'Software developed as part of a collaboration between: \n'
            '  * Departement of Health Research, SINTEF\n'
            '  * St. Olavs hospital, Trondheim University Hospital\n'
            '  * Amsterdam University Medical Center\n\n'
            'Contact: David Bouget, Andre Pedersen\n\n'
            'For questions about the software, please visit:\n'
            'https://github.com/SINTEFMedtek/GSI-RADS\n'
            'For questions about the methodological aspect, please refer to the original publication:\n'
            'https://www.mdpi.com/2072-6694/13/12/2854/review_report')
        popup.exec_()

    def quit_action_triggered(self):
        self.printer_thread.stop()
        sys.exit()

    def diagnose_main_wrapper(self):
        self.run_diagnosis_thread = threading.Thread(target=self.run_diagnosis)
        self.run_diagnosis_thread.daemon = True  # using daemon thread the thread is killed gracefully if program is abruptly closed
        self.run_diagnosis_thread.start()

    def run_diagnosis(self):
        if not os.path.exists(self.input_image_filepath) or not os.path.exists(
                self.output_folderpath):
            self.standardOutputWritten(
                'Process could not be started - The 1st and 2nd above-fields must be filled in.\n'
            )
            return

        self.run_button.setEnabled(False)
        self.prompt_lineedit.clear()
        self.main_display_tabwidget.setCurrentIndex(1)
        QApplication.processEvents(
        )  # to immidiently update GUI after button is clicked
        self.seg_preprocessing_scheme = 'P1' if self.settings_seg_preproc_menu_p1_action.isChecked(
        ) else 'P2'

        try:
            start_time = time.time()
            print('Initialize - Begin (Step 0/6)')
            from diagnosis.main import diagnose_main
            print('Initialize - End (Step 0/6)')
            print('Step runtime: {} seconds.'.format(
                np.round(time.time() - start_time, 3)) + "\n")
            diagnose_main(
                input_volume_filename=self.input_image_filepath,
                input_segmentation_filename=self.input_annotation_filepath,
                output_folder=self.output_folderpath,
                preprocessing_scheme=self.seg_preprocessing_scheme)
        except Exception as e:
            print('{}'.format(traceback.format_exc()))
            self.run_button.setEnabled(True)
            self.standardOutputWritten(
                'Process could not be completed - Issue arose.\n')
            QApplication.processEvents()
            return

        self.run_button.setEnabled(True)
        results_filepath = os.path.join(
            ResourcesConfiguration.getInstance().output_folder, 'report.txt')
        self.results_textedit.setPlainText(open(results_filepath, 'r').read())
        self.main_display_tabwidget.setCurrentIndex(2)

    def run_select_input_image(self):
        input_image_filedialog = QFileDialog()
        self.input_image_filepath = input_image_filedialog.getOpenFileName(
            self, 'Select input T1 MRI', '~',
            "Image files (*.nii *.nii.gz *.nrrd *.mha *.mhd)")[0]
        self.input_image_lineedit.setText(self.input_image_filepath)

    def run_select_input_segmentation(self):
        filedialog = QFileDialog()
        self.input_annotation_filepath = filedialog.getOpenFileName(
            self, 'Select input segmentation file', '~',
            "Image files (*.nii *.nii.gz)")[0]
        self.input_segmentation_lineedit.setText(
            self.input_annotation_filepath)

    def import_dicom_action_triggered(self):
        filedialog = QFileDialog()
        filedialog.setFileMode(QFileDialog.DirectoryOnly)
        self.input_image_filepath = filedialog.getExistingDirectory(
            self, 'Select DICOM folder', '~')
        self.input_image_lineedit.setText(self.input_image_filepath)

    def run_select_output_folder(self):
        filedialog = QFileDialog()
        filedialog.setFileMode(QFileDialog.DirectoryOnly)
        self.output_folderpath = filedialog.getExistingDirectory(
            self, 'Select output folder', '~')
        self.output_folder_lineedit.setText(self.output_folderpath)

    def standardOutputWritten(self, text):
        self.prompt_lineedit.moveCursor(QTextCursor.End)
        self.prompt_lineedit.insertPlainText(text)

        QApplication.processEvents()

    def help_action_triggered(self):
        # opens browser with specified url, directs user to Issues section of GitHub repo
        QDesktopServices.openUrl(
            QUrl("https://github.com/SINTEFMedtek/GSI-RADS/issues"))

    def settings_seg_preproc_menu_p1_action_triggered(self, status):
        if status:
            self.settings_seg_preproc_menu_p2_action.setChecked(False)
        else:
            self.settings_seg_preproc_menu_p2_action.setChecked(True)

    def settings_seg_preproc_menu_p2_action_triggered(self, status):
        if status:
            self.settings_seg_preproc_menu_p1_action.setChecked(False)
        else:
            self.settings_seg_preproc_menu_p1_action.setChecked(True)
Ejemplo n.º 27
0
class VOGTab(QWidget):
    """ This code is for helping the user interact with the configurations of the VOG device. """
    def __init__(self, device, ch):
        self.logger = logging.getLogger(__name__)
        self.logger.addHandler(ch)
        self.logger.debug("Initializing")
        try:
            super().__init__()
        except Exception as e:
            self.logger.exception(
                "Error making VOGTab, passed parent is invalid")
            return
        self.setLayout(QVBoxLayout(self))
        self.setGeometry(QRect(0, 0, 200, 500))
        self.setMaximumHeight(500)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set configuration value display area"""
        self.__config_frame = EasyFrame()
        self.__config_horiz_layout = QHBoxLayout(self.__config_frame)
        self.__config_label = QLabel(self.__config_frame)
        self.__config_label.setAlignment(Qt.AlignCenter)
        self.__config_horiz_layout.addWidget(self.__config_label)
        self.__config_val_line_edit = QLineEdit(self.__config_frame)
        self.__config_val_line_edit.setAlignment(Qt.AlignCenter)
        self.__config_horiz_layout.addWidget(self.__config_val_line_edit)
        self.layout().addWidget(self.__config_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set preset button selection area. """
        self.__presets_frame = EasyFrame()
        self.__presets_vert_layout = QVBoxLayout(self.__presets_frame)
        self.__nhtsa_button = ClickAnimationButton(self.__presets_frame)
        self.__presets_vert_layout.addWidget(self.__nhtsa_button)
        self.__eblindfold_button = ClickAnimationButton(self.__presets_frame)
        self.__presets_vert_layout.addWidget(self.__eblindfold_button)
        self.__direct_control_button = ClickAnimationButton(
            self.__presets_frame)
        self.__presets_vert_layout.addWidget(self.__direct_control_button)
        self.layout().addWidget(self.__presets_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set open duration, close duration, and debounce time settings display area. """
        self.__input_box_frame = EasyFrame()
        self.__input_box_grid_layout = QGridLayout(self.__input_box_frame)
        self.__input_box_grid_layout.setContentsMargins(0, 6, 0, 6)
        self.__open_dur_label = QLabel(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__open_dur_label, 0, 0, 1,
                                               1)
        self.__open_dur_line_edit = QLineEdit(self.__input_box_frame)
        self.__open_dur_line_edit.setFixedWidth(80)
        self.__input_box_grid_layout.addWidget(self.__open_dur_line_edit, 0, 1,
                                               1, 1)
        self.__open_inf_check_box = QCheckBox(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__open_inf_check_box, 0, 2,
                                               1, 1)
        self.__close_dur_label = QLabel(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__close_dur_label, 1, 0, 1,
                                               1)
        self.__close_dur_line_edit = QLineEdit(self.__input_box_frame)
        self.__close_dur_line_edit.setFixedWidth(80)
        self.__input_box_grid_layout.addWidget(self.__close_dur_line_edit, 1,
                                               1, 1, 1)
        self.__close_inf_check_box = QCheckBox(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__close_inf_check_box, 1,
                                               2, 1, 1)
        self.__debounce_label = QLabel(self.__input_box_frame)
        self.__input_box_grid_layout.addWidget(self.__debounce_label, 2, 0, 1,
                                               1)
        self.__debounce_time_line_edit = QLineEdit(self.__input_box_frame)
        self.__debounce_time_line_edit.setFixedWidth(80)
        self.__input_box_grid_layout.addWidget(self.__debounce_time_line_edit,
                                               2, 1, 1, 1)
        self.layout().addWidget(self.__input_box_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set button mode setting display area. """
        self.__button_mode_frame = EasyFrame()
        self.__button_mode_horiz_layout = QHBoxLayout(self.__button_mode_frame)
        self.__button_mode_label = QLabel(self.__button_mode_frame)
        self.__button_mode_horiz_layout.addWidget(self.__button_mode_label)
        self.__button_mode_selector = QComboBox(self.__button_mode_frame)
        self.__button_mode_selector.addItem("")
        self.__button_mode_selector.addItem("")
        self.__button_mode_horiz_layout.addWidget(self.__button_mode_selector)
        self.layout().addWidget(self.__button_mode_frame)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set upload button selection area. """
        self.__upload_settings_button = ClickAnimationButton()
        self.layout().addWidget(self.__upload_settings_button)

        self.layout().addWidget(EasyFrame(line=True))
        """ Set manual control selection area. """
        self.__manual_control_button = ClickAnimationButton()
        self.layout().addWidget(self.__manual_control_button)

        self.layout().addWidget(EasyFrame(line=True))

        self.__graph_buttons = []
        self.device_info = device
        self.__index = 0
        self.__set_texts()
        self.__set_tooltips()
        self.logger.debug("Initialized")

    def add_manual_control_handler(self, func):
        self.logger.debug("running")
        self.__manual_control_button.clicked.connect(func)
        self.logger.debug("done")

    def add_nhtsa_button_handler(self, func):
        self.logger.debug("running")
        self.__nhtsa_button.clicked.connect(func)
        self.logger.debug("done")

    def add_eblind_button_handler(self, func):
        self.logger.debug("running")
        self.__eblindfold_button.clicked.connect(func)
        self.logger.debug("done")

    def add_direct_control_button_handler(self, func):
        self.logger.debug("running")
        self.__direct_control_button.clicked.connect(func)
        self.logger.debug("done")

    def add_upload_button_handler(self, func):
        self.logger.debug("running")
        self.__upload_settings_button.clicked.connect(func)
        self.logger.debug("done")

    def add_open_inf_handler(self, func):
        self.logger.debug("running")
        self.__open_inf_check_box.toggled.connect(func)
        self.logger.debug("done")

    def add_close_inf_handler(self, func):
        self.logger.debug("running")
        self.__close_inf_check_box.toggled.connect(func)
        self.logger.debug("done")

    def add_open_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__open_dur_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def add_close_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__close_dur_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def add_debounce_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__debounce_time_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def add_button_mode_entry_changed_handler(self, func):
        self.logger.debug("running")
        self.__button_mode_selector.currentIndexChanged.connect(func)
        self.logger.debug("done")

    def add_config_val_changed_handler(self, func):
        self.logger.debug("running")
        self.__config_val_line_edit.textChanged.connect(func)
        self.logger.debug("done")

    def set_upload_button_activity(self, is_active):
        """ Set upload button to enabled or disabled depending on is_active bool. """
        self.logger.debug("running")
        self.__upload_settings_button.setEnabled(is_active)
        self.logger.debug("done")

    def set_config_value(self, value):
        """ Set display value of config.txt. """
        self.logger.debug("running")
        self.__config_val_line_edit.setText(value)
        self.logger.debug("done")

    def get_config_value(self):
        return self.__config_val_line_edit.text()

    def get_open_val(self):
        return self.__open_dur_line_edit.text()

    def set_open_val(self, val):
        """ Set display value of open duration. """
        self.logger.debug("running")
        self.__open_dur_line_edit.setText(str(val))
        self.logger.debug("done")

    def set_open_val_error(self, is_error):
        """ Set display of error in open duration line edit. """
        self.logger.debug("running")
        if is_error:
            self.__open_dur_line_edit.setStyleSheet(tab_line_edit_error_style)
        else:
            self.__open_dur_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self.logger.debug("done")

    def set_close_val_error(self, is_error):
        """ Set display of error in close duration line edit. """
        self.logger.debug("running")
        if is_error:
            self.__close_dur_line_edit.setStyleSheet(tab_line_edit_error_style)
        else:
            self.__close_dur_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self.logger.debug("done")

    def set_debounce_val_error(self, is_error):
        """ Set display of error in debounce line edit. """
        self.logger.debug("running")
        if is_error:
            self.__debounce_time_line_edit.setStyleSheet(
                tab_line_edit_error_style)
        else:
            self.__debounce_time_line_edit.setStyleSheet(
                tab_line_edit_compliant_style)
        self.logger.debug("done")

    def set_open_val_entry_activity(self, is_active):
        """ Set open value line edit to enabled or disabled depending on is_active bool. """
        self.logger.debug("running")
        self.__open_dur_line_edit.setEnabled(is_active)
        self.logger.debug("done")

    def get_open_inf(self):
        return self.__open_inf_check_box.isChecked()

    def set_open_inf(self, is_checked):
        """ Set open infinity checkbox state to is_checked. """
        self.logger.debug("running")
        self.__open_inf_check_box.setChecked(is_checked)
        self.logger.debug("done")

    def get_close_val(self):
        return self.__close_dur_line_edit.text()

    def set_close_val(self, val):
        """ Set display value of close duration. """
        self.logger.debug("running")
        self.__close_dur_line_edit.setText(str(val))
        self.logger.debug("done")

    def set_close_val_entry_activity(self, is_active):
        """ Set close value line edit to enabled or disabled depending on is_active bool. """
        self.logger.debug("running")
        self.__close_dur_line_edit.setEnabled(is_active)
        self.logger.debug("done")

    def get_close_inf(self):
        return self.__close_inf_check_box.isChecked()

    def set_close_inf(self, is_checked):
        """ Set close infinity checkbox state to is_checked. """
        self.logger.debug("running")
        self.__close_inf_check_box.setChecked(is_checked)
        self.logger.debug("done")

    def get_debounce_val(self):
        return self.__debounce_time_line_edit.text()

    def set_debounce_val(self, val):
        """ Set debounce display value. """
        self.logger.debug("running")
        self.__debounce_time_line_edit.setText(str(val))
        self.logger.debug("done")

    def get_button_mode(self):
        return self.__button_mode_selector.currentIndex()

    def set_button_mode(self, val):
        """ Set display value of button mode. """
        self.logger.debug("running")
        self.__button_mode_selector.setCurrentIndex(int(val))
        self.logger.debug("done")

    def get_name(self):
        return self.device_info

    def __set_texts(self):
        self.logger.debug("running")
        self.__config_label.setText("Current configuration:")
        self.__config_val_line_edit.setText("DIRECT CONTROL")
        self.__nhtsa_button.setText("NHTSA")
        self.__eblindfold_button.setText("eBlindfold")
        self.__direct_control_button.setText("Direct Control")
        self.__open_dur_label.setText("Open Duration")
        self.__open_inf_check_box.setText("INF")
        self.__close_dur_label.setText("Close Duration")
        self.__close_inf_check_box.setText("INF")
        self.__debounce_label.setText("Debounce Time")
        self.__button_mode_label.setText("Button Mode")
        self.__button_mode_selector.setItemText(0, "Hold")
        self.__button_mode_selector.setItemText(1, "Click")
        self.__upload_settings_button.setText("Upload settings")
        self.__manual_control_button.setText("Toggle Lens")
        self.logger.debug("done")

    def __set_tooltips(self):
        self.logger.debug("running")
        self.__config_label.setToolTip("Current device configuration")
        self.__config_val_line_edit.setToolTip("Enter custom config name here")
        self.__config_val_line_edit.setPlaceholderText("Custom config name")
        self.__nhtsa_button.setToolTip("Set Device to NHTSA standard")
        self.__eblindfold_button.setToolTip("Set Device to eBlindfold mode")
        self.__direct_control_button.setToolTip(
            "Set Device to Direct Control mode")
        self.__button_mode_label.setToolTip("CHANGEME")
        self.__open_dur_label.setToolTip("Range: " + str(vog_min_open_close) +
                                         "-" + str(vog_max_open_close))
        self.__close_dur_label.setToolTip("Range: " + str(vog_min_open_close) +
                                          "-" + str(vog_max_open_close))
        self.__debounce_label.setToolTip("Range: " + str(vog_debounce_min) +
                                         "-" + str(vog_debounce_max))
        self.__open_inf_check_box.setToolTip("Set to manual switching")
        self.__close_inf_check_box.setToolTip("Set to manual switching")
        self.__upload_settings_button.setToolTip(
            "Upload current configuration to device")
        self.__manual_control_button.setToolTip(
            "Manually open or close the lens")
        self.logger.debug("done")
Ejemplo n.º 28
0
class FormAndMenuWindow(QMainWindow):
    """
    This class creates a form to edit a dictionary. It nests tabs for different
    levels of the nesting within the dictionaries.

    This automatically builds an interface from the dictionary.
    """

    def __init__(self, parent=None):
        """
        Parameters
        ----------
        dict_to_edit: Dict[str, Any]
            The dictionary to edit in this form.

        output_filename: str
            The filename to write the dictionary when the save button is clicked.

        parent
            The parent as needed by the base class.
        """
        super(FormAndMenuWindow, self).__init__(parent)
        self.analysis_yaml_editor_widget = None
        self.modeling_yaml_widget = None
        self.geometry_yaml_widget = None
        self.geometry_filename_line_edit = None
        self.modeling_filename_line_edit = None
        self.analysis_filename_line_edit = None
        self.geometry_dict = None
        self.analysis_dict = None
        self.modeling_dict = None
        self.geometry_filename = None
        self.analysis_filename = None
        self.modeling_filename = None
        self.main_widget = None
        self.status_widget = None
        self.status_label = None

    def setup(self) -> None:
        """
        After this class is instantiated, this method should be called to
        lay out the user interface.
        """
        self.setWindowTitle("YAML GUI")
        # self.setup_menu_bar()

        central_widget = self.create_central_widget()
        self.setCentralWidget(central_widget)

    def recursion_ui_setup(self, dict_or_list: Union[List[Any], Dict[str, Any]]) -> QFormLayout:
        """
        This recursive method is where the automatic layout magic happens.
        This method calls itself recursively as it descends down the dictionary
        nesting structure.

        Basically, any given dictionary can consist of scalar and dictionary
        values. At each level of the dictionary, edit fields are placed for
        scalar values and tabbed widgets are placed for the next level of
        nesting.

        Parameters
        ----------
        dict_or_list: Dict[str, Any]
            The dictionary to automatically lay out in to the interface.
        """
        form_level_layout = QFormLayout()
        dict_tabs = QTabWidget()
        display_tabs = False
        subscripts_values = dict_or_list.items() if type(dict_or_list) is dict else enumerate(dict_or_list)  # type: ignore
        for k, v in subscripts_values:

            # Recursive call for nested dictionaries within dictionaries.
            if type(v) is dict:
                display_tabs = True
                child_widget = QWidget()
                child_layout = self.recursion_ui_setup(v)
                child_widget.setLayout(child_layout)
                dict_tabs.addTab(child_widget, str(k))

            # Recursive call for nested dictionaries within lists.
            elif type(v) is list and type(v[0]) is dict:
                display_tabs = True
                child_widget = QWidget()
                child_layout = self.recursion_ui_setup(v)
                child_widget.setLayout(child_layout)
                dict_tabs.addTab(child_widget, str(k))

            # Otherwise just lay out a label and text field.
            else:
                line_edit = FocusQLineEdit(str(v))
                line_edit.setMinimumWidth(150)
                line_edit.set_dictionary_and_key(dict_or_list, k)
                form_level_layout.addRow(QLabel(k), line_edit)

        # If there is a nested dictionary, display it.
        if display_tabs:
            form_level_layout.addRow(dict_tabs)

        # Return the whole layout
        return form_level_layout

    def write_dict_to_yaml(self) -> None:
        """
        This is the event handler for the save button. It simply writes the
        dictionary (which has been continuously updated during focus out
        events) to a YAML file as specified in self.output_filename.
        """
        with open(self.output_filename, "w") as file:
            yaml.dump(self.dict_to_edit, file)

    def create_central_widget(self) -> QWidget:
        """
        Returns
        -------
        QWidget
            The form with buttons on it.
        """
        status_and_main_widget = QWidget()
        status_and_main_widget_layout = QVBoxLayout()

        self.status_widget = QWidget()
        status_form_layout = QFormLayout()
        status_label = QLabel("Status:")
        self.status_label = QLabel()
        self.status_label.setText("Please create simulation configurations.")
        status_form_layout.addRow(status_label, self.status_label)
        self.status_widget.setLayout(status_form_layout)

        self.main_widget = QWidget()
        subsection_width = 500
        subsection_height = 900

        geometry_section_label = QLabel("Geometry")
        geometry_section_label.setStyleSheet("font-weight: bold;")
        geometry_filename_button = QPushButton("Select geometry YAML...")
        # geometry_visualize_button = QPushButton("Visualize geometry")
        self.geometry_filename_line_edit = QLineEdit()
        self.geometry_filename_line_edit.setPlaceholderText("Please select a geometry file.")
        self.geometry_filename_line_edit.setFixedWidth(200)
        self.geometry_filename_line_edit.setReadOnly(True)
        geometry_filename_button.clicked.connect(self.file_picker_geometry)

        modeling_section_label = QLabel("Modeling")
        modeling_section_label.setStyleSheet("font-weight: bold;")
        modeling_filename_button = QPushButton("Select modeling YAML...")
        self.modeling_filename_line_edit = QLineEdit()
        self.modeling_filename_line_edit.setPlaceholderText("Please select a modeling file.")
        self.modeling_filename_line_edit.setFixedWidth(200)
        self.modeling_filename_line_edit.setReadOnly(True)
        modeling_filename_button.clicked.connect(self.file_picker_modeling)

        analysis_section_label = QLabel("Analysis")
        analysis_section_label.setStyleSheet("font-weight: bold;")
        analysis_filename_button = QPushButton("Select analysis YAML...")
        self.analysis_filename_line_edit = QLineEdit()
        self.analysis_filename_line_edit.setPlaceholderText("Please select an analysis file...")
        self.analysis_filename_line_edit.setFixedWidth(200)
        self.analysis_filename_line_edit.setReadOnly(True)
        analysis_filename_button.clicked.connect(self.file_picker_analysis)

        run_weis_button = QPushButton("Run WISDEM")
        run_weis_button.clicked.connect(self.run_weis_clicked)

        self.modeling_yaml_widget = QWidget()
        self.analysis_yaml_editor_widget = QWidget()
        self.geometry_yaml_widget = QWidget()

        geometry_layout = QFormLayout()
        geometry_layout.addRow(geometry_section_label)
        geometry_layout.addRow(self.geometry_filename_line_edit, geometry_filename_button)
        # geometry_layout.addRow(geometry_visualize_button)
        geometry_layout.addRow(self.geometry_yaml_widget)
        geometry_widget = QWidget()
        geometry_widget.setFixedWidth(subsection_width)
        geometry_widget.setFixedHeight(subsection_height)
        geometry_widget.setLayout(geometry_layout)

        modeling_layout = QFormLayout()
        modeling_layout.addRow(modeling_section_label)
        modeling_layout.addRow(self.modeling_filename_line_edit, modeling_filename_button)
        modeling_layout.addRow(self.modeling_yaml_widget)
        modeling_widget = QWidget()
        modeling_widget.setFixedWidth(subsection_width)
        modeling_widget.setFixedHeight(subsection_height)
        modeling_widget.setLayout(modeling_layout)

        analysis_layout = QFormLayout()
        analysis_layout.addRow(analysis_section_label)
        analysis_layout.addRow(self.analysis_filename_line_edit, analysis_filename_button)
        analysis_layout.addRow(self.analysis_yaml_editor_widget)
        analysis_widget = QWidget()
        analysis_widget.setFixedWidth(subsection_width)
        analysis_widget.setFixedHeight(subsection_height)
        analysis_widget.setLayout(analysis_layout)

        main_layout = QHBoxLayout()
        main_layout.addWidget(geometry_widget)
        main_layout.addWidget(modeling_widget)
        main_layout.addWidget(analysis_widget)
        main_layout.addWidget(run_weis_button)

        self.main_widget.setLayout(main_layout)
        # return self.main_widget

        status_and_main_widget_layout.addWidget(self.status_widget)
        status_and_main_widget_layout.addWidget(self.main_widget)
        status_and_main_widget.setLayout(status_and_main_widget_layout)

        return status_and_main_widget

    def run_weis_clicked(self):
        """
        When the "Run WEIS" button is clicked, a popup dialog
        will pop up asking what the user wants to do. If the user
        has skipped any configuration files, then it will tell them
        to go back and create those configuration files. If the user
        has specified all the configuration files, then it will prompt
        the user for confirmation before saving the WEIS configuration
        files.
        """
        if self.geometry_filename is None:
            msg = QMessageBox()
            msg.setText("Run WISDEM: Missing file")
            msg.setInformativeText("You did not specify a geometry file.")
            msg.addButton(QMessageBox.Cancel)
            msg.exec()
        elif self.modeling_filename is None:
            msg = QMessageBox()
            msg.setText("Run WISDEM: Missing file")
            msg.setInformativeText("You did not specify a modeling file.")
            msg.addButton(QMessageBox.Cancel)
            msg.exec()
        elif self.analysis_filename is None:
            msg = QMessageBox()
            msg.setText("Run WISDEM: Missing file")
            msg.setInformativeText("You did not specify an analysis file.")
            msg.addButton(QMessageBox.Cancel)
            msg.exec()
        else:
            self.status_label.setText("Writing files...")
            self.write_configuration_files()
            self.status_label.setText("Configuration files written.")
            msg = QMessageBox()
            msg.setText("Run WISDEM: Configuration files complete!")
            msg.setInformativeText("Click cancel to back out and continue editing. Click OK to run WISDEM.")
            msg.addButton(QMessageBox.Cancel)
            msg.addButton(QMessageBox.Ok)
            choice = msg.exec()
            if choice == QMessageBox.Ok:
                self.disable_ui_and_execute_wisdem()

    def write_configuration_files(self):
        """
        The "Run WEIS" click event handler calls this method when it is ready
        to make an attempt to run WEIS. It checks to see if all file shave been
        edited
        """
        if self.geometry_filename is not None:
            print(f"Writing geometry: {self.geometry_filename}")
            with open(self.geometry_filename, "w") as file:
                yaml.dump(self.geometry_dict, file)
        else:
            print("No geometry file to write")

        if self.analysis_filename is not None:
            print(f"Writing analysis: {self.analysis_filename}")
            with open(self.analysis_filename, "w") as file:
                yaml.dump(self.analysis_dict, file)
        else:
            print("No analysis file to write")

        if self.modeling_filename is not None:
            print(f"Writing modeling: {self.modeling_filename}")
            with open(self.modeling_filename, "w") as file:
                yaml.dump(self.modeling_dict, file)
        else:
            print("No modeling file to write")

    def disable_ui_and_execute_wisdem(self):
        """
        This method disables all widgets on the UI and executes WISDEM. It
        displays message boxes depending on whether WISDEM executed
        successfully.
        """
        self.main_widget.setEnabled(False)
        self.status_label.setText("Running WISDEM")

        try:
            wt_opt, modeling_options, analysis_options = run_wisdem(
                self.geometry_filename, self.modeling_filename, self.analysis_filename
            )
        except Exception as err:
            short_error_message = f"{type(err)}: {err}. More details on command line."
            traceback.print_exc(file=sys.stdout)
            self.status_label.setText("Execution error")
            msg = QMessageBox()
            msg.setText("WISDEM execution error")
            msg.setInformativeText(short_error_message)
            msg.addButton(QMessageBox.Ok)
            msg.exec()
            self.main_widget.setEnabled(True)
        else:
            self.status_label.setText("Execution success")
            msg = QMessageBox()
            msg.setText("WISDEM executed successfully")
            msg.addButton(QMessageBox.Ok)
            msg.exec()
            self.main_widget.setEnabled(True)

    def file_picker_geometry(self):
        """
        Shows the open file dialog for the geometry file.

        Returns
        -------
        None
            Returns nothing for now.
        """
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setViewMode(QFileDialog.Detail)
        self.geometry_filename, _ = dialog.getOpenFileName(None, "Open File", str(Path.home()), "YAML (*.yml *.yaml)")
        self.geometry_filename_line_edit.setText(self.geometry_filename)
        self.geometry_dict = self.read_yaml_to_dictionary(self.geometry_filename)
        layout = self.recursion_ui_setup(self.geometry_dict)
        self.geometry_yaml_widget.setLayout(layout)

    def file_picker_modeling(self):
        """
        Shows the open dialog

        Returns
        -------
        None
            Returns nothing for now.
        """
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setViewMode(QFileDialog.Detail)
        self.modeling_filename, _ = dialog.getOpenFileName(None, "Open File", str(Path.home()), "YAML (*.yml *.yaml)")
        self.modeling_filename_line_edit.setText(self.modeling_filename)
        self.modeling_dict = self.read_yaml_to_dictionary(self.modeling_filename)
        layout = self.recursion_ui_setup(self.modeling_dict)
        self.modeling_yaml_widget.setLayout(layout)

    def file_picker_analysis(self) -> None:
        """
        Shows the open dialog for the analysis YAML

        Returns
        -------
        None
        """
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setViewMode(QFileDialog.Detail)
        self.analysis_filename, _ = dialog.getOpenFileName(None, "Open File", str(Path.home()), "YAML (*.yml *.yaml)")
        self.analysis_filename_line_edit.setText(self.analysis_filename)
        self.analysis_dict = self.read_yaml_to_dictionary(self.analysis_filename)
        layout = self.recursion_ui_setup(self.analysis_dict)
        self.analysis_yaml_editor_widget.setLayout(layout)

    @staticmethod
    def read_yaml_to_dictionary(input_filename: str) -> Dict[str, Any]:
        """
        This reads the YAML input which is used to build the user interface.
        """
        with open(input_filename) as file:
            result = yaml.load(file, Loader=yaml.FullLoader)
        return result
Ejemplo n.º 29
0
class ParameterInteger(QWidget):
    def check_int(self, s):
        if s[0] in ("-", "+"):
            return s[1:].isdigit()
        return s.isdigit()

    def clamp(self, value, min_value, max_value):
        if value < min_value:
            return min_value
        elif value > max_value:
            return max_value
        else:
            return value

    def __init__(self,
                 parent=None,
                 value=0,
                 name="",
                 label_text="",
                 min_value=None,
                 max_value=None,
                 label_width=64,
                 height=22,
                 min_visible=0,
                 max_visible=10,
                 change_callback=None):
        QWidget.__init__(self, parent)

        self.VERTICAL_MARGIN = 0
        self.HORIZONTAL_MARGIN = 0

        self.name = name
        self.label_text = label_text
        self.min_value_raw = min_value
        self.max_value_raw = max_value
        self.min_value = min_value if min_value is not None else -sys.maxsize
        self.max_value = max_value if max_value is not None else sys.maxsize
        self.value = self.clamp(value, self.min_value, self.max_value)
        self.min_visible = max(self.min_value, min(min_visible, self.value))
        self.max_visible = min(self.max_value, max(max_visible, self.value))
        self._is_callback_define = False
        if change_callback is not None:
            self._change_callback = change_callback
            self._is_callback_define = True
        self._last_call = None

        self.label = QLabel(label_text)
        self.label.setFixedWidth(label_width)
        self.label.setFixedHeight(height)
        self.value_textbox = QLineEdit()
        self.value_textbox.setFixedWidth(52)
        self.value_textbox.setFixedHeight(height)
        self._update_value_label()
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setFixedHeight(height)
        self._update_visible_interval()
        self.slider.setValue(value)
        layout = QHBoxLayout()
        layout.setContentsMargins(self.HORIZONTAL_MARGIN, self.VERTICAL_MARGIN,
                                  self.HORIZONTAL_MARGIN, self.VERTICAL_MARGIN)
        layout.addWidget(self.label)
        layout.addWidget(self.value_textbox)
        layout.addWidget(self.slider)
        self.setLayout(layout)

        self.slider.valueChanged.connect(self.slider_valueChanged)
        self.value_textbox.returnPressed.connect(self.textbox_enter)
        self.value_textbox.editingFinished.connect(self.textbox_enter)
        self.slider.sliderReleased.connect(self.slider_sliderReleased)

    def _update_visible_interval(self):
        self.slider.setRange(self.min_visible, self.max_visible)

    def _update_value_label(self):
        self.value_textbox.setText(str(self.value))

    def slider_valueChanged(self, value):
        self.value = value
        self._update_value_label()
        self.value_change()

    def slider_sliderReleased(self):
        self.try_change_visible(self.value)
        self.slider.setValue(self.value)

    def try_change_visible(self, new_value):
        delta = self.max_visible - self.min_visible
        # increase visible interval if new value out of the current
        if new_value <= self.min_visible:
            self.min_visible = max(self.min_value, new_value - delta)
        if new_value >= self.max_visible:
            self.max_visible = min(self.max_value, new_value + delta)
        self._update_visible_interval()

    def textbox_enter(self):
        text = self.value_textbox.text()
        # check is this text is integer
        if self.check_int(text):
            new_value = int(text)
            # clamp value
            if new_value < self.min_value:
                new_value = self.min_value
            if new_value > self.max_value:
                new_value = self.max_value
            self.try_change_visible(new_value)
            self.slider.setValue(new_value)
            self._update_value_label()
            self.value_change()
        else:
            self._update_value_label()
        self.value_textbox.clearFocus()

    def value_change(self):
        if self._is_callback_define:
            if self._last_call is None or self._last_call != self.value:
                self._last_call = self.value
                self._change_callback(param_name=self.name,
                                      param_value=self.value)
Ejemplo n.º 30
0
class MonteCarloTab(NewAnalysisTab):
    def __init__(self, parent=None):
        super(MonteCarloTab, self).__init__(parent)
        self.parent: LCAResultsSubTab = parent

        self.layout.addLayout(get_header_layout('Monte Carlo Simulation'))
        self.scenario_label = QLabel("Scenario:")
        self.include_box = QGroupBox("Include uncertainty for:", self)
        grid = QGridLayout()
        self.include_tech = QCheckBox("Technosphere", self)
        self.include_tech.setChecked(True)
        self.include_bio = QCheckBox("Biosphere", self)
        self.include_bio.setChecked(True)
        self.include_cf = QCheckBox("Characterization Factors", self)
        self.include_cf.setChecked(True)
        self.include_parameters = QCheckBox("Parameters", self)
        self.include_parameters.setChecked(True)
        grid.addWidget(self.include_tech, 0, 0)
        grid.addWidget(self.include_bio, 0, 1)
        grid.addWidget(self.include_cf, 1, 0)
        grid.addWidget(self.include_parameters, 1, 1)
        self.include_box.setLayout(grid)

        self.add_MC_ui_elements()

        self.table = LCAResultsTable()
        self.table.table_name = 'MonteCarlo_' + self.parent.cs_name
        self.plot = MonteCarloPlot(self.parent)
        self.plot.hide()
        self.plot.plot_name = 'MonteCarlo_' + self.parent.cs_name
        self.layout.addWidget(self.plot)
        self.export_widget = self.build_export(has_plot=True, has_table=True)
        self.layout.addWidget(self.export_widget)
        self.layout.setAlignment(QtCore.Qt.AlignTop)
        self.connect_signals()

    def connect_signals(self):
        self.button_run.clicked.connect(self.calculate_mc_lca)
        # signals.monte_carlo_ready.connect(self.update_mc)
        # self.combobox_fu.currentIndexChanged.connect(self.update_plot)
        self.combobox_methods.currentIndexChanged.connect(
            # ignore the index and send the cs_name instead
            lambda x: self.update_mc(cs_name=self.parent.cs_name))

        # signals
        # self.radio_button_biosphere.clicked.connect(self.button_clicked)
        # self.radio_button_technosphere.clicked.connect(self.button_clicked)

        if self.using_presamples:
            self.scenario_box.currentIndexChanged.connect(
                self.parent.update_scenario_data)
            self.parent.update_scenario_box_index.connect(
                lambda index: self.set_combobox_index(self.scenario_box, index
                                                      ))

    def add_MC_ui_elements(self):
        layout_mc = QVBoxLayout()

        # H-LAYOUT start simulation
        self.button_run = QPushButton('Run Simulation')
        self.label_iterations = QLabel('Iterations:')
        self.iterations = QLineEdit('10')
        self.iterations.setFixedWidth(40)
        self.iterations.setValidator(QtGui.QIntValidator(1, 1000))
        self.label_seed = QLabel('Random seed:')
        self.label_seed.setToolTip(
            'Seed value (integer) for the random number generator. '
            'Use this for reproducible samples.')
        self.seed = QLineEdit('')
        self.seed.setFixedWidth(30)

        self.hlayout_run = QHBoxLayout()
        self.hlayout_run.addWidget(self.scenario_label)
        self.hlayout_run.addWidget(self.scenario_box)
        self.hlayout_run.addWidget(self.button_run)
        self.hlayout_run.addWidget(self.label_iterations)
        self.hlayout_run.addWidget(self.iterations)
        self.hlayout_run.addWidget(self.label_seed)
        self.hlayout_run.addWidget(self.seed)
        self.hlayout_run.addWidget(self.include_box)
        self.hlayout_run.addStretch(1)
        layout_mc.addLayout(self.hlayout_run)

        # self.label_running = QLabel('Running a Monte Carlo simulation. Please allow some time for this. '
        #                             'Please do not run another simulation at the same time.')
        # self.layout_mc.addWidget(self.label_running)
        # self.label_running.hide()

        # # buttons for all FUs or for all methods
        # self.radio_button_all_fu = QRadioButton("For all functional units")
        # self.radio_button_all_methods = QRadioButton("Technosphere flows")
        #
        # self.radio_button_biosphere.setChecked(True)
        # self.radio_button_technosphere.setChecked(False)
        #
        # self.label_for_all_fu = QLabel('For all functional units')
        # self.combobox_fu = QRadioButton()
        # self.hlayout_fu = QHBoxLayout()

        # FU selection
        # self.label_fu = QLabel('Choose functional unit')
        # self.combobox_fu = QComboBox()
        # self.hlayout_fu = QHBoxLayout()
        #
        # self.hlayout_fu.addWidget(self.label_fu)
        # self.hlayout_fu.addWidget(self.combobox_fu)
        # self.hlayout_fu.addStretch()
        # self.layout_mc.addLayout(self.hlayout_fu)

        # method selection
        self.method_selection_widget = QWidget()
        self.label_methods = QLabel('Choose LCIA method')
        self.combobox_methods = QComboBox()
        self.hlayout_methods = QHBoxLayout()

        self.hlayout_methods.addWidget(self.label_methods)
        self.hlayout_methods.addWidget(self.combobox_methods)
        self.hlayout_methods.addStretch()
        self.method_selection_widget.setLayout(self.hlayout_methods)

        layout_mc.addWidget(self.method_selection_widget)
        self.method_selection_widget.hide()

        self.layout.addLayout(layout_mc)

    def build_export(self,
                     has_table: bool = True,
                     has_plot: bool = True) -> QWidget:
        """Construct the export layout but set it into a widget because we
         want to hide it."""
        export_layout = super().build_export(has_table, has_plot)
        export_widget = QWidget()
        export_widget.setLayout(export_layout)
        # Hide widget until MC is calculated
        export_widget.hide()
        return export_widget

    @QtCore.Slot(name="calculateMcLca")
    def calculate_mc_lca(self):
        self.method_selection_widget.hide()
        self.plot.hide()
        self.export_widget.hide()

        iterations = int(self.iterations.text())
        seed = None
        if self.seed.text():
            print('SEED: ', self.seed.text())
            try:
                seed = int(self.seed.text())
            except ValueError:
                traceback.print_exc()
                QMessageBox.warning(
                    self, 'Warning',
                    'Seed value must be an integer number or left empty.')
                self.seed.setText('')
                return
        includes = {
            "technosphere": self.include_tech.isChecked(),
            "biosphere": self.include_bio.isChecked(),
            "cf": self.include_cf.isChecked(),
            "parameters": self.include_parameters.isChecked(),
        }

        try:
            self.parent.mc.calculate(iterations=iterations,
                                     seed=seed,
                                     **includes)
            self.update_mc()
        except InvalidParamsError as e:  # This can occur if uncertainty data is missing or otherwise broken
            # print(e)
            traceback.print_exc()
            QMessageBox.warning(self,
                                'Could not perform Monte Carlo simulation',
                                str(e))

        # a threaded way for this - unfortunatley this crashes as:
        # pypardsio_solver is used for the 'spsolve' and 'factorized' functions. Python crashes on windows if multiple
        # instances of PyPardisoSolver make calls to the Pardiso library
        # worker_thread = WorkerThread()
        # print('Created local worker_thread')
        # worker_thread.set_mc(self.parent.mc, iterations=iterations)
        # print('Passed object to thread.')
        # worker_thread.start()
        # self.label_running.show()

        #

        # thread = NewCSMCThread() #self.parent.mc
        # thread.calculation_finished.connect(
        #     lambda x: print('Calculation finished.'))
        # thread.start()

        # # give us a thread and start it
        # thread = QtCore.QThread()
        # thread.start()
        #
        # # create a worker and move it to our extra thread
        # worker = Worker()
        # worker.moveToThread(thread)

        # self.parent.mct.start()
        # self.parent.mct.run(iterations=iterations)
        # self.parent.mct.finished()

        # objThread = QtCore.QThread()
        # obj = QObjectMC()  # self.parent.cs_name
        # obj.moveToThread(objThread)
        # obj.finished.connect(objThread.quit)
        # objThread.started.connect(obj.long_running)
        # # objThread.finished.connect(app.exit)
        # objThread.finished.connect(
        #     lambda x: print('Finished Thread!')
        # )
        # objThread.start()

        # objThread = QtCore.QThread()
        # obj = SomeObject()
        # obj.moveToThread(objThread)
        # obj.finished.connect(objThread.quit)
        # objThread.started.connect(obj.long_running)
        # objThread.finished.connect(
        #     lambda x: print('Finished Thread!')
        # )
        # objThread.start()

        # self.method_selection_widget.show()
        # self.plot.show()
        # self.export_widget.show()

    def configure_scenario(self):
        super().configure_scenario()
        self.scenario_label.setVisible(self.using_presamples)

    def update_tab(self):
        self.update_combobox(self.combobox_methods,
                             [str(m) for m in self.parent.mc.methods])
        # self.update_combobox(self.combobox_methods, [str(m) for m in self.parent.mct.mc.methods])

    def update_mc(self, cs_name=None):
        # act = self.combobox_fu.currentText()
        # activity_index = self.combobox_fu.currentIndex()
        # act_key = self.parent.mc.activity_keys[activity_index]
        # if cs_name != self.parent.cs_name:  # relevant if several CS are open at the same time
        #     return

        # self.label_running.hide()
        self.method_selection_widget.show()
        self.export_widget.show()

        method_index = self.combobox_methods.currentIndex()
        method = self.parent.mc.methods[method_index]

        # data = self.parent.mc.get_results_by(act_key=act_key, method=method)
        self.df = self.parent.mc.get_results_dataframe(method=method)

        self.update_table()
        self.update_plot(method=method)
        filename = '_'.join([
            str(x)
            for x in [self.parent.cs_name, 'Monte Carlo results',
                      str(method)]
        ])
        self.plot.plot_name, self.table.table_name = filename, filename

    def update_plot(self, method):
        idx = self.layout.indexOf(self.plot)
        self.plot.figure.clf()
        self.plot.deleteLater()
        self.plot = MonteCarloPlot(self.parent)
        self.layout.insertWidget(idx, self.plot)
        self.plot.plot(self.df, method=method)
        self.plot.show()
        if self.layout.parentWidget():
            self.layout.parentWidget().updateGeometry()

    def update_table(self):
        self.table.sync(self.df)
Ejemplo n.º 31
0
class MyWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.thread = SerialMonitorThread()
        self.thread.dataReady.connect(self.get_data, Qt.QueuedConnection)
        self.thread.setTerminationEnabled(True)

        #Menu
        self.setPalette(get_verifone_color())

        collapsible = CollapsibleWidget()
        self.init_logging(collapsible)

        self.init_download(collapsible)

        self.init_analyser(collapsible)

        collapsible.add_sections()
        # Scroll Area
        self.createLoggingDisplayLabel()
        self.scrollArea = QScrollArea()
        self.scrollArea.setBackgroundRole(QPalette.Dark)
        self.scrollArea.setWidget(self.text)
        self.scrollArea.setWidgetResizable(True)

        hLayout = QHBoxLayout()
        #hLayout.addLayout(vLayout)
        hLayout.addWidget(collapsible)
        hLayout.addWidget(self.scrollArea)

        self.setLayout(hLayout)

    def init_logging(self, collapsible):

        self.logger = QPushButton("Start Logging", self)
        self.logger.setFont(QFont("Times", 14, QFont.Bold))
        self.logger.clicked.connect(lambda: self.display_log_data())
        self.logger.setStyleSheet("background-color: white")

        #self.filterLayout = QtWidgets.QHBoxLayout()
        self.logFilterLabel = QLabel('Filter', self)
        self.logFilterLabel.setFont(QFont("Times", 14, QFont.Bold))
        self.logFilterLabel.setPalette(get_white_color_text())
        self.logFilterLabel.setFixedWidth(60)
        self.logFilter = QLineEdit(self)
        self.logFilter.setPalette(get_white_color())
        self.logFilter.setStyleSheet("background-color: white")
        self.logFilter.setFixedWidth(200)
        #self.filterLayout.addWidget(self.logFilterLabel, QtCore.Qt.AlignLeft)
        #self.filterLayout.addWidget(self.logFilter, QtCore.Qt.AlignLeft)

        self.serialList = QComboBox()
        ports = get_available_serial_ports()
        if (len(ports) == 1):
            self.serialList.addItem(ports[0])
            self.thread.set_comport(self.serialList.currentText())
        else:
            self.serialList.addItem("Select")
            for port in ports:
                self.serialList.addItem(port)

        self.serialList.currentIndexChanged.connect(
            lambda: self.set_serial_port())
        self.serialList.setStyleSheet("background-color: white")
        self.clear = QPushButton("Clear Log File", self)
        self.clear.setStyleSheet("background-color: white")
        self.clear.setFont(QFont("Times", 14, QFont.Bold))
        self.clear.clicked.connect(lambda: self.clear_data())

        widget = QFrame(collapsible.get_tree())
        widget.setPalette(get_verifone_color())
        title = "Logging"
        self.loggerGrid = QGridLayout(widget)
        self.loggerGrid.addWidget(self.logger, 0, 0, 1, 2)
        self.loggerGrid.addWidget(self.logFilterLabel, 1, 0, 1, 1)
        self.loggerGrid.addWidget(self.logFilter, 1, 1, 1, 1)
        self.loggerGrid.addWidget(self.serialList, 2, 0, 1, 2)
        self.loggerGrid.addWidget(self.clear, 3, 0, 1, 2)

        collapsible.include_section(title, widget)

    def init_download(self, collapsible):
        self.download = QPushButton("Download Package", self)
        self.download.setFont(QFont("Times", 14, QFont.Bold))
        self.download.clicked.connect(lambda: self.send_file())
        self.download.setStyleSheet("background-color: white")

        self.loadDownloadFile = QPushButton("Load File", self)
        self.loadDownloadFile.setFont(QFont("Times", 14, QFont.Bold))
        self.loadDownloadFile.clicked.connect(self.loadFromFile)
        self.loadDownloadFile.setStyleSheet("background-color: white")

        self.downloadFileName = QLineEdit("File name", self)
        self.downloadFileName.setStyleSheet("background-color: white")
        self.downloadFileName.setFixedWidth(300)

        self.downloadAddress = QLineEdit("IP Address", self)
        self.downloadAddress.setStyleSheet("background-color: white")
        self.downloadAddress.setFixedWidth(300)

        self.downloadStatus = QLabel("Download Status", self)
        self.downloadStatus.setStyleSheet(
            "background-color: rgba(3, 169, 229, 0); color : white")
        self.downloadStatus.setFixedWidth(300)
        widget = QFrame(collapsible.get_tree())
        title = "Download"

        self.downloadGrid = QGridLayout(widget)
        self.downloadGrid.addWidget(self.download, 0, 0, 1, 2)
        self.downloadGrid.addWidget(self.loadDownloadFile, 1, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadFileName, 2, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadAddress, 3, 0, 1, 2)
        self.downloadGrid.addWidget(self.downloadStatus, 4, 0, 1, 2)
        collapsible.include_section(title, widget)

    def init_analyser(self, collapsible):
        self.performanceData = QPushButton("View Performance Data", self)
        self.performanceData.setFont(QFont("Times", 14, QFont.Bold))
        self.performanceData.clicked.connect(
            lambda: self.display_performance_data())
        self.performanceData.setStyleSheet("background-color: white")

        self.performanceChart = QPushButton("View Performance Chart", self)
        self.performanceChart.setFont(QFont("Times", 14, QFont.Bold))
        self.performanceChart.clicked.connect(
            lambda: self.display_performance_chart())
        self.performanceChart.setStyleSheet("background-color: white")

        widget = QFrame(collapsible.get_tree())
        title = "Analyser"
        self.analyserGrid = QGridLayout(widget)
        self.analyserGrid.addWidget(self.performanceData, 0, 0, 1, 2)
        self.analyserGrid.addWidget(self.performanceChart, 1, 0, 1, 2)
        collapsible.include_section(title, widget)

    def loadFromFile(self):
        fileName, _ = QFileDialog.getOpenFileName(
            self, "Load Package", '', "Download Files (*.tgz);;All Files (*)")

        if not fileName:
            return

        try:
            in_file = open(str(fileName), 'rb')
        except IOError:
            QMessageBox.information(
                self, "Unable to open file",
                "There was an error opening \"%s\"" % fileName)
            return
        in_file.close()
        self.downloadFileName.setText(fileName)

    def createLoggingDisplayLabel(self):
        # Display Area
        self.text = QPlainTextEdit(self)
        self.text.setReadOnly(True)
        self.text.setFont(QFont("Times", 12, QFont.Bold))
        self.text.setTextInteractionFlags(Qt.TextSelectableByMouse
                                          | Qt.TextSelectableByKeyboard)

    def clear_data(self):
        self.text.clear()
        os.remove(logfile_path, dir_fd=None)

    def display_log_data(self):
        #send_file()

        if ('COM' in self.serialList.currentText()):
            self.createLoggingDisplayLabel()
            self.scrollArea.setWidget(self.text)
            self.thread.stop()
            self.thread.start()

            data = get_data_from_file(logfile_path)
            if (len(data) > 0 and data != None):
                self.text.appendPlainText(data)
            self.logger.setDisabled(True)

    def get_data(self, data):
        if (len(data) > 0):
            logFile = open(logfile_path, "a")
            logFile.write(data)
            logFile.close()
            filterText = self.logFilter.text()
            if filterText in data.rstrip():
                self.text.appendPlainText(data.rstrip())
                vbar = self.scrollArea.verticalScrollBar()
                vbar.setValue(vbar.maximum())

    def display_performance_data(self):
        self.thread.stop()
        data = get_data_from_file(logfile_path)
        jsonData = translate_data_to_json(data)
        self.performanceData = DisplayPerformanceData()
        self.performanceData.loadCsv(
            os.path.join(base_log_path, "performance_data.csv"))
        self.scrollArea.setWidget(self.performanceData)
        self.logger.setDisabled(False)

    def display_performance_chart(self):
        self.thread.stop()
        self.scrollArea.setWidget(get_performace_chart())
        self.logger.setDisabled(False)

    def set_serial_port(self):
        self.thread.set_comport(self.serialList.currentText())

    def send_file(self):
        base_path = os.path.join("c:/", "VFI", 'wks',
                                 'global-payment-application', 'GPA', 'output',
                                 'vos2', 'gpa', 'dl.gpa-1.0.0.0-000.tgz')
        fileName = self.downloadFileName.text()
        try:
            in_file = open(str(fileName), 'rb')
        except IOError:
            QMessageBox.information(
                self, "Unable to open file",
                "There was an error opening \"%s\"" % fileName)
            return
        in_file.close()

        load_vos_package_ip('192.168.0.104', fileName, self.downloadStatus)