Пример #1
0
class SubFileDialog(QFileDialog):
    def __init__(self, parent = None, caption = "", directory = "", filter = ""):
        super().__init__(parent, caption, directory, filter)
        self.setOption(QFileDialog.DontUseNativeDialog)

    def _initAllSubFormats(self, formatList):
        self._formats = {}
        for f in formatList:
            self._formats[f.NAME] = f

    def _addEncodingsBox(self, row, addAuto):
        mainLayout = self.layout()

        encodingLabel = QLabel(_("File encoding:"), self)

        self._encodingBox = QComboBox(self)
        if addAuto is True:
            self._encodingBox.addItem(AUTO_ENCODING_STR)
        self._encodingBox.addItems(ALL_ENCODINGS)
        self._encodingBox.setToolTip(_("Change file encoding"))
        self._encodingBox.setEditable(True)

        mainLayout.addWidget(encodingLabel, row, 0)
        mainLayout.addWidget(self._encodingBox, row, 1)

    def _addFormatBox(self, row, formatList):
        self._initAllSubFormats(formatList)
        displayedFormats = list(self._formats.keys())
        displayedFormats.sort()

        mainLayout = self.layout()

        formatLabel = QLabel(_("Subtitle format:"), self)
        self._formatBox = QComboBox(self)
        self._formatBox.addItems(displayedFormats)

        mainLayout.addWidget(formatLabel, row, 0)
        mainLayout.addWidget(self._formatBox, row, 1)

    def getEncoding(self):
        encoding = self._encodingBox.currentText()
        if encoding == AUTO_ENCODING_STR:
            encoding = None
        return encoding

    def setEncoding(self, encoding):
        index = self._encodingBox.findText(encoding)
        self._encodingBox.setCurrentIndex(index)

    def getSubFormat(self):
        return self._formats.get(self._formatBox.currentText())

    def setSubFormat(self, subFormat):
        for key, val in self._formats.items():
            if val == subFormat:
                index = self._formatBox.findText(key)
                self._formatBox.setCurrentIndex(index)
                return
Пример #2
0
class General(SettingsPage):

    NAME = 'General'

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.setLayout(QVBoxLayout())
        self.layout().setAlignment(Qt.AlignTop)

        # Startup layout
        self.layoutGroup = QGroupBox(self)
        self.layoutGroup.setTitle('Startup layout')
        self.layoutGroup.setLayout(QVBoxLayout())
        self.layout().addWidget(self.layoutGroup)

        self.startupDialogCheck = QCheckBox(self.layoutGroup)
        self.startupDialogCheck.setText('Use startup dialog')
        self.layoutGroup.layout().addWidget(self.startupDialogCheck)

        self.layoutCombo = QComboBox(self.layoutGroup)
        self.layoutCombo.addItems([lay.NAME for lay in layouts.get_layouts()])
        self.layoutGroup.layout().addWidget(self.layoutCombo)

        self.startupDialogCheck.clicked.connect(
            lambda check: self.layoutCombo.setEnabled(not check))

        # Application style
        self.themeGroup = QGroupBox(self)
        self.themeGroup.setTitle('Application theme')
        self.themeGroup.setLayout(QVBoxLayout())
        self.layout().addWidget(self.themeGroup)

        self.themeCombo = QComboBox(self.themeGroup)
        self.themeCombo.addItems(styles.get_styles())
        self.themeGroup.layout().addWidget(self.themeCombo)

    def get_settings(self):
        conf = {'Layout': {}, 'Theme': {}}

        if self.startupDialogCheck.isChecked():
            conf['Layout']['default'] = 'NoDefault'
        else:
            conf['Layout']['default'] = self.layoutCombo.currentText()

        conf['Theme']['theme'] = self.themeCombo.currentText()
        styles.apply_style(self.themeCombo.currentText())

        return conf

    def load_settings(self, settings):
        if 'default' in settings['Layout']:
            if settings['Layout']['default'].lower() == 'nodefault':
                self.startupDialogCheck.setChecked(True)
                self.layoutCombo.setEnabled(False)
            else:
                self.layoutCombo.setCurrentText(settings['Layout']['default'])
        if 'theme' in settings['Theme']:
            self.themeCombo.setCurrentText(settings['Theme']['theme'])
Пример #3
0
class General(SettingsSection):

    NAME = 'General'

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

        # Startup layout
        self.layoutGroup = QGroupBox(self)
        self.layoutGroup.setTitle('Startup layout')
        self.layoutGroup.setLayout(QVBoxLayout())
        self.layoutGroup.setGeometry(0, 0, self.width(), 120)

        self.startupDialogCheck = QCheckBox(self.layoutGroup)
        self.startupDialogCheck.setText('Use startup dialog')
        self.layoutGroup.layout().addWidget(self.startupDialogCheck)

        self.layoutCombo = QComboBox(self.layoutGroup)
        self.layoutCombo.addItems([lay.NAME for lay in layouts.get_layouts()])
        self.layoutGroup.layout().addWidget(self.layoutCombo)

        self.startupDialogCheck.clicked.connect(
            lambda check: self.layoutCombo.setEnabled(not check))

        # Application style
        self.themeGroup = QGroupBox(self)
        self.themeGroup.setTitle('Application theme')
        self.themeGroup.setLayout(QVBoxLayout())
        self.themeGroup.setGeometry(0, 125, self.width(), 80)

        self.themeCombo = QComboBox(self.themeGroup)
        self.themeCombo.addItems(styles.get_styles())
        self.themeGroup.layout().addWidget(self.themeCombo)

    def get_configuration(self):
        conf = {'Layout': {}, 'Theme': {}}

        if self.startupDialogCheck.isChecked():
            conf['Layout']['default'] = 'NoDefault'
        else:
            conf['Layout']['default'] = self.layoutCombo.currentText()

        conf['Theme']['current'] = self.themeCombo.currentText()
        styles.apply_style(self.themeCombo.currentText())

        return conf

    def set_configuration(self, conf):
        if 'default' in conf['Layout']:
            if conf['Layout']['default'].lower() == 'nodefault':
                self.startupDialogCheck.setChecked(True)
                self.layoutCombo.setEnabled(False)
            else:
                self.layoutCombo.setCurrentText(conf['Layout']['default'])
        if 'current' in conf['Theme']:
            self.themeCombo.setCurrentText(conf['Theme']['current'])
Пример #4
0
class AreaOperation(QWidget):
    
    # - add objects to an area
    # - remove objects from an area
    
    @update_paths
    def __init__(self, mode, obj, AS=set(), controller=None):
        super().__init__()
        
        title = 'Add to area' if mode == 'add' else 'Remove from area'
        self.setWindowTitle(title)

        values = tuple(map(str, AS))
        
        # list of existing AS
        self.AS_list = QComboBox()
        self.AS_list.addItems(values)
        self.AS_list.activated.connect(self.update_value)
        
        # list of areas
        self.area_list = QComboBox()
        self.update_value()
        
        # confirmation button
        button_area_operation = QPushButton()
        button_area_operation.setText('OK')
        button_area_operation.clicked.connect(lambda: self.area_operation(mode, *obj))
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(self.AS_list, 0, 0, 1, 2)
        layout.addWidget(self.area_list, 1, 0, 1, 2)
        layout.addWidget(button_area_operation, 2, 0, 1, 1)
        layout.addWidget(cancel_button, 2, 1, 1, 1)
        self.setLayout(layout)
        
    def update_value(self, index):
        self.area_list.clear()
        selected_AS = self.network.AS_factory(name=self.AS_list.currentText())
        self.area_list.addItems(tuple(map(str, selected_AS.areas)))
        
    def area_operation(self, mode, *objects):
        selected_AS = self.network.AS_factory(name=self.AS_list.currentText())
        selected_area = self.area_list.currentText()

        if mode == 'add':
            selected_AS.management.add_to_area(selected_area, *objects)
        else:
            selected_AS.management.remove_from_area(selected_area, *objects)
            
        self.close()
Пример #5
0
class GestionEleve(QWidget):
    def __init__(self,parent=None):
        super(GestionEleve,self).__init__(parent)
        
        #charge la classe en cour
        self.initClass()

        palette = QPalette()
        palette.setColor(QPalette.Text,QColor(128,128,128))    

        self.leNom = QLineEdit(self)
        self.leNom.setText("NOM..")
        self.leNom.setPalette(palette)
        
        self.lePrenom = QLineEdit(self)
        self.lePrenom.setText("PRENOM..")
        self.lePrenom.setPalette(palette)
        
        self.comboSex = QComboBox(self)
        self.comboSex.addItem("sexe..")
        self.comboSex.addItem("M")
        self.comboSex.addItem("F")
        
        self.comboClasse =  self.initComboClasse(["CE1","CE2"])
        
        self.buttonSave = QPushButton("Save")
        self.buttonSave.clicked.connect(self.saveEleve)

        layout = QHBoxLayout()
        layout.addStretch()
        layout.addWidget(self.leNom)
        layout.addWidget(self.lePrenom)
        layout.addWidget(self.comboSex)
        layout.addWidget(self.comboClasse)
        layout.addWidget(self.buttonSave)
        layout.addStretch()
        self.setLayout(layout)
    
    def initComboClasse(self,list):
        res = QComboBox()
        res.addItem("classe..")
        for elt in list:
            res.addItem(elt)
        return res
        
    def saveEleve(self):
        if (self.leNom.text == "NOM.."
            or self.lePrenom.text == "PRENOM.."
            or str(self.comboSex.currentText()) == "sexe.."
            or str(self.comboClasse.currentText()) == "classe.."
        ):
            pass
            #on enregistre pas
        else :
            pass
            #on enregistre
            
        
    def initClass(self):
        pass
Пример #6
0
class CueItemWidget(QWidget):
    def __init__(self, target, action, cue_dialog, **kwargs):
        super().__init__(**kwargs)

        self.target = target
        self.cue_dialog = cue_dialog

        self.setLayout(QHBoxLayout(self))
        self.layout().setContentsMargins(2, 1, 2, 1)

        self.selectButton = QPushButton(self)
        self.selectButton.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.selectButton.setText(target.name)
        self.selectButton.setToolTip(target.name)
        self.selectButton.clicked.connect(self.select_target)
        self.layout().addWidget(self.selectButton)

        self.targetActionsCombo = QComboBox(self)
        self.targetActionsCombo.addItems([a.name for a in CueAction])
        self.targetActionsCombo.setCurrentText(CueAction[action].name)
        self.layout().addWidget(self.targetActionsCombo)

        self.layout().setStretch(0, 3)
        self.layout().setStretch(1, 1)

    def get_target(self):
        return self.target.id, self.targetActionsCombo.currentText()

    def select_target(self):
        if self.cue_dialog.exec_() == QDialog.Accepted:
            self.target = self.cue_dialog.selected_cues()[0]
            self.selectButton.setText(self.target.name)
            self.selectButton.setToolTip(self.target.name)
Пример #7
0
class ModeSelectionToolbar(QToolBar):
    switch_mode = pyqtSignal(str)

    def __init__(self, network_handler):
        super().__init__("Mode selection")

        self._nh = network_handler

        mode_text = QLabel()
        mode_text.setText("Select mode:")

        self._mode_selection = QComboBox()
        self._mode_selection.setMinimumWidth(100)
        self._mode_selection.setMaximumWidth(140)
        self._mode_selection.addItem("RC")
        self._mode_selection.addItem("GPS")

        self.addWidget(mode_text)
        self.addWidget(self._mode_selection)

        self.addAction("Select", self._send_mode)

    @QtCore.pyqtSlot()
    def _send_mode(self):
        mode = self._mode_selection.currentText()
        self.switch_mode.emit(mode)

        if mode == "RC":
            command = "START_PROG_RC"
        elif mode == "GPS":
            command = "START_PROG_GPS"
        else:
            command = "START_PROG_RC"

        self._nh.send_command(command)
Пример #8
0
class PropertyChanger(QWidget):
                                 
    @update_paths
    def __init__(self, objects, type, controller):
        super().__init__()
        
        # list of properties
        self.property_list = QComboBox()
        self.property_list.addItems(map(str, object_properties[type]))
                            
        self.value_edit = QLineEdit()

        confirmation_button = QPushButton()
        confirmation_button.setText('OK')
        confirmation_button.clicked.connect(lambda: self.confirm(objects))
                                       
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(self.property_list, 0, 0)
        layout.addWidget(self.value_edit, 1, 0)
        layout.addWidget(confirmation_button, 2, 0)
        self.setLayout(layout)
        
    def confirm(self, objects):
        selected_property = pretty_name_to_class[self.property_list.currentText()]
        str_value = self.value_edit.text()
        value = self.network.objectizer(selected_property.name, str_value)
        for object in objects:
            setattr(object, selected_property.name, value)
        self.close()
Пример #9
0
class AlsaSinkSettings(SettingsSection):

    NAME = "ALSA Sink"
    ELEMENT = AlsaSink

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

        self.id = Id
        self.devs = self._discover_pcm_devices()
        self.devs['default'] = 'default'

        self.group = QGroupBox(self)
        self.group.setTitle('ALSA device')
        self.group.setGeometry(0, 0, self.width(), 100)
        self.group.setLayout(QHBoxLayout())

        self.device = QComboBox(self.group)
        self.device.addItems(self.devs.keys())
        self.device.setCurrentText('default')
        self.device.setToolTip('ALSA device, as defined in an asound '
                               'configuration file')
        self.group.layout().addWidget(self.device)

        self.label = QLabel('ALSA device', self.group)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.group.layout().addWidget(self.label)

    def sizeHint(self):
        return QSize(450, 100)

    def enable_check(self, enable):
        self.group.setCheckable(enable)
        self.group.setChecked(False)

    def set_configuration(self, conf):
        if self.id in conf:
            device = conf[self.id].get('device', 'default')
            for name in self.devs:
                if device == self.devs[name]:
                    self.device.setCurrentText(name)
                    break

    def get_configuration(self):
        if not (self.group.isCheckable() and not self.group.isChecked()):
            return {self.id: {'device': self.devs[self.device.currentText()]}}
        else:
            return {}

    def _discover_pcm_devices(self):
        devices = {}

        with open('/proc/asound/pcm', mode='r') as f:
            for dev in f.readlines():
                dev_name = dev[7:dev.find(':', 7)].strip()
                dev_code = 'hw:' + dev[:5].replace('-', ',')
                devices[dev_name] = dev_code

        return devices
Пример #10
0
class TriggerWidget(QWidget):

    def __init__(self, tr_action, target, ta_action, cue_dialog, **kwargs):
        super().__init__(**kwargs)

        self.target = target
        self.cue_dialog = cue_dialog
        self.target_actions = {a.name: a.value for a in target.CueActions}

        self.setLayout(QHBoxLayout(self))
        self.layout().setContentsMargins(2, 1, 2, 1)

        self.triggerActions = QComboBox(self)
        # MediaTriggers members names and values are equals
        self.triggerActions.addItems([a.value for a in CueTriggers])
        self.triggerActions.setCurrentText(tr_action)
        self.layout().addWidget(self.triggerActions)

        self.selectButton = QPushButton(self)
        self.selectButton.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        self.selectButton.setText(target.name)
        self.selectButton.setToolTip(target.name)
        self.selectButton.clicked.connect(self.select_target)
        self.layout().addWidget(self.selectButton)

        self.targetActionCombo = QComboBox(self)
        self.targetActionCombo.addItems(self.target_actions.keys())
        self.targetActionCombo.setCurrentText(CueAction(ta_action).name)
        self.layout().addWidget(self.targetActionCombo)

        self.layout().setStretch(0, 1)
        self.layout().setStretch(1, 3)
        self.layout().setStretch(2, 1)

    def get_trigger(self):
        target = self.target.id
        tr_action = self.triggerActions.currentText()
        ta_action = self.target_actions[self.targetActionCombo.currentText()]

        return tr_action, target, ta_action

    def select_target(self):
        if self.cue_dialog.exec_() == QDialog.Accepted:
            self.target = self.cue_dialog.selected_cues()[0]
            self.selectButton.setText(self.target.name)
            self.selectButton.setToolTip(self.target.name)
class Subplot(QHBoxLayout):
    def __init__(self, customize, id, name):
        QHBoxLayout.__init__(self)

        self.customize = customize
        self.checkbox = QCheckBox(name)

        self.id = id

        self.checkbox.setCheckState(0)
        self.checkbox.stateChanged.connect(self.handleChecking)

        self.comscale = QComboBox()
        self.comscale.addItems(['linear', 'log'])
        self.comscale.currentIndexChanged.connect(self.updateScale)

        self.addWidget(self.checkbox)
        self.addWidget(self.comscale)

    @property
    def customAxes(self):
        return self.customize.customAxes

    @property
    def scale(self):
        return self.comscale.currentText()

    @property
    def graph(self):
        return self.customize.plotWindow.graph

    def handleChecking(self):

        if self.checkbox.isChecked():
            self.customAxes.append(self)
        else:
            self.customAxes.remove(self)

        self.customize.plotWindow.createGraph(self.customAxes)
        self.customize.checkAvailable()

    def updateScale(self):
        try:
            self.graph.updateScale(self.graph.allAxes[self.id], self.comscale.currentText())
        except Exception as e:
            print(e)
Пример #12
0
class ASOperation(QWidget):
    
    # - add objects to an AS
    # - remove objects from an AS
    # - enter the AS management window
    
    @update_paths
    def __init__(self, mode, obj, AS=set(), controller=None):
        super().__init__()
        
        title = {
        'add': 'Add to AS',
        'remove': 'Remove from AS',
        'manage': 'Manage AS'
        }[mode]
        
        self.setWindowTitle(title)
        
        if mode == 'add':
            # all AS are proposed 
            values = tuple(map(str, self.network.pnAS))
        else:
            # only the common AS among all selected objects
            values = tuple(map(str, AS))
        
        # list of existing AS
        self.AS_list = QComboBox()
        self.AS_list.addItems(values)
        
        # confirmation button
        button_AS_operation = QPushButton()
        button_AS_operation.setText('OK')
        button_AS_operation.clicked.connect(lambda: self.as_operation(mode, *obj))
        
        # cancel button
        cancel_button = QPushButton()
        cancel_button.setText('Cancel')
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(self.AS_list, 0, 0, 1, 2)
        layout.addWidget(button_AS_operation, 1, 0, 1, 1)
        layout.addWidget(cancel_button, 1, 1, 1, 1)
        self.setLayout(layout)
        
    def as_operation(self, mode, *objects):
        selected_AS = self.network.AS_factory(name=self.AS_list.currentText())

        if mode == 'add':
            selected_AS.management.add_to_AS(*objects)
        elif mode == 'remove':
            selected_AS.management.remove_from_AS(*objects)
        else:
            selected_AS.management.show()
            
        self.close()
            
Пример #13
0
class DisjointSPWindow(QWidget):
    
    algorithms = (
    'Constrained A*', 
    'Bhandari algorithm', 
    'Suurbale algorithm', 
    'Linear programming'
    )
    
    def __init__(self, controller):
        super().__init__()
        self.controller = controller
        self.setWindowTitle('Disjoint shortest paths algorithms')
        
        algorithm = QLabel('Algorithm')        
        self.dsp_list = QComboBox()
        self.dsp_list.addItems(self.algorithms)

        source = QLabel('Source')
        self.source_edit = QLineEdit()
        
        destination = QLabel('Destination')
        self.destination_edit = QLineEdit()
        
        number_of_paths = QLabel('Number of paths')
        self.number_of_paths_edit = QLineEdit()
                
        # confirmation button
        button_compute = QPushButton()
        button_compute.setText('Compute')
        button_compute.clicked.connect(self.compute_dsp)
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(algorithm, 0, 0, 1, 1)
        layout.addWidget(self.dsp_list, 0, 1, 1, 1)
        layout.addWidget(source, 1, 0, 1, 1)
        layout.addWidget(self.source_edit, 1, 1, 1, 1)
        layout.addWidget(destination, 2, 0, 1, 1)
        layout.addWidget(self.destination_edit, 2, 1, 1, 1)
        layout.addWidget(number_of_paths, 3, 0, 1, 1)
        layout.addWidget(self.number_of_paths_edit, 3, 1, 1, 1)
        layout.addWidget(button_compute, 4, 0, 1, 2)
        self.setLayout(layout)
        
    @update_paths
    def compute_dsp(self, _):
        source = self.network.nf(name=self.source_edit.text())
        destination = self.network.nf(name=self.destination_edit.text())
        algorithm = {
                    'Constrained A*': self.network.A_star_shortest_pair,
                    'Bhandari algorithm': self.network.bhandari,
                    'Suurbale algorithm': self.network.suurbale,
                    'Linear programming': lambda: 'to repair'
                    }[self.dsp_list.currentText()]
        nodes, physical_links = algorithm(source, destination)
        self.view.select(*(nodes + physical_links))
Пример #14
0
class JackSinkSettings(SettingsSection):

    NAME = "Jack Sink"
    ELEMENT = JackSink

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

        self.id = Id

        self.group = QGroupBox(self)
        self.group.setTitle('Jack')
        self.group.setGeometry(0, 0, self.width(), 100)
        self.group.setLayout(QGridLayout())

        self.client = QLineEdit(self.group)
        self.client.setToolTip('The client name of the Jack instance')
        self.client.setText('Linux Show Player')
        self.group.layout().addWidget(self.client, 0, 0)

        self.clientLabel = QLabel('Client name', self.group)
        self.clientLabel.setAlignment(QtCore.Qt.AlignCenter)
        self.group.layout().addWidget(self.clientLabel, 0, 1)

        self.connection = QComboBox(self.group)
        self.connection.setToolTip('Specify how the output ports will be'
                                   'connected')
        self.connection.addItems([JackSink.CONNECT_NONE,
                                  JackSink.CONNECT_AUTO,
                                  JackSink.CONNECT_AUTO_FORCED])
        self.connection.setCurrentIndex(1)
        self.group.layout().addWidget(self.connection, 1, 0)

        self.connLabel = QLabel('Connection mode', self.group)
        self.connLabel.setAlignment(QtCore.Qt.AlignCenter)
        self.group.layout().addWidget(self.connLabel, 1, 1)

    def sizeHint(self):
        return QSize(450, 100)

    def enable_check(self, enable):
        self.group.setCheckable(enable)
        self.group.setChecked(False)

    def set_configuration(self, conf):
        if self.id in conf:
            if 'client-name' in conf[self.id]:
                self.client.setText(conf[self.id]['client-name'])
            if 'connection' in conf[self.id]:
                self.connection.setCurrentText(conf[self.id]['connection'])

    def get_configuration(self):
        if not (self.group.isCheckable() and not self.group.isChecked()):
            return {self.id: {'client-name': self.client.text(),
                              'connection': self.connection.currentText()}}
        else:
            return {}
Пример #15
0
class StartSession(preferences.Group):
    def __init__(self, page):
        super(StartSession, self).__init__(page)
        
        grid = QGridLayout()
        self.setLayout(grid)
        
        def changed():
            self.changed.emit()
            self.combo.setEnabled(self.custom.isChecked())
        
        self.none = QRadioButton(toggled=changed)
        self.lastused = QRadioButton(toggled=changed)
        self.custom = QRadioButton(toggled=changed)
        self.combo = QComboBox(currentIndexChanged=changed)
        
        grid.addWidget(self.none, 0, 0, 1, 2)
        grid.addWidget(self.lastused, 1, 0, 1, 2)
        grid.addWidget(self.custom, 2, 0, 1, 1)
        grid.addWidget(self.combo, 2, 1, 1, 1)

        app.translateUI(self)
        
    def translateUI(self):
        self.setTitle(_("Session to load if Frescobaldi is started without arguments"))
        self.none.setText(_("Start with no session"))
        self.lastused.setText(_("Start with last used session"))
        self.custom.setText(_("Start with session:"))
        
    def loadSettings(self):
        s = QSettings()
        s.beginGroup("session")
        startup = s.value("startup", "none", str)
        if startup ==  "lastused":
            self.lastused.setChecked(True)
        elif startup == "custom":
            self.custom.setChecked(True)
        else:
            self.none.setChecked(True)
        sessionNames = sessions.sessionNames()
        self.combo.clear()
        self.combo.addItems(sessionNames)
        custom = s.value("custom", "", str)
        if custom in sessionNames:
            self.combo.setCurrentIndex(sessionNames.index(custom))

    def saveSettings(self):
        s = QSettings()
        s.beginGroup("session")
        s.setValue("custom", self.combo.currentText())
        if self.custom.isChecked():
            startup = "custom"
        elif self.lastused.isChecked():
            startup = "lastused"
        else:
            startup = "none"
        s.setValue("startup", startup)
Пример #16
0
class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        config = configparser.ConfigParser()
        config.read('launcher.original.ini')
        Login = config.get('Options', 'Logins')
        addlogins = Login.split(",")

        self.lbl = QLabel("Logins", self)
        self.combo = QComboBox(self)
        self.combo.addItems(addlogins)

        self.combo.move(50, 50)
        self.lbl.move(50, 30)

        btn = QPushButton('Set', self)
        btn.setGeometry(230, 50, 42, 32)
        btn.clicked.connect(self.buttonSet)

        self.resize(350, 140)
        self.center()
        self.setWindowTitle('Message box')
        self.show()

        self.setWindowTitle('Launcher')
        self.show()

    def buttonSet(self):
        config = configparser.ConfigParser()
        config.read('launcher.ini')
        config.set('Options', 'Autologin', self.combo.currentText())
        with open('launcher.ini', 'w') as configfile:
            config.write(configfile)

    def center(self):

        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def closeEvent(self, event):

        reply = QMessageBox.question(self, 'Message',
                                     "Are you sure to quit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
Пример #17
0
class DeleteForm(QDialog):
    def __init__(self):
        super(DeleteForm, self).__init__()
        self.initUI(self)

    def initUI(self, DeleteForm):
        layout = QGridLayout(self)

        self.delete_label = QLabel("Delete by:")
        self.delete_combo_box = QComboBox()
        self.delete_combo_box.addItem("ISBN")
        self.delete_combo_box.addItem("Title")
        self.delete_line_edit = QLineEdit()
        self.delete_button = QPushButton("Delete")

        layout.addWidget(self.delete_label, 0, 0)
        layout.addWidget(self.delete_combo_box, 0, 1)
        layout.addWidget(self.delete_line_edit, 0, 2)
        layout.addWidget(self.delete_button, 0, 3, 1, 2)

        self.setLayout(layout)
        self.delete_button.clicked.connect(self.delete_button_click)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle("Delete Book")
        self.setWindowIcon(QIcon(QPixmap('../images/delete.png')))

    def delete_button_click(self):
        search = self.delete_combo_box.currentText()
        text = self.delete_line_edit.text()
        if search == 'ISBN':
            if not(Validations.is_valid_isbn(text)):
                QMessageBox(QMessageBox.Critical, "Error",
                            "Invalid ISBN. Please correct it!").exec_()
            books = select_by_isbn(text)
            if books != []:
                delete_by_isbn(text)
                QMessageBox(QMessageBox.Information, "Information",
                            "You successfully deleted this book!").exec_()
                return
            else:
                QMessageBox(QMessageBox.Information, "No results",
                            "There is NO such book in the library!").exec_()
                return
        elif search == 'Title':
            books = select_by_title(string.capwords(text))
            if books != []:
                delete_by_title(string.capwords(text))
                QMessageBox(QMessageBox.Information, "Information",
                            "You successfully deleted this book!").exec_()
                return
            else:
                QMessageBox(QMessageBox.Information, "No results",
                            "There is NO such book in the library!").exec_()
                return
Пример #18
0
class RequestDialog(QDialog):
    """
    The dialog used to add and edit requests.
    """
    def __init__(self, parent=None):
        super(RequestDialog, self).__init__(parent)
        self.parent = parent

        self.set_up_window()
        self.set_up_request_dialog()

    def set_up_window(self):
        self.resize(200, 150)

        center_x = self.parent.x() + (self.parent.frameGeometry().width() - self.frameGeometry().width()) / 2
        center_y = self.parent.y() + (self.parent.frameGeometry().height() - self.frameGeometry().height()) / 2

        self.move(center_x, center_y)

        font = QFont()
        font.setPointSize(10)
        self.setFont(font)

    def set_up_request_dialog(self):
        keyword_label = QLabel("Keyword ")
        self.keyword_edit = QLineEdit()

        subreddit_label = QLabel("Subreddit ")
        self.subreddit_edit = QLineEdit()

        listing_label = QLabel("Listing")
        self.listing_combo_box = QComboBox()
        self.listing_combo_box.addItems(["Hot", "New", "Rising", "Controversial", "Top"])

        info_layout = QFormLayout()
        info_layout.addRow(keyword_label, self.keyword_edit)
        info_layout.addRow(subreddit_label, self.subreddit_edit)
        info_layout.addRow(listing_label, self.listing_combo_box)

        add_button = QPushButton("Add")
        add_button.setMaximumWidth(100)
        add_button.clicked.connect(self.accept)

        add_button_layout = QHBoxLayout()
        add_button_layout.addWidget(add_button)

        dialog_layout = QVBoxLayout()
        dialog_layout.addLayout(info_layout)
        dialog_layout.addLayout(add_button_layout)

        self.setLayout(dialog_layout)

    def values(self):
        return self.keyword_edit.text(), self.subreddit_edit.text(), self.listing_combo_box.currentText()
Пример #19
0
class LilyPondPreferences(QGroupBox):
    def __init__(self, parent):
        super(LilyPondPreferences, self).__init__(parent)

        grid = QGridLayout()
        self.setLayout(grid)

        self.pitchLanguageLabel = QLabel()
        self.pitchLanguage = QComboBox()
        self.versionLabel = QLabel()
        self.version = QComboBox(editable=True)

        self.pitchLanguage.addItem('')
        self.pitchLanguage.addItems([lang.title() for lang in sorted(scoreproperties.keyNames)])
        self.version.addItem(lilypondinfo.preferred().versionString())
        for v in ("2.18.0", "2.16.0", "2.14.0", "2.12.0"):
            if v != lilypondinfo.preferred().versionString():
                self.version.addItem(v)

        grid.addWidget(self.pitchLanguageLabel, 0, 0)
        grid.addWidget(self.pitchLanguage, 0, 1)
        grid.addWidget(self.versionLabel, 1, 0)
        grid.addWidget(self.version, 1, 1)

        self.pitchLanguage.activated.connect(self.slotPitchLanguageChanged)
        app.translateUI(self)
        self.loadSettings()
        self.window().finished.connect(self.saveSettings)

    def translateUI(self):
        self.setTitle(_("LilyPond"))
        self.pitchLanguageLabel.setText(_("Pitch name language:"))
        self.pitchLanguage.setToolTip(_(
            "The LilyPond language you want to use for the pitch names."))
        self.pitchLanguage.setItemText(0, _("Default"))
        self.versionLabel.setText(_("Version:"))
        self.version.setToolTip(_(
            "The LilyPond version you will be using for this document."))

    def slotPitchLanguageChanged(self, index):
        if index == 0:
            language = ''
        else:
            language = self.pitchLanguage.currentText().lower()
        self.window().setPitchLanguage(language)

    def loadSettings(self):
        language = self.window().pitchLanguage()
        languages = list(sorted(scoreproperties.keyNames))
        index = languages.index(language) + 1 if language in languages else 0
        self.pitchLanguage.setCurrentIndex(index)

    def saveSettings(self):
        QSettings().setValue('scorewiz/lilypond/pitch_language', self.window().pitchLanguage())
Пример #20
0
class MCFlowWindow(QWidget):
    
    algorithms = ('Linear programming', 'Klein')
    
    def __init__(self, controller):
        super().__init__()
        self.controller = controller
        self.setWindowTitle('Minimum-cost flow algorithms')
        
        algorithm = QLabel('Algorithm')        
        self.mcf_list = QComboBox()
        self.mcf_list.addItems(self.algorithms)

        source = QLabel('Source')
        self.source_edit = QLineEdit()
        
        destination = QLabel('Destination')
        self.destination_edit = QLineEdit()
        
        flow = QLabel('Flow')
        self.flow_edit = QLineEdit()
                
        # confirmation button
        button_compute = QPushButton()
        button_compute.setText('Compute')
        button_compute.clicked.connect(self.compute_mcflow)
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(algorithm, 0, 0, 1, 1)
        layout.addWidget(self.mcf_list, 0, 1, 1, 1)
        layout.addWidget(source, 1, 0, 1, 1)
        layout.addWidget(self.source_edit, 1, 1, 1, 1)
        layout.addWidget(destination, 2, 0, 1, 1)
        layout.addWidget(self.destination_edit, 2, 1, 1, 1)
        layout.addWidget(flow, 3, 0, 1, 1)
        layout.addWidget(self.flow_edit, 3, 1, 1, 1)
        layout.addWidget(button_compute, 4, 0, 1, 2)
        self.setLayout(layout)
        
    @update_paths
    def compute_mcflow(self, _):
        source = self.network.nf(name=self.source_edit.text())
        destination = self.network.nf(name=self.destination_edit.text())
        flow = self.flow_entry.text
        algorithm = {
                    'Linear programming': self.network.LP_MCF_formulation,
                    'Klein': lambda: 'to be implemented'
                    }[self.mcf_list.currentText()]
        cost = algorithm(source, destination, flow)   
        print(cost)
        
Пример #21
0
class MaximumFlowWindow(QWidget):
    
    algorithms = (
    'Ford-Fulkerson',
    'Edmond-Karps', 
    'Dinic', 
    'Linear programming'
    )
    
    def __init__(self, controller):
        super().__init__()
        self.controller = controller
        self.setWindowTitle('Maximum flow algorithms')
        
        algorithm = QLabel('Algorithm')        
        self.mf_list = QComboBox()
        self.mf_list.addItems(self.algorithms)

        source = QLabel('Source')
        self.source_edit = QLineEdit()
        
        destination = QLabel('Destination')
        self.destination_edit = QLineEdit()
                
        # confirmation button
        button_compute = QPushButton()
        button_compute.setText('Compute')
        button_compute.clicked.connect(self.compute_flow)
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(algorithm, 0, 0, 1, 1)
        layout.addWidget(self.mf_list, 0, 1, 1, 1)
        layout.addWidget(source, 1, 0, 1, 1)
        layout.addWidget(self.source_edit, 1, 1, 1, 1)
        layout.addWidget(destination, 2, 0, 1, 1)
        layout.addWidget(self.destination_edit, 2, 1, 1, 1)
        layout.addWidget(button_compute, 3, 0, 1, 2)
        self.setLayout(layout)
        
    @update_paths
    def compute_flow(self, _):
        source = self.network.nf(name=self.source_edit.text())
        destination = self.network.nf(name=self.destination_edit.text())
        algorithm = {
                    'Ford-Fulkerson': self.network.ford_fulkerson,
                    'Edmond-Karps': self.network.edmonds_karp,
                    'Dinic': self.network.dinic,
                    'Linear programming': self.network.LP_MF_formulation
                    }[self.mf_list.currentText()]
        maximum_flow = algorithm(source, destination)   
        print(maximum_flow)
Пример #22
0
class ShortestPathWindow(QWidget):
    
    algorithms = (
    'Constrained A*',
    'Bellman-Ford algorithm', 
    'Floyd-Warshall algorithm',
    'Linear programming'
    )
    
    def __init__(self, controller):
        super().__init__()
        self.controller = controller
        self.setWindowTitle('Shortest path algorithms')
        
        algorithm = QLabel('Algorithm')        
        self.sp_list = QComboBox()
        self.sp_list.addItems(self.algorithms)

        source = QLabel('Source')
        self.source_edit = QLineEdit()
        
        destination = QLabel('Destination')
        self.destination_edit = QLineEdit()
                
        # confirmation button
        button_compute = QPushButton()
        button_compute.setText('Compute')
        button_compute.clicked.connect(self.compute_sp)
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(algorithm, 0, 0, 1, 1)
        layout.addWidget(self.sp_list, 0, 1, 1, 1)
        layout.addWidget(source, 1, 0, 1, 1)
        layout.addWidget(self.source_edit, 1, 1, 1, 1)
        layout.addWidget(destination, 2, 0, 1, 1)
        layout.addWidget(self.destination_edit, 2, 1, 1, 1)
        layout.addWidget(button_compute, 3, 0, 1, 2)
        self.setLayout(layout)
        
    @update_paths
    def compute_sp(self, _):
        source = self.network.nf(name=self.source_edit.text())
        destination = self.network.nf(name=self.destination_edit.text())
        algorithm = {
                    'Constrained A*': self.network.A_star,
                    'Bellman-Ford algorithm': self.network.bellman_ford,
                    'Floyd-Warshall algorithm': self.network.floyd_warshall,
                    'Linear programming': self.network.LP_SP_formulation
                    }[self.sp_list.currentText()]
        nodes, physical_links = algorithm(source, destination)
        self.view.select(*(nodes + physical_links))
Пример #23
0
    def update_annotation(self, child: QTreeWidgetItem, cbox: QComboBox):
        """
        On getting a change signal from the parameter option combobox, set options on the volume.annotations object
        Also set the selected row to active

        Parameters
        ----------
        child: is the node in the QTreeWidget that corresponds to our paramter option selection
        cbox: Qt combobox that was clicked
        row: The row of the qtreewidget where the combobox is

        """
        vol = self.controller.current_annotation_volume()
        if not vol:
            error_dialog(self, "Error", "No volume selected")
            return
        try:
            x = int(self.ui.labelXPos.text())
            y = int(self.ui.labelYPos.text())
            z = int(self.ui.labelZPos.text())
        except ValueError:
            x = y = z = None

        base_node = child
        term = base_node.text(1)

        option = cbox.currentText()

        # If we are updating the annotation to ImageOnly, we should wipe any coordinates that may have been added to
        # a previous annotation option.
        if option == 'imageOnly':
            x = y = z = None

        elif option in (centre_stage_options.opts['options_requiring_points']):
            if None in (x, y, z):
                info_dialog(self, 'Select a region!',
                                   "For option '{}' coordinates must be specified".format(option))
                # this will reset the option back to what it is on the volume.annotation object
                cbox.setCurrentIndex(cbox.findText(vol.annotations.get_by_term(term).selected_option))
                return

        if not term:
            error_dialog(self, "Error", "No term is selected!")
            return

        vol.annotations.update_annotation(term, x, y, z, option)
        self.on_tree_clicked(base_node)

        # We are now autosaving. so save on each annotation term changed
        self.save_annotations(suppress_msg=True)
class ComboBoxDelegate(QStyledItemDelegate):

    typeSelected = pyqtSignal(str)

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

    def createEditor(self, parent, option=None, index=None):
        self.comboBox = QComboBox(parent)
        self.comboBox.currentIndexChanged.connect(self.currentIndexChanged)
        return self.comboBox

    def setEditorData(self, editor, index):
        self.comboBox = editor
        editor.blockSignals(True)
        cboIndex = -1
        if not index.model().data(index) is None:
            for i in range(editor.count()):
                if editor.itemText(i) == index.model().data(index):
                    cboIndex = i
                    break
        editor.setCurrentIndex(cboIndex)    
        editor.blockSignals(False)



    def setModelData(self, editor, model, index):
        self.comboBox = editor
        model.setData(index, self.comboBox.currentText()) #, QtGui.Qt.EditRole)

    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)


    def currentIndexChanged(self):
        self.commitData.emit(self.sender())
        self.typeSelected.emit(self.comboBox.currentText())
Пример #25
0
class tb_lasers(QWidget):

	def update(self):
		self.sim_mode.clear()
		lines=[]

		files=inp_lsdir()
		if files!=False:
			for i in range(0,len(files)):
				if files[i].endswith(".inp"):
					inp_load_file(lines,files[i])
					value=inp_search_token_value(lines, "#laser_name")
					if value!=False:
						value=value.rstrip()
						self.sim_mode.addItem(value)

			token=inp_get_token_value(self.config_file, "#pump_laser")

			all_items  = [self.sim_mode.itemText(i) for i in range(self.sim_mode.count())]

			for i in range(0,len(all_items)):
				if all_items[i] == token:
					self.sim_mode.setCurrentIndex(i)
					found=True


	def __init__(self,config_file):
		self.config_file=config_file
		QWidget.__init__(self)
		layout=QHBoxLayout()
		label=QLabel()
		label.setText(_("Laser:"))
		layout.addWidget(label)

		self.sim_mode = QComboBox(self)
		self.sim_mode.setEditable(True)
		self.update()

		self.sim_mode.currentIndexChanged.connect(self.call_back_sim_mode_changed)

		layout.addWidget(self.sim_mode)

		self.setLayout(layout)

		return

	def call_back_sim_mode_changed(self):
		mode=self.sim_mode.currentText()
		inp_update_token_value(self.config_file, "#pump_laser", mode,1)
Пример #26
0
class TZprompt(QDialog):
    def __init__(self, parent=None):
        super(TZprompt, self).__init__(parent)

        #self.idDates = QCheckBox("Import ID and created/modified dates")

        promptLabel = QLabel("Time Zone in which the Tellico data was entered:")

        self.zoneName = QComboBox(self)
        current = -1
        self.suppliedTZ = 'America/Chicago'
        for i, zone in enumerate (pytz.common_timezones):
            self.zoneName.addItem(zone, i)
            if self.suppliedTZ == zone:
                current = i
        self.zoneName.setCurrentIndex(current)

        self.submitButton = QPushButton("Submit")
        self.submitButton.isDefault()


        buttonLayout1 = QVBoxLayout()
        #buttonLayout1.addWidget(self.idDates)
        buttonLayout1.addWidget(promptLabel)
        buttonLayout1.addWidget(self.zoneName)
        buttonLayout1.addWidget(self.submitButton)

        self.submitButton.clicked.connect(self.TZsubmitted)

        mainLayout = QGridLayout()
        mainLayout.addLayout(buttonLayout1, 0, 1)

        self.setLayout(mainLayout)
        self.setWindowTitle("Time Zone")

    def TZsubmitted(self):
        self.suppliedTZ = self.zoneName.currentText()
        QDialog.accept(self)

    @staticmethod
    def getTZ(parent = None):
        TZdialog = TZprompt(parent)
        result = TZdialog.exec_()

        if result == QDialog.Accepted:
            return TZdialog.suppliedTZ

        return 'UTC'
Пример #27
0
    def loadUser(self,elem:QComboBox):
        user = elem.currentText()
        userdata = user.split()
        if len(userdata) > 2:
            last = userdata[-1]
            userdata = [" ".join(userdata[:-1]), last]

        user = QueryTool().queryByNames(userdata[0], userdata[1])

        print(user)
        self.sportlerID.setText("{}".format(user[0]))
        self.sportlerName.setEditText(user[1])
        self.sportlerVName.setEditText(user[2])
        self.sportlerAlter.setCurrentIndex(user[3]-2)
        self.sportlerGeschlecht.setCurrentIndex(int(bool(user[4]))+1)
        self.sportlerAusDatenbank = True
Пример #28
0
class tb_pulse_load_type(QWidget):

	changed = pyqtSignal()

	def __init__(self,index):
		self.index=index

		QWidget.__init__(self)


		layout=QHBoxLayout()
		label=QLabel()
		label.setText(_("Load type:"))
		layout.addWidget(label)

		self.sim_mode = QComboBox(self)
		self.sim_mode.setEditable(True)


		layout.addWidget(self.sim_mode)

		self.setLayout(layout)

		self.sim_mode.addItem("open_circuit")
		self.sim_mode.addItem("load")
		self.sim_mode.addItem("ideal_diode_ideal_load")


		lines=[]
		inp_load_file(lines,os.path.join(get_inp_file_path(),"pulse"+str(self.index)+".inp"))

		token=inp_get_token_value("pulse"+str(self.index)+".inp", "#pulse_sim_mode")

		all_items  = [self.sim_mode.itemText(i) for i in range(self.sim_mode.count())]
		for i in range(0,len(all_items)):
		    if all_items[i] == token:
		        self.sim_mode.setCurrentIndex(i)

		self.sim_mode.currentIndexChanged.connect(self.call_back_sim_mode_changed)


	def call_back_sim_mode_changed(self):
		mode=self.sim_mode.currentText()
		inp_update_token_value("pulse"+str(self.index)+".inp", "#pulse_sim_mode", mode,1)
		self.changed.emit()
Пример #29
0
    def createDateTimeEdits(self):
        self.editsGroup = QGroupBox("Date and time spin boxes")

        dateLabel = QLabel()
        dateEdit = QDateEdit(QDate.currentDate())
        dateEdit.setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31))
        dateLabel.setText("Appointment date (between %s and %s):" %
                    (dateEdit.minimumDate().toString(Qt.ISODate),
                    dateEdit.maximumDate().toString(Qt.ISODate)))

        timeLabel = QLabel()
        timeEdit = QTimeEdit(QTime.currentTime())
        timeEdit.setTimeRange(QTime(9, 0, 0, 0), QTime(16, 30, 0, 0))
        timeLabel.setText("Appointment time (between %s and %s):" %
                    (timeEdit.minimumTime().toString(Qt.ISODate),
                    timeEdit.maximumTime().toString(Qt.ISODate)))

        self.meetingLabel = QLabel()
        self.meetingEdit = QDateTimeEdit(QDateTime.currentDateTime())

        formatLabel = QLabel("Format string for the meeting date and time:")

        formatComboBox = QComboBox()
        formatComboBox.addItem('yyyy-MM-dd hh:mm:ss (zzz \'ms\')')
        formatComboBox.addItem('hh:mm:ss MM/dd/yyyy')
        formatComboBox.addItem('hh:mm:ss dd/MM/yyyy')
        formatComboBox.addItem('hh:mm:ss')
        formatComboBox.addItem('hh:mm ap')

        formatComboBox.activated[str].connect(self.setFormatString)

        self.setFormatString(formatComboBox.currentText())

        editsLayout = QVBoxLayout()
        editsLayout.addWidget(dateLabel)
        editsLayout.addWidget(dateEdit)
        editsLayout.addWidget(timeLabel)
        editsLayout.addWidget(timeEdit)
        editsLayout.addWidget(self.meetingLabel)
        editsLayout.addWidget(self.meetingEdit)
        editsLayout.addWidget(formatLabel)
        editsLayout.addWidget(formatComboBox)
        self.editsGroup.setLayout(editsLayout)
Пример #30
0
    def CreateInputGroup(self):
        #QCombobox used to pick the csv file to be read
        #initialises the signal and slot mechanism used to change data.values
        csvComboBox = QComboBox()
        csvComboBox.insertPolicy = csvComboBox.InsertAlphabetically
        csvComboBox.addItems(DiscoverCSV())
        csvComboBox.currentIndexChanged[str].connect(
            lambda v: self.UpdateDateRange(self.GetDateRangeCSV(v), startBox,
                                           endBox))
        csvComboBox.currentIndexChanged[str].connect(
            ApplicationData.csvFile.fset.__get__(data))
        data.csvFile = csvComboBox.currentText()

        #QDateEdit used to interact and change the starting and ending dates
        startBox = QDateEdit()
        startBox.dateChanged.connect(
            ApplicationData.startDate.fset.__get__(data))
        data.startDate = startBox.date()

        startLabel = QLabel("&Start")
        startLabel.setBuddy(startBox)

        endBox = QDateEdit()
        endBox.dateChanged.connect(ApplicationData.endDate.fset.__get__(data))
        data.endDate = endBox.date()

        endLabel = QLabel("&End")
        endLabel.setBuddy(endBox)

        #initialises the begging and ending dates
        self.UpdateDateRange(self.GetDateRangeCSV(data.csvFile), startBox,
                             endBox)

        #QLineEdit used to interact and change the money used to trade
        amountBox = QLineEdit()
        amountBox.textEdited.connect(ApplicationData.amount.fset.__get__(data))

        amountLabel = QLabel("&Amount")
        amountLabel.setBuddy(amountBox)

        runButton = QPushButton("&Run")
        runButton.clicked.connect(self.graph.getPlotItem().clear)
        runButton.clicked.connect(
            lambda: ApplicationData.plotData.fset.__get__(data)({}))
        runButton.clicked.connect(lambda: self.StandardGraph(self, data))
        runButton.clicked.connect(lambda: self.SMAGraph(self, data))
        runButton.clicked.connect(lambda: self.buySellScatter(data))

        #the QGridLayout used to manager the positioning of above widgets
        layout = QGridLayout()

        layout.addWidget(csvComboBox, 0, 0, 1, 4)
        layout.addWidget(startLabel, 1, 0)
        layout.addWidget(startBox, 1, 1)
        layout.addWidget(endLabel, 1, 2)
        layout.addWidget(endBox, 1, 3)
        layout.addWidget(amountLabel, 2, 0)
        layout.addWidget(amountBox, 2, 1)
        layout.addWidget(runButton, 2, 3)

        return layout
Пример #31
0
class ColorPaletteDock(QDockWidget):
    """Dock containing the color palette and preview area

    :param source:  Subject source for the dock and its contents, either
                    sprite or tile
    :type source:   Source
    :param parent:  Parent widget, defaults to None
    :type parent:   QWidget, optional
    """

    palette_updated = pyqtSignal(str)

    def __init__(self, source, parent=None):
        super().__init__("Color Palettes", parent)
        self.source = source
        self.setFloating(False)
        self.setFeatures(
            QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable
        )
        self.docked_widget = QWidget(self)
        self.setWidget(self.docked_widget)
        self.docked_widget.setLayout(QVBoxLayout())
        self.docked_widget.setSizePolicy(
            QSizePolicy.Maximum, QSizePolicy.Maximum
        )
        self.color_palette = ColorPalette(self.source, self)
        self.color_palette_list = QComboBox()
        self.color_palette_list.setSizePolicy(
            QSizePolicy.Minimum, QSizePolicy.Maximum
        )
        self.palette_picker = QHBoxLayout()
        self.palette_label = QLabel("Palette:")
        self.palette_label.setSizePolicy(
            QSizePolicy.Maximum, QSizePolicy.Maximum
        )
        self.palette_picker.addWidget(self.palette_label)
        self.palette_picker.addWidget(self.color_palette_list)
        self.add_palette = QToolButton(self)
        self.add_palette.mousePressEvent = self.addPaletteReq
        self.add_palette.setToolTip("Add new palette")
        add_icon = QIcon()
        add_icon.addPixmap(QPixmap(":/icons/add.png"))
        self.add_palette.setIcon(add_icon)
        self.add_palette.setEnabled(False)
        self.remove_palette = QToolButton(self)
        self.remove_palette.mousePressEvent = self.removePaletteReq
        self.remove_palette.setToolTip("Remove current palette")
        remove_icon = QIcon()
        remove_icon.addPixmap(QPixmap(":/icons/remove.png"))
        self.remove_palette.setIcon(remove_icon)
        self.remove_palette.setEnabled(False)
        self.rename_palette = QToolButton(self)
        self.rename_palette.mousePressEvent = self.renamePaletteReq
        self.rename_palette.setToolTip("Rename current palette")
        rename_icon = QIcon()
        rename_icon.addPixmap(QPixmap(":/icons/rename.png"))
        self.rename_palette.setIcon(rename_icon)
        self.rename_palette.setEnabled(False)
        self.palette_picker.addWidget(self.add_palette)
        self.palette_picker.addWidget(self.remove_palette)
        self.palette_picker.addWidget(self.rename_palette)
        self.docked_widget.layout().addLayout(self.palette_picker)
        self.docked_widget.layout().addWidget(self.color_palette)
        self.color_palette_list.setEnabled(False)
        self.color_palette.setEnabled(False)
        self.color_palette.palette_updated.connect(self.verifyCurrentPalette)

    def setup(self, data):
        """Sets up the data source for the dock's contents and enables UI elements

        :param data:    Data source of dock
        :type data:     GameData
        """
        self.data = data
        self.data.col_pal_renamed.connect(self.renamePalette)
        self.data.col_pal_added.connect(self.addPalette)
        self.data.col_pal_removed.connect(self.removePalette)
        self.color_palette.setup(self.data)
        self.color_palette_list.currentIndexChanged.connect(
            self.setColorPalette
        )
        self.color_palette_list.setEnabled(True)
        self.color_palette.setEnabled(True)
        self.add_palette.setEnabled(True)
        self.remove_palette.setEnabled(True)
        self.rename_palette.setEnabled(True)
        for name in self.data.getColPalNames(self.source):
            self.color_palette_list.addItem(name)

    def addPaletteReq(self, event=None):
        """Sends command to GameData source to add a color palette

        :param event:   Mouse click event which triggered the request,
                        defaults to None
        :type event:    QMouseEvent, optional
        """
        name, accepted = QInputDialog.getText(
            self, "Add", "Palette name:", QLineEdit.Normal, "New palette"
        )
        if accepted:
            self.data.addColPal(name, self.source)

    def removePaletteReq(self, event=None):
        """Sends command to GameData source to remove a color palette

        :param event:   Mouse click event which triggered the request,
                        defaults to None
        :type event:    QMouseEvent, optional
        """
        if self.color_palette_list.count() == 1:
            QMessageBox(
                QMessageBox.Critical,
                "Error",
                "There must be at least one sprite and tile color palette in \
                the project",
            ).exec()
        else:
            name = self.color_palette_list.currentText()
            self.data.remColPal(name, self.source)

    def renamePaletteReq(self, event=None):
        """Sends command to GameData source to rename a color palette

        :param event:   Mouse click event which triggered the request,
                        defaults to None
        :type event:    QMouseEvent, optional
        """
        cur_name = self.color_palette_list.currentText()
        new_name, accepted = QInputDialog.getText(
            self, "Rename", "Palette name:", QLineEdit.Normal, cur_name
        )
        if accepted:
            self.data.setColPalName(cur_name, new_name, self.source)

    @pyqtSlot(Source, str, int)
    def addPalette(self, source, name, index):
        """Adds a new color palette

        :param source:  Subject source of the addition, either sprite or tile
        :type source:   Source
        :param name:    Name of the added color palette
        :type name:     str
        :param index:   Index in color palette list to insert the new palette
        :type index:    int
        """
        if source is not self.source:
            return
        if name is not None:
            self.color_palette_list.insertItem(index, name)
            self.color_palette_list.setCurrentIndex(index)
            self.color_palette.current_palette = name
        else:
            QMessageBox(
                QMessageBox.Critical,
                "Error",
                "Palette with that name already exists",
            ).exec()
            self.addPaletteReq()

    @pyqtSlot(Source, str)
    def removePalette(self, source, name):
        """Removes a color palette

        :param source:  Subject source of the removal, either sprite or tile
        :type source:   Source
        :param name:    Name of the removed color palette
        :type name:     str
        """
        if source is not self.source:
            return
        if name is not None:
            index = self.color_palette_list.findText(name)
            self.color_palette_list.removeItem(index)
            name = self.color_palette_list.currentText()
            self.color_palette.current_palette = name
        else:
            QMessageBox(
                QMessageBox.Critical,
                "Error",
                "Unable to remove palette {}".format(name),
            ).exec()

    @pyqtSlot(Source, str, str)
    def renamePalette(self, source, cur_name, new_name):
        """Renames a color palette

        :param source:      Subject source of the removal, either sprite or
                            tile
        :type source:       Source
        :param cur_name:    Current name of the target color palette
        :type cur_name:     str
        :param new_name:    New name of the target color palette
        :type new_name:     str
        """
        if source is not self.source:
            return
        if cur_name != new_name:
            self.color_palette_list.setItemText(
                self.color_palette_list.findText(cur_name), new_name
            )
            self.color_palette_list.setCurrentIndex(
                self.color_palette_list.findText(new_name)
            )
            self.color_palette.current_palette = new_name
        else:
            QMessageBox(
                QMessageBox.Critical,
                "Error",
                "Palette with that name already exists",
            ).exec()
            self.renamePaletteReq()

    @pyqtSlot(str)
    def verifyCurrentPalette(self, name):
        """Ensures that the current color palette in the selection list is accurate

        :param name:    Name of the selected color palette
        :type name:     str
        """
        self.color_palette_list.setCurrentIndex(
            self.color_palette_list.findText(name)
        )
        self.palette_updated.emit(name)

    def setColorPalette(self):
        """Sets the active color palette to the one chosen in the selection list
        """
        self.color_palette.setPalette(
            self.source, self.color_palette_list.currentText()
        )

    def closeEvent(self, event):
        """Intercepts the dock close event to prevent its closure

        :param event:   Source event
        :type event:    QEvent
        """
        event.ignore()
Пример #32
0
class Ui_Class(QWidget):
    click_btn_sig = pyqtSignal(bool)

    def __init__(self):
        super().__init__()
        self.dg_clicked_flg = True  #这个标识是:勾选手动输城市时,第一次点弹出下拉框,第二次点确认信息;
        self.usr_define_city = False
        self.usr_def_flag_ret = False
        self.cid_list = []
        self.city_name_list = []
        self.city = QLabel("当前城市", self)
        self.time = QLabel("当前时间", self)
        self.weath = QLabel("当前天气", self)
        self.weath_1 = QLabel("明天天气", self)
        self.weath_2 = QLabel("后天天气", self)
        self.city_line = QLineEdit(self)
        self.time_line = QLineEdit(self)
        self.weat_line = QLineEdit(self)
        self.weat_line_1 = QLineEdit(self)
        self.weat_line_2 = QLineEdit(self)

        self.manu_check = QCheckBox("手动输入城市名称", self)
        self.usr_city_line = QLineEdit(self)
        self.usr_confirm_btn = QPushButton("确定", self)

        #系统托盘实例
        self.trayIcon = QSystemTrayIcon(self)
        self.trayIcon.setIcon(QIcon('weather.ico'))
        self.trayIcon.activated.connect(self.ico_clicked)

        #托盘添加右键退出菜单
        self.quit_action = QAction("退出", self, triggered=self.tray_quit)
        self.traymenu = QMenu(self)
        self.traymenu.addAction(self.quit_action)
        self.trayIcon.setContextMenu(self.traymenu)

        self.tray_msg_flag = True

        self.init_ui()

    #重写关闭事件
    def closeEvent(self, e):
        sel = QMessageBox.question(self, "后台提示", "是否需要最小化到系统托盘",
                                   QMessageBox.Yes | QMessageBox.No,
                                   QMessageBox.Yes)
        if sel == QMessageBox.Yes:
            e.ignore()  #忽略关闭事件
            self.trayIcon.setVisible(True)
            self.hide()
        else:
            self.trayIcon.setVisible(False)
            e.accept()  #响应关闭事件

    def tray_quit(self):
        self.trayIcon.setVisible(False)
        qApp.quit()

    #托盘上的图标被左键单击或者双击时的响应函数
    def ico_clicked(self, reason):
        if (reason == QSystemTrayIcon.Trigger
                or reason == QSystemTrayIcon.DoubleClick):
            if self.isVisible():
                self.hide()
            else:
                self.show()

    def init_ui(self):
        ui_font = QFont("宋体", 12)
        self.setFont(ui_font)
        self.resize(480, 320)
        self.setWindowTitle("简易天气")

        #将窗体部署到屏幕中间
        screen_size = QDesktopWidget().screenGeometry()
        app_ui_size = self.geometry()
        self.move((screen_size.width() - app_ui_size.width()) / 2,
                  (screen_size.height() - app_ui_size.height()) / 2)

        #设置lineedit不可编辑
        self.city_line.setDisabled(True)
        self.time_line.setDisabled(True)
        self.weat_line.setDisabled(True)
        self.weat_line_1.setDisabled(True)
        self.weat_line_2.setDisabled(True)
        self.usr_city_line.setDisabled(True)
        self.usr_confirm_btn.setDisabled(False)

        #控件布局
        grid = QGridLayout()
        grid.setSpacing(2)
        grid.addWidget(self.manu_check, 0, 0)
        grid.addWidget(self.usr_city_line, 0, 1)
        grid.addWidget(self.usr_confirm_btn, 0, 2)
        grid.addWidget(self.city, 1, 0)
        grid.addWidget(self.city_line, 1, 1, 1, 2)
        grid.addWidget(self.time, 2, 0)
        grid.addWidget(self.time_line, 2, 1, 1, 2)
        grid.addWidget(self.weath, 3, 0)
        grid.addWidget(self.weat_line, 3, 1, 1, 2)
        grid.addWidget(self.weath_1, 4, 0)
        grid.addWidget(self.weat_line_1, 4, 1, 1, 2)
        grid.addWidget(self.weath_2, 5, 0)
        grid.addWidget(self.weat_line_2, 5, 1, 1, 2)

        #设置信号响应
        self.manu_check.toggled.connect(self.check_box_toggle)
        self.usr_confirm_btn.clicked.connect(self.confirm_btn_click)

        self.setLayout(grid)
        self.show()

    #更新 当前天气 信息
    def update_now_weather(self, str_info):
        self.weat_line.setText(str_info)

    #更新当前时间信息
    def update_time(self, str_info):
        self.time_line.setText(str_info)

    #更新 明天天气 信息
    def update_1_weather(self, str_info):
        self.weat_line_1.setText(str_info)

    #更新 后天天气 信息
    def update_2_weather(self, str_info):
        self.weat_line_2.setText(str_info)

    #设置 当前天气 字体颜色
    def set_now_weathercolor(self, str_color):
        self.weat_line.setStyleSheet("color:" + str_color)

    #更新当前城市信息
    def update_location(self, str_info):
        self.city_line.setText(str_info)

    #设置 label 内容,index为1表示明日天气, 为2表示后天天气
    def set_label(self, index, str):
        if index == 1:
            self.weath_1.setText(str)
        elif index == 2:
            self.weath_2.setText(str)
        else:
            pass

    #设置 明天或后天 天气字体颜色
    def set_otr_weathercolor(self, index, str_color):
        if index == 1:
            self.weat_line_1.setStyleSheet("color:" + str_color)
        else:
            self.weat_line_2.setStyleSheet("color:" + str_color)

    #手动输入城市名称checkbox响应
    def check_box_toggle(self, check_stat):
        if check_stat == True:  #checkBox被勾选
            self.usr_city_line.setDisabled(False)
            self.usr_confirm_btn.setDisabled(False)
            self.usr_define_city = True
        else:
            self.usr_city_line.setDisabled(True)
            self.usr_confirm_btn.setDisabled(True)
            self.usr_define_city = False

    #确定按钮响应函数
    def confirm_btn_click(self):
        #自动模式下点击 确定 按钮
        if self.usr_define_city == False:
            self.usr_def_flag_ret = False
            self.usr_confirm_btn.setDisabled(True)
            self.manu_check.setDisabled(True)
            self.click_btn_sig.emit(False)
        #手动模式下点击 确定 按钮
        else:
            self.usr_def_flag_ret = True
            if self.dg_clicked_flg == True:  #当前是第一次点击 确定 按钮
                self.city_name_list.clear()  #清空list,否则会在输入内容变化时,无法及时更新城市信息
                usr_def_city_str = self.usr_city_line.text()
                if len(usr_def_city_str) > 0:
                    url_str = SEARCH_CITY_URL + usr_def_city_str + USR_KEY + SEARCH_GROUP
                    rs_we = requests.get(url_str).json()
                    get_status = rs_we["HeWeather6"][0]["status"]
                    if get_status == "ok":
                        city_num = len(rs_we["HeWeather6"][0]["basic"])
                        city_str_index = 0
                        while (city_str_index < city_num):
                            self.city_name_list.append(
                                rs_we["HeWeather6"][0]["basic"][city_str_index]
                                ["admin_area"] + "-" + rs_we["HeWeather6"][0]
                                ["basic"][city_str_index]["parent_city"] +
                                "-" + rs_we["HeWeather6"][0]["basic"]
                                [city_str_index]["location"])
                            self.cid_list.append(
                                rs_we["HeWeather6"][0]["basic"][city_str_index]
                                ["cid"])
                            city_str_index = city_str_index + 1
                        self.showDialog(self.city_name_list)
                    else:
                        QMessageBox.warning(self, "错误", "无法获取城市信息!")
                else:
                    QMessageBox.warning(self, "错误", "用户未输入!")
            else:  #第二次点击
                self.usr_city_line.setDisabled(True)
                self.usr_confirm_btn.setDisabled(True)
                self.manu_check.setDisabled(True)
                self.click_btn_sig.emit(True)

    #托盘弹出气泡提示框,弹出频率由刷新天气频率确定
    def tray_msg_show(self, str_info):
        if len(str_info) > 5:  #确保是有效数据
            if self.tray_msg_flag == True:
                self.trayIcon.showMessage("简易天气提示", str_info,
                                          QSystemTrayIcon.Information, 2000)
                #self.tray_msg_flag = False  #保留功能
            else:
                pass
        else:
            pass

    def showDialog(self, city_list):
        vbox = QVBoxLayout()  #纵向布局
        hbox = QHBoxLayout()  #横向布局
        self.dialog = QDialog(self)
        self.dialog.resize(100, 60)
        self.okBtn = QPushButton("确定")
        self.cancelBtn = QPushButton("取消")
        self.okBtn.clicked.connect(self.click_diag_ok_btn)
        self.cancelBtn.clicked.connect(self.click_diag_cancel_btn)
        self.city_cmb = QComboBox(self)
        for ct in city_list:
            self.city_cmb.addItem(ct)

        self.dialog.setWindowTitle("城市选择")
        # 确定与取消按钮横向布局
        hbox.addWidget(self.okBtn)
        hbox.addWidget(self.cancelBtn)

        vbox.addWidget(self.city_cmb)
        vbox.addLayout(hbox)
        self.dialog.setLayout(vbox)

        self.dialog.setWindowModality(
            Qt.ApplicationModal)  #该模式下,只有该dialog关闭,才可以关闭父界面
        self.dialog.exec_()

    # 弹出的对话框里的确认按钮
    def click_diag_ok_btn(self):
        select_txt = self.city_cmb.currentText()
        self.usr_city_line.setText(select_txt)
        self.dialog.close()
        self.dg_clicked_flg = False

    # 弹出的对话框里的取消按钮
    def click_diag_cancel_btn(self):
        self.dialog.close()

    #根据城市名称获取城市id
    def get_cid(self):
        ret = 0
        index = 0
        usr_cit = self.usr_city_line.text()
        for i in self.city_name_list:
            if usr_cit == i:
                ret = index
                break
            else:
                index = index + 1
        return self.cid_list[ret]

    def get_usr_define_flg(self):
        return self.usr_define_city

    #返回False表示使用自动获取,返回True表示用户自定义
    def get_flag(self):
        return self.usr_def_flag_ret
Пример #33
0
class DocView(QMainWindow):
    #resized = QtCore.pyqtSignal()
    def __init__(self):
        super(DocView, self).__init__()
        #
        self.step = 0
        self.combos = {
        }  # project member and other project-related people selection
        #
        self.lastpath = 'c:\\'
        self.filename = None
        self.isfinished = True
        self.isselected = False
        #
        self.filepath_in = None
        self.filepath_extract = None
        self.filepath_out = None
        #
        self.sections = None
        self.project_type = '水利'
        #
        self.address_dic = {}
        self.selected = 0
        #
        self.setting_info = {}
        #
        self.initUI()

    ####################################################################
    ############################UI#####################################
    ####################################################################
    def createAct(self):
        ###########################
        # create act
        ###########################
        self.openAct = QAction(QIcon('icons\\open.png'), '打开', self)
        self.openAct.setShortcut('Ctrl+O')
        self.openAct.setStatusTip('Open Document')
        self.openAct.triggered.connect(self.act_open)
        ## exit
        self.exitAct = QAction(QIcon('icons\\close_.png'), '终了', self)
        self.exitAct.setShortcut('Ctrl+Q')
        self.exitAct.setStatusTip('Exit application')
        self.exitAct.triggered.connect(self.close)
        ## exit
        self.saveAct = QAction(QIcon('icons\\save.png'), '保存', self)
        self.saveAct.setShortcut('Ctrl+S')
        self.saveAct.setStatusTip('Save Document')
        self.saveAct.triggered.connect(self.act_save)
        ## select
        self.selectAct = QAction(QIcon('icons\\select.png'), '选择', self)
        self.selectAct.setShortcut('Ctrl+E')
        self.selectAct.setStatusTip('Select Project Member')
        self.selectAct.triggered.connect(self.act_select)
        ## delete
        self.deleteAct = QAction(QIcon('icons\\delete.png'), '选择', self)
        self.deleteAct.setShortcut('Ctrl+D')
        self.deleteAct.setStatusTip('Delete Document')
        self.deleteAct.triggered.connect(self.act_delete)
        ## extract
        self.extractAct = QAction(QIcon('icons\\extract.png'), '提取', self)
        self.extractAct.setShortcut(QKeySequence('Ctrl+Shit+E'))
        self.extractAct.setStatusTip('Extract Format Pages')
        self.extractAct.triggered.connect(self.act_extract)
        ## split
        self.splitAct = QAction(QIcon('icons\\split.png'), '分离', self)
        self.splitAct.setShortcut('Ctrl+Shit+S')
        self.splitAct.setStatusTip('Split Document')
        self.splitAct.triggered.connect(self.act_split)
        ## fill
        self.fillAct = QAction(QIcon('icons\\fillin.png'), '填写', self)
        self.fillAct.setShortcut('Ctrl+Shit+F')
        self.fillAct.setStatusTip('Fill in Blank')
        self.fillAct.triggered.connect(self.act_fillin)
        ## auto
        self.autoAct = QAction(QIcon('icons\\auto.png'), '完全自动', self)
        self.autoAct.setShortcut('Ctrl+Shit+A')
        self.autoAct.setStatusTip('Do Automatically')
        self.autoAct.triggered.connect(self.act_auto)
        ## merge
        self.mergeAct = QAction(QIcon('icons\\merge.png'), '合并', self)
        self.mergeAct.setShortcut('Ctrl+Shit+M')
        self.mergeAct.setStatusTip('Merge Documents')
        self.mergeAct.triggered.connect(self.act_merge)
        ## check
        self.todocxAct = QAction(QIcon('icons\\doc.png'), '检查', self)
        self.todocxAct.setShortcut('Ctrl+Shit+')
        self.todocxAct.setStatusTip('Check Document')
        self.todocxAct.triggered.connect(self.act_2docx)
        ## 2xml
        self.toxmlAct = QAction(QIcon('icons\\xml.png'), '变换到XML', self)
        self.toxmlAct.setShortcut('Ctrl+Shit+X')
        self.toxmlAct.setStatusTip('Convert Docx to Xml')
        self.toxmlAct.triggered.connect(self.act_2xml)
        ## 2html
        self.tohtmlAct = QAction(QIcon('icons\\html.png'), '变换到HTML', self)
        self.tohtmlAct.setShortcut('Ctrl+Shit+H')
        self.tohtmlAct.setStatusTip('Convert docx to HTML')
        self.tohtmlAct.triggered.connect(self.act_2html)
        ## setting
        self.settingAct = QAction(QIcon('icons\\setting_.png'), '设置', self)
        self.settingAct.setShortcut('Ctrl+Shit+T')
        self.settingAct.setStatusTip('Setting')
        self.settingAct.triggered.connect(self.act_setting)
        ## help
        self.aboutAct = QAction(QIcon('icons\\help.png'), '关于', self)
        self.aboutAct.setShortcut('Ctrl+H')
        self.aboutAct.setStatusTip('About Program')
        self.aboutAct.triggered.connect(self.act_about)

    def createMenu(self):
        ###########################
        # create menu
        ###########################
        self.menubar = self.menuBar()
        ## File
        fileMenu = self.menubar.addMenu('&文件')
        fileMenu.addAction(self.openAct)
        fileMenu.addAction(self.saveAct)
        fileMenu.addAction(self.exitAct)
        ## Edit
        editMenu = self.menubar.addMenu('&编辑')
        editMenu.addAction(self.selectAct)
        ## Act
        processMenu = self.menubar.addMenu('&执行')
        processMenu.addAction(self.extractAct)
        processMenu.addAction(self.splitAct)
        processMenu.addAction(self.fillAct)
        processMenu.addAction(self.autoAct)
        processMenu.addAction(self.mergeAct)
        ## Tool
        toolMenu = self.menubar.addMenu('&工具')
        toolMenu.addAction(self.todocxAct)
        toolMenu.addAction(self.toxmlAct)
        toolMenu.addAction(self.tohtmlAct)
        ## Setting
        settingMenu = self.menubar.addMenu('&设置')
        settingMenu.addAction(self.settingAct)
        ## Help
        helpMenu = self.menubar.addMenu('&帮助')
        helpMenu.addAction(self.aboutAct)

    def createToolbar(self):
        ###########################
        # create toolbar
        ###########################
        self.toolbar = self.addToolBar('File')
        self.toolbar.addAction(self.openAct)
        self.toolbar.addAction(self.saveAct)
        #self.toolbar.addAction(self.exitAct)
        #
        self.toolbar = self.addToolBar('Edit')
        self.toolbar.addAction(self.settingAct)
        self.toolbar.addAction(self.selectAct)
        #
        self.toolbar = self.addToolBar('Act')
        self.toolbar.addAction(self.extractAct)
        self.toolbar.addAction(self.splitAct)
        self.toolbar.addAction(self.fillAct)
        self.toolbar.addAction(self.autoAct)
        self.toolbar.addAction(self.mergeAct)
        #
        self.toolbar = self.addToolBar('Tool')
        self.toolbar.addAction(self.todocxAct)
        self.toolbar.addAction(self.toxmlAct)
        self.toolbar.addAction(self.tohtmlAct)
        #
        #self.toolbar = self.addToolBar('Setting')
        #self.toolbar.addAction(self.settingAct)
        #
        self.toolbar = self.addToolBar('Delete')
        self.toolbar.addAction(self.deleteAct)
        ####
        # create combobox
        self.toolbar = self.addToolBar('Select Target')
        self.combobox = QComboBox()
        self.combobox.currentIndexChanged.connect(self.selection_change)
        self.combobox.setMinimumWidth(150)
        self.combobox.setMinimumHeight(20)
        self.toolbar.addWidget(self.combobox)
        # create progress bar
        self.toolbar = self.addToolBar('Progress')

        self.progressBar = QProgressBar(self)
        self.progressBar.setEnabled(True)
        #width = self.frameGeometry().width()
        #height = self.frameGeometry().height()
        #self.progressBar.setGeometry(0, height-20, width-20, 20)
        self.progressBar.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        self.progressBar.setValue(self.step)
        #self.setCentralWidget(self.progressBar)
        self.timer = QtCore.QBasicTimer()
        self.timer.start(20, self)
        self.toolbar.addWidget(self.progressBar)

    def createDlgs(self):
        ###################################
        ##### select #######################
        ###################################
        self.dlg_select = QDialog(self)
        vbox = QVBoxLayout()
        vbox.addStretch(1)
        for position in []:  #POSITION:
            label = QLabel()
            label.setText(position)
            label.setMinimumWidth(80)
            combo = QComboBox()
            print(position)
            for case in switch(position):
                if case('法人'):
                    positions = ['项目经理']
                    break
                if case('联系人'):
                    positions = ['工程师']
                    break
                if case('委托人1'):
                    positions = ['项目经理', '工程师']
                    break
                if case('委托人2'):
                    positions = ['项目经理', '工程师']
                    break
                if case('技术负责人'):
                    positions = ['工程师']
                    break
                if case('财务负责人'):
                    positions = ['工程师']
                    break
                if case():
                    positions = [position]
                    break
            print(positions)
            from db_sqlite import get_name_list
            combo.addItems(
                get_name_list(positions)
            )  #db['human'].filtering_by_position(positions=positions))
            combo.setMinimumWidth(90)
            self.combos[position] = combo
            hbox = QHBoxLayout()
            hbox.addStretch(1)
            hbox.addWidget(label)
            hbox.addWidget(combo)
            vbox.addLayout(hbox)
        self.refresh_project_members()
        self.dlg_select.setLayout(vbox)
        self.dlg_select.setWindowTitle(r'选择项目有关人')
        self.dlg_select.setWindowIcon(QIcon('icons\\select.png'))
        ######################################
        ### setting ##########################
        ######################################
        self.dlg_setting = QDialog(self)
        vbox = QVBoxLayout()
        vbox.addStretch(1)
        #####################################
        from db_sqlite import get_project_types
        label = QLabel()
        label.setText('项目类型')
        label.setMinimumWidth(80)
        combo = QComboBox()
        for ptype in get_project_types():
            combo.addItem(ptype)
        combo.setMinimumWidth(90)
        self.ptype_combo = combo
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(label)
        hbox.addWidget(self.ptype_combo)
        vbox.addLayout(hbox)
        ############################
        ############################
        self.setting_labels = []
        self.setting_buttons = []
        self.setting_edits = []
        self.setting_selected = 0
        for i, routine in enumerate(PATH):
            label = QLabel()
            label.setText(routine)
            label.setMinimumWidth(80)
            self.setting_labels.append(label)
            edit = QLineEdit()
            if routine in list(db.keys()):
                edit.setText(db[routine])
                self.setting_info[PATH[i]] = db[routine]
            edit.setMinimumWidth(200)
            self.setting_edits.append(edit)

            button = QPushButton()
            self.setting_buttons.append(button)
            self.setting_buttons[i].setText('选择')
            self.setting_buttons[i].toggle()
            self.setting_buttons[i].setAccessibleName(str(i))
            self.setting_buttons[i].released.connect(self.act_filebrowser)
            #self.connect(button,SIGNAL("clicked()"),self.act_filebrowser)
            #button.clicked.connect(lambda:self.act_filebrowser(button))
            #self.setting_buttons.append(button)
            #self.setting_buttons[i].clicked.connect(lambda:self.act_filebrowser(self.setting_buttons[i]))
            hbox = QHBoxLayout()
            hbox.addStretch(1)
            hbox.addWidget(label)
            hbox.addWidget(edit)
            hbox.addWidget(button)
            vbox.addLayout(hbox)
        self.dlg_setting.setLayout(vbox)
        self.dlg_setting.setWindowTitle(r'选择路径')
        self.dlg_setting.setWindowIcon(QIcon('icons\\setting_.png'))

    @staticmethod
    def createTextEdit():
        textEdit = QTextEdit()
        textEdit.setFont(QFont('宋体', 16))
        return textEdit

    @staticmethod
    def createWebView():
        webView = QWebView()
        webView.settings().setAttribute(QWebSettings.PluginsEnabled, True)
        #self.webView.settings().setAttribute(QWebSettings.WebAttribute.DeveloperExtrasEnabled, True)
        webView.settings().setAttribute(QWebSettings.PrivateBrowsingEnabled,
                                        True)
        webView.settings().setAttribute(
            QWebSettings.LocalContentCanAccessRemoteUrls, True)
        #self.webView.loadFinished.connect(self._loadfinished)
        #self.webView.setUrl(QtCore.QUrl("file:///G:/AutoMaking/src/Documentation/test.pdf"))
        #self.webView.load(QtCore.QUrl().fromLocalFile("G:\\AutoMaking\\src\\Documentation\\test.pdf"))
        #`self.webView.setHtml('<html><head></head><title></title><body></body></html>', baseUrl = QtCore.QUrl().fromLocalFile("G:\\AutoMaking\\src\\Documentation\\test.pdf"))
        #webView.setHtml(docx2html("G:\\AutoMaking\\src\\Documentation\\test.docx"))
        #self.webView.show()
        #self.webView.hide()
        #self.webView.setObjectName("webView")
        #QtCore.QTimer.singleShot(1200, self.webView.show)
        #self.webView.setContent()
        return webView

    def createViews(self):

        self.preView_L = DocView.createTextEdit()  #createWebView()
        self.preView_L.setObjectName('TextEdit_L')  #'WebView_L'
        self.preView_L.setAccessibleName('TextEdit_L')
        self.preView_R = DocView.createTextEdit()  #createWebView()
        self.preView_R.setObjectName('TextEdit_R')  #'WebView_R'
        self.preView_R.setAccessibleName('TextEdit_R')

        self.splitter = QSplitter(QtCore.Qt.Horizontal)
        self.splitter.setStretchFactor(1, 1)
        self.splitter.addWidget(self.preView_L)
        self.splitter.addWidget(self.preView_R)
        self.setCentralWidget(self.splitter)

    def initUI(self):
        # create act
        self.createAct()
        # create status bar
        self.statusBar()
        # create menu
        self.createMenu()
        # create toolbar
        self.createToolbar()
        # create dlgs
        self.createDlgs()
        # create central widgets
        self.createViews()

        # set size
        #self.setGeometry(300, 300, 350, 250)
        #self.resized.connect(self.act_resize)
        self.setMinimumSize(500, 350)
        self.showMaximized()
        self.setWindowTitle(r'标书自动生成')  # set title
        self.setWindowIcon(QIcon('icons\\document_.png'))  # set windowIcon
        self.show()
        ##
        #self.setMouseTracking(True)

    ####################################################################
    ##############################Signals################################
    ####################################################################
    '''
    def mousePressEvent(self, event):
        self.origin = event.pos()
        self.rubberband.setGeometry(
            QtCore.QRect(self.origin, QtCore.QSize()))
        self.rubberband.show()
        QtGui.QWidget.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if self.rubberband.isVisible():
            self.rubberband.setGeometry(
                QtCore.QRect(self.origin, event.pos()).normalized())
        QtGui.QWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        if self.rubberband.isVisible():
            self.rubberband.hide()
            selected = []
            rect = self.rubberband.geometry()
            for child in self.findChildren(QtGui.QPushButton):
                if rect.intersects(child.geometry()):
                    selected.append(child)
            print 'Selection Contains:\n ',
            if selected:
                print '  '.join(
                    'Button: %s\n' % child.text() for child in selected)
            else:
                print ' Nothing\n'
        QtGui.QWidget.mouseReleaseEvent(self, event)
    '''

    def resizeEvent(self, event):
        #self.resized.emit()
        '''
        width = self.frameGeometry().width()
        height = self.frameGeometry().height()
        print(width,height)
        self.progressBar.setGeometry(QtCore.QRect(0, height-20, width-20, 20))
        self.progressBar.setVisible(True)
        self.update()
        '''
        return super(DocView, self).resizeEvent(event)

    def timerEvent(self, e):

        if self.step >= 100:
            self.timer.stop()
            return

        self.step = self.step + 1
        self.progressBar.setValue(self.step)

    def keyPressEvent(self, event):
        #
        if event.key(
        ) == QtCore.Qt.Key_Escape:  # QtCore.Qt.Key_Escape is a value that equates to what the operating system passes to python from the keyboard when the escape key is pressed.
            self.close()

    def closeEvent(self, event):

        if self.isfinished:
            self.deleteLater()
            return

        reply = QMessageBox.question(self, '警示', "确定关闭?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.deleteLater()
            event.accept()
        else:
            event.ignore()

    def selection_change(self, i):
        '''
        print("Items in the list are :")
		
        for count in range(self.combobox.count()):
            print(self.combobox.itemText(count))
        print("Current index",i,"selection changed ",self.combobox.currentText())
        '''
        section_name = self.combobox.currentText()
        print(section_name)
        if '提取的文件' == section_name:
            inpath = self.filepath_extract
            outpath = None
        elif '原件' == section_name:
            inpath = self.filepath_in
            outpath = self.filepath_out
        else:
            inpath = os.path.join(self.split_dir, section_name + '.docx')
            outpath = os.path.join(self.processed_dir, section_name + '.docx')
        self.refresh_left_preview(inpath)
        self.refresh_right_preview(outpath)

    ####################################################################
    ##############################Actions################################
    ####################################################################
    '''
    def act_resize(self):
        width = self.frameGeometry().width()
        height = self.frameGeometry().height()
        self.progressBar.setGeometry(0, height-40, width-20, 20)
    '''

    def act_open(self):
        filepath, extensions = QFileDialog.getOpenFileName(
            self, r'打开招标文件', '', "Document files (*.docx *.doc *.wps *pdf)")
        print(filepath)
        if filepath is self.filepath_in:
            return
        if filepath is not '':
            self.lastpath, self.filename = os.path.split(filepath)
            filename, extension = os.path.splitext(filepath)
            self.filepath_in = filename + '.docx'
            self.filepath_extract = os.path.join(self.lastpath,
                                                 'extracted.docx')
            self.filepath_out = os.path.join(self.lastpath, 'out.docx')
            self.address_dic = {}
            if '.docx' in extension:
                self.combobox.clear()
                self.combobox.addItem('原件')
                return
            else:
                reply = QMessageBox.question(self, '警示', "变换文件扩展名?",
                                             QMessageBox.Yes | QMessageBox.No,
                                             QMessageBox.No)
                if reply == QMessageBox.No:
                    QMessageBox.warning(self, '警示', '文件扩展名需要被变换')
                    return
            self.combobox.clear()
            self.combobox.addItem('原件')
            # convert into docx file
            for case in switch(extension):
                if case('.doc'):
                    doc2docx(filepath)
                    break
                if case('.pdf'):
                    pdf2docx(filepath)
                    break
                if case(''):
                    break

    def act_select(self):
        self.dlg_select.show()
        self.refresh_project_members()
        from processing.xml2dict import dic2xml
        dic2xml(self.setting_info, os.path.join(os.getcwd(), 'db\\项目设置.xml'))
        from setting import set_xml_db
        set_xml_db()
        '''
        self.dlg_select.show()
        #
        self.refresh_project_members()
        #
        db['finance'].filtering(need_years=3)
        #db['human'].select_people(name_list=[db['project_members'][position] for position in POSITION])
        db['projects_done'].filtering(project_types=['水利'],need_years=3)
        db['projects_being'].filtering(project_types=['水利'])
        '''
        #

    def act_extract(self):
        if self.filepath_in is None or not os.path.exists(self.filepath_in):
            self.act_open()
        # initialize
        self.combobox.clear()
        self.combobox.addItem('原件')
        self.combobox.addItem(r'提取的文件')
        self.combobox.setCurrentIndex(1)
        #
        extract = Extract(self.filepath_in)
        extract.process(output_filepath=self.filepath_extract)
        #db['project_info'].set_db(extract.extract_project_infos())
        self.refresh_left_preview(self.filepath_extract)
        #self.isfinished = True
        #

    def act_split(self):
        mkdir(self.split_dir)
        split = Split(input_filepath=self.filepath_extract)
        self.sections = split.process(self.progressBar)
        self.combobox.addItems(self.sections)

    def act_fillin(self):
        self.refresh_project_members()
        #https://stackoverflow.com/questions/6415737/change-the-value-of-the-progress-bar-from-a-class-other-than-my-gui-class-pyqt4?rq=1
        section_name = self.combobox.currentText()
        #print(section_name)
        if any(key in section_name for key in ['提取的文件', '原件']):
            QMessageBox.about(self, '通知', '请先选择要填写的')
            return
        # set in and out path
        print(self.processed_dir)
        if not os.path.exists(self.processed_dir):
            os.mkdir(self.processed_dir)
        inpath = os.path.join(self.split_dir, section_name + '.docx')
        outpath = os.path.join(self.processed_dir, section_name + '.docx')
        # fillin
        if not os.path.exists(outpath):
            fillin = FillIn(inpath)
            fillin.process(outpath)
        # preview
        self.refresh_right_preview(outpath)

    def act_auto(self):
        self.refresh_project_members()
        self.progressBar.setValue(0)
        mkdir(self.processed_dir)
        count = len(self.sections)
        for index, section in enumerate(self.sections):
            fillin = FillIn(os.path.join(self.split_dir, section + '.docx'))
            fillin.process(os.path.join(self.processed_dir, section + '.docx'))
            self.progressBar.setValue(int((index + 1) * 100 / count))

    def act_merge(self):
        merge = Merge(tmpdir=self.processed_dir, section_names=self.sections)
        merge.process(self.filepath_out)
        opendocument(self.filepath_out)

    def act_delete(self):
        section_name = self.combobox.currentText()
        #print(section_name)
        if '原件' == section_name:
            filepath = self.filepath_out
        elif '提取的文件' == section_name:
            filepath = self.filepath_extract
        else:
            filepath = os.path.join(self.processed_dir, section_name + '.docx')

        if os.path.exists(filepath):
            os.remove(filepath)
            self.refresh_right_preview(filepath)

    def act_save(self):
        filepath, extensions = QFileDialog.getSaveFileName(
            self, r'保存投标文件', '', "Document files (*.docx)")
        if os.path.exists(filepath):
            os.rename(self.filepath_out, filepath)
        pass

    def act_2docx(self):
        section_name = self.combobox.currentText()
        #print(section_name)
        if '原件' == section_name:
            outpath = self.filepath_out
            inpath = self.filepath_in
        elif '提取的文件' == section_name:
            outpath = self.filepath_extract
            inpath = None
        else:
            outpath = os.path.join(self.processed_dir, section_name + '.docx')
            inpath = os.path.join(self.split_dir, section_name + '.docx')

        if os.path.exists(outpath):
            opendocument(outpath)
        elif outpath is not None and os.path.exists(inpath):
            opendocument(inpath)

    def act_2xml(self):
        section_name = self.combobox.currentText()
        if '原件' == section_name:
            inpath = self.filepath_in
        elif '提取的文件' == section_name:
            inpath = self.filepath_extract
        else:
            if os.path.exists(
                    os.path.join(self.processed_dir, section_name + '.docx')):
                inpath = os.path.join(self.processed_dir,
                                      section_name + '.docx')
            else:
                inpath = os.path.join(self.split_dir, section_name + '.docx')
        outpath = os.path.splitext(inpath)[0] + '.xml'
        if not os.path.exists(outpath):
            docx2xml(inpath)
        open_chrome(outpath)

    def act_2html(self):
        section_name = self.combobox.currentText()
        if '原件' == section_name:
            inpath = self.filepath_in
        elif '提取的文件' == section_name:
            inpath = self.filepath_extract
        else:
            if os.path.exists(
                    os.path.join(self.processed_dir, section_name + '.docx')):
                inpath = os.path.join(self.processed_dir,
                                      section_name + '.docx')
            else:
                inpath = os.path.join(self.split_dir, section_name + '.docx')
        outpath = os.path.splitext(inpath)[0] + '.html'
        if not os.path.exists(outpath):
            docx2html(inpath)
        open_chrome(outpath)

    def act_about(self):
        QMessageBox.about(self, '关于标书自动生成软件', '版本号:0.1.0\n生成时间:2017.11.28')

    def act_setting(self):
        self.dlg_setting.show()
        self.setting_info['项目类型'] = self.ptype_combo.currentText()
        from processing.xml2dict import dic2xml
        dic2xml(self.setting_info, os.path.join(os.getcwd(), 'db\\项目设置.xml'))
        from setting import set_xml_db
        set_xml_db()

    def act_filebrowser(self):  #,button):
        #print(selected)
        sending_button = self.sender()
        selected = int(
            sending_button.accessibleName()
        )  #int(button.accessibleName())#self.setting_buttons.index(button)#int(object.accessibleName())
        dir_path = str(
            QFileDialog.getExistingDirectory(self, PATH[selected])
        ) if '数据库' not in PATH[selected] else QFileDialog.getOpenFileName(
            self, PATH[selected], '', "sqlite database files (*.db)")[0]
        if dir_path is not None and dir_path is not '':
            print(dir_path)
            db[PATH[selected]] = dir_path
            self.setting_edits[selected].setText(dir_path)
            self.setting_info[PATH[selected]] = dir_path
        #print(dir_path)

    ####################################################################
    ##############################Methods################################
    ####################################################################
    def refresh_project_members(self):
        project_member_info = {}
        for position in POSITION:
            project_member_info[position] = self.combos[position].currentText()
        self.setting_info['项目组织机构'] = project_member_info
        '''
        for position in POSITION:
            db['project_members'][position] = self.combos[position].currentText()
        if len(db['project_members']) > 0:
            db['human'].select_people(name_list=[db['project_members'][position] for position in POSITION])
        #print(self.project_members)
        '''

    def _loadfinished(self, ok):
        #self.webView.load(QtCore.QUrl('about:blank'))
        pass

    def refresh_left_preview(self, filepath):
        if filepath and os.path.exists(filepath):
            #print(self.preView_L.accessibleName(),self.preView_L.objectName(),'here')
            if 'Edit' in self.preView_L.accessibleName():
                fulltext = docx2text(filepath)
                self.preView_L.setText(fulltext)
            else:
                self.preView_L.setHtml(docx2html(filepath))

    def refresh_right_preview(self, filepath):
        if filepath and os.path.exists(filepath):
            if 'Edit' in self.preView_R.accessibleName():
                fulltext = docx2text(filepath)
                self.preView_R.setText(fulltext)
            else:
                self.preView_R.setHtml(docx2html(filepath))
        else:
            if 'Edit' in self.preView_L.accessibleName():
                self.preView_R.setText('')
            else:
                self.preView_R.setHtml('')
Пример #34
0
class ProjectPropertiesDialog(QDialog):
    """
    The class which support the creation and management of the output. It is notably used to select the options to
    create the figures.

    """
    send_log = pyqtSignal(str, name='send_log')
    cut_mesh_partialy_dry_signal = pyqtSignal(
        bool, name='cut_mesh_partialy_dry_signal')  # to change suffix no_cut
    """
    A PyQtsignal used to write the log.
    """
    def __init__(self, path_prj, name_prj, name_icon):

        super().__init__()
        self.path_prj = path_prj
        self.name_prj = name_prj
        self.name_icon = name_icon
        self.is_modification = False
        # list with the available color map
        self.namecmap = [
            'coolwarm', 'jet', 'magma', 'viridis', 'inferno', 'plasma',
            'Blues', 'Greens', 'Greys', 'Oranges', 'Purples', 'Reds',
            'gist_earth', 'terrain', 'ocean'
        ]
        self.msg2 = QMessageBox()
        self.hvum = HydraulicVariableUnitManagement()
        self.init_iu()

    def init_iu(self):
        # insist on white background color (for linux, mac)
        self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.white)
        self.setPalette(p)
        """ WIDGETS """
        """ general widgets """
        # cut_2d_grid
        self.cut_2d_grid_label = QLabel(
            self.tr('Cut hydraulic mesh partialy wet'))
        self.cut_2d_grid_checkbox = QCheckBox(self.tr(''))

        # min_height
        min_height_label = QLabel(self.tr('2D minimum water height [m]'))
        self.min_height_lineedit = QLineEdit("")

        # erase_data
        self.erase_data_label = QLabel(self.tr('Erase file if exist'))
        self.erase_data_checkbox = QCheckBox(self.tr(''))
        """ outputs widgets """
        self.mesh_whole_profile_hyd = QCheckBox("")
        self.mesh_whole_profile_hyd.setObjectName("mesh_whole_profile_hyd")

        self.point_whole_profile_hyd = QCheckBox("")
        self.point_whole_profile_hyd.setObjectName("point_whole_profile_hyd")

        self.mesh_units_hyd = QCheckBox("")
        self.mesh_units_hyd.setObjectName("mesh_units_hyd")
        self.mesh_units_hab = QCheckBox("")
        self.mesh_units_hab.setObjectName("mesh_units_hab")

        self.point_units_hyd = QCheckBox("")
        self.point_units_hyd.setObjectName("point_units_hyd")
        self.point_units_hab = QCheckBox("")
        self.point_units_hab.setObjectName("point_units_hab")

        vertical_exaggeration = QLabel("3D vertical exaggeration")
        self.vertical_exaggeration_lineedit = QLineEdit()
        self.vertical_exaggeration_lineedit.setToolTip(
            self.tr("Exaggeration coefficient of z nodes values (all 3D)"))
        self.vertical_exaggeration_lineedit.setAlignment(Qt.AlignCenter)
        self.vertical_exaggeration_lineedit.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Maximum)
        self.vertical_exaggeration_lineedit.setFixedHeight(
            self.point_units_hyd.sizeHint().height())
        self.vertical_exaggeration_lineedit.setFixedWidth(75)

        self.elevation_whole_profile_hyd = QCheckBox("")
        self.elevation_whole_profile_hyd.setObjectName(
            "elevation_whole_profile_hyd")

        self.pvd_variable_z_combobox = QComboBox()
        self.pvd_variable_z_combobox.setToolTip(
            self.tr("Choose the variable to assign to the z nodes (3D)"))
        self.variables_units_hyd = QCheckBox("")
        self.variables_units_hab = QCheckBox("")
        self.variables_units_hyd.setObjectName("variables_units_hyd")
        self.variables_units_hab.setObjectName("variables_units_hab")

        self.mesh_detailled_text_hyd = QCheckBox("")
        self.mesh_detailled_text_hyd.setObjectName("mesh_detailled_text_hyd")
        self.point_detailled_text_hyd = QCheckBox("")
        self.point_detailled_text_hyd.setObjectName("point_detailled_text_hyd")

        self.mesh_detailled_text_hab = QCheckBox("")
        self.mesh_detailled_text_hab.setObjectName("mesh_detailled_text_hab")
        self.point_detailled_text_hab = QCheckBox("")
        self.point_detailled_text_hab.setObjectName("point_detailled_text_hab")

        self.fish_information_hab = QCheckBox("")
        self.fish_information_hab.setObjectName("fish_information_hab")

        self.output_checkbox_list = [
            self.mesh_whole_profile_hyd, self.point_whole_profile_hyd,
            self.mesh_units_hyd, self.mesh_units_hab, self.point_units_hyd,
            self.point_units_hab, self.elevation_whole_profile_hyd,
            self.variables_units_hyd, self.variables_units_hab,
            self.mesh_detailled_text_hyd, self.point_detailled_text_hyd,
            self.mesh_detailled_text_hab, self.point_detailled_text_hab,
            self.fish_information_hab
        ]

        self.checkbox_list_set = list(
            set([
                checkbox.objectName()[:-4]
                for checkbox in self.output_checkbox_list
            ]))
        """ figure widgets """
        # fig_size
        fig_size_label = QLabel(self.tr('Figure size (w,h) [cm]'), self)
        self.fig_size_lineedit = QLineEdit("")
        self.fig_size_lineedit.setToolTip(self.tr("width, height"))
        fig_size_label.setToolTip(self.tr("width, height"))

        # color_map
        color_map_label = QLabel(self.tr('Color map'), self)
        self.color_map_combobox = QComboBox()
        self.color_map_combobox.addItems(self.namecmap)

        # font_size
        font_size_label = QLabel(self.tr('Font size'), self)
        self.font_size_lineedit = QLineEdit("")

        # font_family
        font_family_label = QLabel(self.tr('Font family'), self)
        self.font_family_combobox = QComboBox()
        self.font_family_combobox.addItems(
            ["Arial", "Calibri", "Times New Roman", "Tahoma", "DejaVu Sans"])

        # line_width
        line_width_label = QLabel(self.tr('Line width'), self)
        self.line_width_lineedit = QLineEdit("")

        # grid
        grid_label = QLabel(self.tr('Grid'), self)
        self.grid_checkbox = QCheckBox("", self)

        # fig_forma
        fig_format_label = QLabel(self.tr('Figure format'))
        self.fig_format_combobox = QComboBox()
        self.fig_format_combobox.addItems(['.png', '.pdf'])

        # resolution
        resolution_label = QLabel(self.tr('Resolution [dpi]'))
        self.resolution_lineedit = QLineEdit("")

        # type_fishname
        type_fishname_label = QLabel(self.tr('Type of animal name'))
        self.type_fishname_combobox = QComboBox()
        self.type_fishname_combobox.addItems([
            self.tr('Latin Name'),
            self.tr('French Common Name'),
            self.tr('English Common Name'),
            self.tr('Code ONEMA')
        ])  # order matters here, add stuff at the end!

        # marquers_hab_fig
        marquers_hab_fig_label = QLabel(self.tr('Markers for habitat figures'))
        self.marquers_hab_fig_checkbox = QCheckBox(self.tr(''))

        # reset default
        self.reset_by_default_pref = QPushButton(self.tr('Reset by default'))
        self.reset_by_default_pref.clicked.connect(
            lambda: self.set_pref_gui_from_dict(default=True))

        # save
        self.save_pref_button = QPushButton(self.tr('OK'))
        self.save_pref_button.clicked.connect(self.save_preferences)

        # close
        self.close_pref_button = QPushButton(self.tr('Cancel'))
        self.close_pref_button.clicked.connect(self.close_preferences)
        """ LAYOUT """
        # general options
        layout_general_options = QFormLayout()
        general_options_group = QGroupBox(self.tr("General"))
        #general_options_group.setStyleSheet('QGroupBox {font-weight: bold;}')
        general_options_group.setLayout(layout_general_options)
        layout_general_options.addRow(self.cut_2d_grid_label,
                                      self.cut_2d_grid_checkbox)
        layout_general_options.addRow(min_height_label,
                                      self.min_height_lineedit)
        layout_general_options.addRow(
            self.erase_data_label, self.erase_data_checkbox)  # , Qt.AlignLeft

        # exports options
        self.layout_available_exports = QGridLayout()
        available_exports_group = QGroupBox(self.tr("Default exports"))
        self.doubleclick_check_uncheck_filter = DoubleClicOutputGroup()
        available_exports_group.installEventFilter(
            self.doubleclick_check_uncheck_filter)
        self.doubleclick_check_uncheck_filter.double_clic_signal.connect(
            self.check_uncheck_all_checkboxs_at_once)

        #available_exports_group.setStyleSheet('QGroupBox {font-weight: bold;}')
        available_exports_group.setLayout(self.layout_available_exports)

        # row 0
        self.layout_available_exports.addWidget(QLabel(".hyd"), 0, 2,
                                                Qt.AlignCenter)
        self.layout_available_exports.addWidget(QLabel(".hab"), 0, 3,
                                                Qt.AlignCenter)
        # row 1
        self.layout_available_exports.addWidget(QLabel("Geopackage (.gpkg)"),
                                                1, 0)
        self.layout_available_exports.addWidget(
            QLabel(self.tr("Mesh whole profile")), 1, 1)
        self.layout_available_exports.addWidget(self.mesh_whole_profile_hyd, 1,
                                                2, Qt.AlignCenter)
        # row 2
        self.layout_available_exports.addWidget(QLabel("Geopackage (.gpkg)"),
                                                2, 0)
        self.layout_available_exports.addWidget(
            QLabel(self.tr("Point whole profile")), 2, 1)
        self.layout_available_exports.addWidget(self.point_whole_profile_hyd,
                                                2, 2, Qt.AlignCenter)
        # row 3
        self.layout_available_exports.addWidget(QLabel("Geopackage (.gpkg)"),
                                                3, 0)
        self.layout_available_exports.addWidget(QLabel(self.tr("Mesh units")))
        self.layout_available_exports.addWidget(self.mesh_units_hyd, 3, 2,
                                                Qt.AlignCenter)
        self.layout_available_exports.addWidget(self.mesh_units_hab, 3, 3,
                                                Qt.AlignCenter)
        # row 4
        self.layout_available_exports.addWidget(QLabel("Geopackage (.gpkg)"),
                                                4, 0)
        self.layout_available_exports.addWidget(QLabel(self.tr("Point units")),
                                                4, 1)
        self.layout_available_exports.addWidget(self.point_units_hyd, 4, 2,
                                                Qt.AlignCenter)
        self.layout_available_exports.addWidget(self.point_units_hab, 4, 3,
                                                Qt.AlignCenter)
        # row 5
        self.layout_available_exports.addWidget(QHLine(), 5, 0, 1, 4)
        # row 6
        self.layout_available_exports.addWidget(QLabel("3D (.stl)"), 6, 0)
        self.layout_available_exports.addWidget(
            QLabel(self.tr("Mesh whole profile")), 6, 1)
        self.layout_available_exports.addWidget(
            self.elevation_whole_profile_hyd, 6, 2, Qt.AlignCenter)
        # row 7
        self.layout_available_exports.addWidget(QLabel("3D (.pvd, .vtu)"), 7,
                                                0)
        self.pvd_variable_z_layout = QHBoxLayout()
        self.pvd_variable_z_layout.addWidget(QLabel(self.tr("Mesh units")))
        self.pvd_variable_z_layout.addWidget(self.pvd_variable_z_combobox)
        self.layout_available_exports.addLayout(self.pvd_variable_z_layout, 7,
                                                1)
        #        self.layout_available_exports.addWidget(QLabel(self.tr("Mesh units")), 7, 1)
        self.layout_available_exports.addWidget(self.variables_units_hyd, 7, 2,
                                                Qt.AlignCenter)
        self.layout_available_exports.addWidget(self.variables_units_hab, 7, 3,
                                                Qt.AlignCenter)
        # row 8
        self.layout_available_exports.addWidget(vertical_exaggeration, 8, 0, 1,
                                                2)
        self.layout_available_exports.addWidget(
            self.vertical_exaggeration_lineedit, 8, 2, 1, 2, Qt.AlignCenter)
        # row 9
        self.layout_available_exports.addWidget(QHLine(), 9, 0, 1, 4)
        # row 10
        self.layout_available_exports.addWidget(QLabel("Text (.txt)"), 10, 0)
        self.layout_available_exports.addWidget(
            QLabel(self.tr("Mesh detailled")), 10, 1)
        self.layout_available_exports.addWidget(self.mesh_detailled_text_hyd,
                                                10, 2, Qt.AlignCenter)
        self.layout_available_exports.addWidget(self.mesh_detailled_text_hab,
                                                10, 3, Qt.AlignCenter)
        # row 11
        self.layout_available_exports.addWidget(QLabel("Text (.txt)"), 11, 0)
        self.layout_available_exports.addWidget(
            QLabel(self.tr("Point detailled")), 11, 1)
        self.layout_available_exports.addWidget(self.point_detailled_text_hyd,
                                                11, 2, Qt.AlignCenter)
        self.layout_available_exports.addWidget(self.point_detailled_text_hab,
                                                11, 3, Qt.AlignCenter)
        # row 11
        self.layout_available_exports.addWidget(QLabel("Text (.pdf)"), 12, 0)
        self.layout_available_exports.addWidget(
            QLabel(self.tr("Fish informations")), 12, 1)
        self.layout_available_exports.addWidget(self.fish_information_hab, 12,
                                                3, Qt.AlignCenter)

        # figure options
        layout_figures = QFormLayout()
        figures_group = QGroupBox(self.tr("Figures"))
        #figures_group.setStyleSheet('QGroupBox {font-weight: bold;}')
        figures_group.setLayout(layout_figures)
        layout_figures.addRow(fig_size_label, self.fig_size_lineedit)
        layout_figures.addRow(color_map_label, self.color_map_combobox)
        layout_figures.addRow(font_size_label, self.font_size_lineedit)
        layout_figures.addRow(font_family_label, self.font_family_combobox)
        layout_figures.addRow(line_width_label, self.line_width_lineedit)
        layout_figures.addRow(grid_label, self.grid_checkbox)
        layout_figures.addRow(fig_format_label, self.fig_format_combobox)
        layout_figures.addRow(resolution_label, self.resolution_lineedit)
        layout_figures.addRow(type_fishname_label, self.type_fishname_combobox)
        layout_figures.addRow(marquers_hab_fig_label,
                              self.marquers_hab_fig_checkbox)

        # general
        layout = QGridLayout(self)
        layout.addWidget(general_options_group, 0, 0)
        layout.addWidget(available_exports_group, 1, 0)
        layout.addWidget(figures_group, 0, 1, 3, 2)
        layout.addWidget(self.reset_by_default_pref, 3, 0, Qt.AlignLeft)
        layout.addWidget(self.save_pref_button, 3, 1)  # , 1, 1
        layout.addWidget(self.close_pref_button, 3, 2)  # , 1, 1

        self.setWindowTitle(self.tr("Project properties"))
        self.setWindowIcon(QIcon(self.name_icon))

    def connect_modifications_signal(self):
        self.cut_2d_grid_checkbox.stateChanged.connect(
            self.set_modification_presence)
        self.min_height_lineedit.textChanged.connect(
            self.set_modification_presence)
        self.erase_data_checkbox.stateChanged.connect(
            self.set_modification_presence)
        self.pvd_variable_z_combobox.currentIndexChanged.connect(
            self.set_modification_presence)
        self.vertical_exaggeration_lineedit.textChanged.connect(
            self.set_modification_presence)
        for checkbox in self.output_checkbox_list:
            checkbox.stateChanged.connect(self.set_modification_presence)
        self.fig_size_lineedit.textChanged.connect(
            self.set_modification_presence)
        self.color_map_combobox.currentIndexChanged.connect(
            self.set_modification_presence)
        self.font_size_lineedit.textChanged.connect(
            self.set_modification_presence)
        self.line_width_lineedit.textChanged.connect(
            self.set_modification_presence)
        self.grid_checkbox.stateChanged.connect(self.set_modification_presence)
        self.fig_format_combobox.currentIndexChanged.connect(
            self.set_modification_presence)
        self.resolution_lineedit.textChanged.connect(
            self.set_modification_presence)
        self.type_fishname_combobox.currentIndexChanged.connect(
            self.set_modification_presence)
        self.marquers_hab_fig_checkbox.stateChanged.connect(
            self.set_modification_presence)

    def set_pref_gui_from_dict(self, default=False):
        if default:
            project_properties = create_default_project_properties_dict()
        else:
            # read actual figure option
            project_properties = load_project_properties(self.path_prj)

        # min_height_hyd
        self.min_height_lineedit.setText(
            str(project_properties['min_height_hyd']))

        # CutMeshPartialyDry
        if project_properties[
                'cut_mesh_partialy_dry']:  # is a string not a boolean
            self.cut_2d_grid_checkbox.setChecked(True)
        else:
            self.cut_2d_grid_checkbox.setChecked(False)

        # erase_id
        if project_properties['erase_id']:  # is a string not a boolean
            self.erase_data_checkbox.setChecked(True)
        else:
            self.erase_data_checkbox.setChecked(False)

        # pvd_variable_z_combobox
        item_list = [
            self.hvum.z.name_gui, self.hvum.h.name_gui, self.hvum.v.name_gui,
            self.hvum.level.name_gui, self.hvum.hydraulic_head_level.name_gui,
            self.hvum.conveyance.name_gui, self.hvum.froude.name_gui
        ]
        self.pvd_variable_z_combobox.clear()
        self.pvd_variable_z_combobox.addItems(item_list)
        self.pvd_variable_z_combobox.setCurrentIndex(
            item_list.index(project_properties["pvd_variable_z"]))

        # vertical_exaggeration
        self.vertical_exaggeration_lineedit.setText(
            str(project_properties["vertical_exaggeration"]))

        # check uncheck output checkboxs
        for checkbox in self.output_checkbox_list:
            type = checkbox.objectName()[-3:]
            if type == "hyd":
                index = 0
            if type == "hab":
                index = 1
            checkbox.setChecked(
                project_properties[checkbox.objectName()[:-4]][index])

        # color_map
        self.color_map_combobox.setCurrentIndex(
            self.color_map_combobox.findText(project_properties['color_map']))

        # fig_size
        self.fig_size_lineedit.setText(
            str(project_properties['width']) + ',' +
            str(project_properties['height']))

        # font size
        self.font_size_lineedit.setText(str(project_properties['font_size']))

        # font_family
        font_family_list = [
            self.font_family_combobox.itemText(i)
            for i in range(self.font_family_combobox.count())
        ]
        self.font_family_combobox.setCurrentIndex(
            font_family_list.index(project_properties['font_family']))

        # line_width
        self.line_width_lineedit.setText(str(project_properties['line_width']))

        # grid
        if project_properties['grid']:  # is a string not a boolean
            self.grid_checkbox.setChecked(True)
        else:
            self.grid_checkbox.setChecked(False)

        # format
        fig_format_list = [
            self.fig_format_combobox.itemText(i)
            for i in range(self.fig_format_combobox.count())
        ]
        self.fig_format_combobox.setCurrentIndex(
            fig_format_list.index(project_properties['format']))

        # resolution
        self.resolution_lineedit.setText(str(project_properties['resolution']))

        # fish_name_type
        self.type_fishname_combobox.setCurrentIndex(
            int(project_properties['fish_name_type']))

        # marker
        if project_properties['marker']:  # is a string not a boolean
            self.marquers_hab_fig_checkbox.setChecked(True)
        else:
            self.marquers_hab_fig_checkbox.setChecked(False)

    def open_preferences(self):
        self.set_pref_gui_from_dict()
        self.connect_modifications_signal()
        self.check_modifications_presence()
        self.setModal(True)
        self.show()

    def check_modifications_presence(self):
        self.is_modification = False

    def set_modification_presence(self):
        self.is_modification = True

    def check_uncheck_all_checkboxs_at_once(self):
        # uncheck all
        if self.mesh_whole_profile_hyd.isChecked():
            [
                checkbox.setChecked(False)
                for checkbox in self.output_checkbox_list
            ]
        else:
            [
                checkbox.setChecked(True)
                for checkbox in self.output_checkbox_list
            ]

    def collect_project_properties_choice(self):
        """
        Function to collect user choices of project preferences GUI
        """
        # get default option for security and facility
        project_properties = load_project_properties(self.path_prj)

        fig_size = self.fig_size_lineedit.text()
        if fig_size:
            fig_size = fig_size.split(',')
            try:
                project_properties['width'] = np.float(fig_size[0])
                project_properties['height'] = np.float(fig_size[1])
            except IndexError:
                self.send_log.emit('Error: ' + self.tr(
                    'The size of the figure should be in the format: num1,num2.\n'
                ))
            except ValueError:
                self.send_log.emit('Error: ' + self.tr(
                    'The size of the figure should be in the format: num1,num2.\n'
                ))
        # color map
        c1 = str(self.color_map_combobox.currentText())
        if c1:
            project_properties['color_map'] = c1
        # font size
        font_size = self.font_size_lineedit.text()
        if font_size:
            try:
                project_properties['font_size'] = int(font_size)
            except ValueError:
                self.send_log.emit(
                    'Error: ' + self.tr('Font size should be an integer. \n'))
        # font_family
        font_family = self.font_family_combobox.currentText()
        if font_family:
            try:
                project_properties['font_family'] = font_family
            except ValueError:
                self.send_log.emit('Error: ' +
                                   self.tr('Font family not recognized. \n'))
        # line width
        line_width = self.line_width_lineedit.text()
        if line_width:
            try:
                project_properties['line_width'] = int(line_width)
            except ValueError:
                self.send_log.emit(
                    'Error: ' + self.tr('Line width should be an integer. \n'))
        # grid
        if self.grid_checkbox.isChecked():
            project_properties['grid'] = True
        else:
            project_properties['grid'] = False
        # format
        project_properties['format'] = self.fig_format_combobox.currentText()
        # resolution
        try:
            project_properties['resolution'] = int(
                self.resolution_lineedit.text())
        except ValueError:
            self.send_log.emit(
                'Error: ' + self.tr('The resolution should be an integer. \n'))
        if project_properties['resolution'] < 0:
            self.send_log.emit(
                'Error: ' +
                self.tr('The resolution should be higher than zero \n'))
            return
        if project_properties['resolution'] > 2000:
            self.send_log.emit(
                self.tr('Warning: ') + self.
                tr('The resolution is higher than 2000 dpi. Figures might be very large.\n'
                   ))

        # fish name type
        project_properties['fish_name_type'] = int(
            self.type_fishname_combobox.currentIndex())
        # marker
        if self.marquers_hab_fig_checkbox.isChecked():
            project_properties['marker'] = True
        else:
            project_properties['marker'] = False

        # outputs
        for checkbox in self.output_checkbox_list:
            type = checkbox.objectName()[-3:]
            if type == "hyd":
                index = 0
            if type == "hab":
                index = 1
            if checkbox.isChecked():
                project_properties[checkbox.objectName()[:-4]][index] = True
            else:
                project_properties[checkbox.objectName()[:-4]][index] = False

        # vertical_exaggeration
        try:
            project_properties['vertical_exaggeration'] = int(
                self.vertical_exaggeration_lineedit.text())
            if int(self.vertical_exaggeration_lineedit.text()) < 1:
                self.send_log.emit("Error: " + self.tr(
                    "Vertical exaggeration value must be superior than 1. Value set to 1."
                ))
                project_properties['vertical_exaggeration'] = 1
        except:
            self.send_log.emit("Error: " + self.tr(
                "Vertical exaggeration value is not integer. Value set to 1."))
            project_properties['vertical_exaggeration'] = 1

        # pvd_variable_z
        project_properties[
            'pvd_variable_z'] = self.pvd_variable_z_combobox.currentText()

        # other option
        try:
            project_properties['min_height_hyd'] = float(
                self.min_height_lineedit.text())
        except ValueError:
            self.send_log.emit('Error: ' +
                               self.tr('Minimum Height should be a number'))
        if self.erase_data_checkbox.isChecked():
            project_properties['erase_id'] = True
        else:
            project_properties['erase_id'] = False
        # CutMeshPartialyDry
        if self.cut_2d_grid_checkbox.isChecked():
            project_properties['cut_mesh_partialy_dry'] = True
        else:
            project_properties['cut_mesh_partialy_dry'] = False

        return project_properties

    def save_preferences(self):
        """
        A function which save the options for the figures in the xlm project file. The options for the figures are
        contained in a dictionnary. The idea is to give this dictinnory in argument to all the fonction which create
        figures. In the xml project file, the options for the figures are saved under the attribute "Figure_Option".

        If you change things here, it is necessary to start a new project as the old projects will not be compatible.
        For the new version of HABBY, it will be necessary to insure compatibility by adding xml attribute.
        """
        project_properties = self.collect_project_properties_choice()

        # save the data in the xml file
        fname = os.path.join(self.path_prj, self.name_prj + '.habby')

        # save the name and the path in the xml .prj file
        if not os.path.isfile(fname):
            self.msg2.setIcon(QMessageBox.Warning)
            self.msg2.setWindowTitle(self.tr("Project properties unsaved"))
            self.msg2.setText(self.tr("Create or open an HABBY project."))
            self.msg2.setStandardButtons(QMessageBox.Ok)
            self.msg2.show()
        else:
            save_project_properties(self.path_prj, project_properties)

        self.send_log.emit(self.tr('# Project properties saved.'))

        # project_properties['cut_mesh_partialy_dry'] to change suffix no_cut
        self.cut_mesh_partialy_dry_signal.emit(
            project_properties['cut_mesh_partialy_dry'])

        self.close()

    def close_preferences(self):
        # # really user want to save ?
        # if self.is_modification:
        #     self.msg2.setIcon(QMessageBox.Warning)
        #     self.msg2.setWindowTitle(self.tr("Preferences modified"))
        #     self.msg2.setText(self.tr("Do you really want to close preferences without saving your changes ?"))
        #     self.msg2.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        #     res = self.msg2.exec_()
        #
        #     # delete
        #     if res == QMessageBox.Yes:
        #         self.send_log.emit('Preferences not saved.')
        #         self.close()
        #         return
        #     if res == QMessageBox.No:
        #         return

        # close window if opened
        self.close()
Пример #35
0
class NetworkChoiceLayout(object):
    def __init__(self, network: Network, config, wizard=False):
        self.network = network
        self.config = config
        self.protocol = None
        self.tor_proxy = None

        self.tabs = tabs = QTabWidget()
        server_tab = QWidget()
        proxy_tab = QWidget()
        blockchain_tab = QWidget()
        tabs.addTab(blockchain_tab, _('Overview'))
        tabs.addTab(server_tab, _('Server'))
        tabs.addTab(proxy_tab, _('Proxy'))

        fixed_width_hostname = 30 * char_width_in_lineedit()
        fixed_width_port = 8 * char_width_in_lineedit()

        # server tab
        grid = QGridLayout(server_tab)
        grid.setSpacing(8)

        self.server_host = QLineEdit()
        self.server_host.setFixedWidth(fixed_width_hostname)
        self.server_port = QLineEdit()
        self.server_port.setFixedWidth(fixed_width_port)
        self.autoconnect_cb = QCheckBox(_('Select server automatically'))
        self.autoconnect_cb.setEnabled(
            self.config.is_modifiable('auto_connect'))

        self.server_host.editingFinished.connect(self.set_server)
        self.server_port.editingFinished.connect(self.set_server)
        self.autoconnect_cb.clicked.connect(self.set_server)
        self.autoconnect_cb.clicked.connect(self.update)

        msg = ' '.join([
            _("If auto-connect is enabled, Electrum will always use a server that is on the longest blockchain."
              ),
            _("If it is disabled, you have to choose a server you want to use. Electrum will warn you if your server is lagging."
              )
        ])
        grid.addWidget(self.autoconnect_cb, 0, 0, 1, 3)
        grid.addWidget(HelpButton(msg), 0, 4)

        grid.addWidget(QLabel(_('Server') + ':'), 1, 0)
        grid.addWidget(self.server_host, 1, 1, 1, 2)
        grid.addWidget(self.server_port, 1, 3)

        label = _('Server peers') if network.is_connected() else _(
            'Default Servers')
        grid.addWidget(QLabel(label), 2, 0, 1, 5)
        self.servers_list = ServerListWidget(self)
        grid.addWidget(self.servers_list, 3, 0, 1, 5)

        # Proxy tab
        grid = QGridLayout(proxy_tab)
        grid.setSpacing(8)

        # proxy setting
        self.proxy_cb = QCheckBox(_('Use proxy'))
        self.proxy_cb.clicked.connect(self.check_disable_proxy)
        self.proxy_cb.clicked.connect(self.set_proxy)
        self.proxy_cb.setEnabled(False)

        self.proxy_mode = QComboBox()
        self.proxy_mode.addItems(['SOCKS4', 'SOCKS5'])
        self.proxy_host = QLineEdit()
        self.proxy_host.setFixedWidth(fixed_width_hostname)
        self.proxy_port = QLineEdit()
        self.proxy_port.setFixedWidth(fixed_width_port)
        self.proxy_user = QLineEdit()
        self.proxy_user.setPlaceholderText(_("Proxy user"))
        self.proxy_password = QLineEdit()
        self.proxy_password.setPlaceholderText(_("Password"))
        self.proxy_password.setEchoMode(QLineEdit.Password)
        self.proxy_password.setFixedWidth(fixed_width_port)

        self.proxy_mode.currentIndexChanged.connect(self.set_proxy)
        self.proxy_host.editingFinished.connect(self.set_proxy)
        self.proxy_port.editingFinished.connect(self.set_proxy)
        self.proxy_user.editingFinished.connect(self.set_proxy)
        self.proxy_password.editingFinished.connect(self.set_proxy)

        self.proxy_mode.currentIndexChanged.connect(
            self.proxy_settings_changed)
        self.proxy_host.textEdited.connect(self.proxy_settings_changed)
        self.proxy_port.textEdited.connect(self.proxy_settings_changed)
        self.proxy_user.textEdited.connect(self.proxy_settings_changed)
        self.proxy_password.textEdited.connect(self.proxy_settings_changed)

        self.tor_cb = QCheckBox(_("Use Tor Proxy"))
        self.tor_cb.setIcon(read_QIcon("tor_logo.png"))
        self.tor_cb.hide()
        self.tor_cb.clicked.connect(self.use_tor_proxy)
        self.tor_cb.setEnabled(False)

        grid.addWidget(self.tor_cb, 1, 0, 1, 3)
        grid.addWidget(self.proxy_cb, 2, 0, 1, 3)
        grid.addWidget(
            HelpButton(
                _('Proxy settings apply to all connections: with Electrum servers, but also with third-party services.'
                  )), 2, 4)
        grid.addWidget(self.proxy_mode, 4, 1)
        grid.addWidget(self.proxy_host, 4, 2)
        grid.addWidget(self.proxy_port, 4, 3)
        grid.addWidget(self.proxy_user, 5, 2)
        grid.addWidget(self.proxy_password, 5, 3)
        grid.setRowStretch(7, 1)

        # Blockchain Tab
        grid = QGridLayout(blockchain_tab)
        msg = ' '.join([
            _("Electrum connects to several nodes in order to download block headers and find out the longest blockchain."
              ),
            _("This blockchain is used to verify the transactions sent by your transaction server."
              )
        ])
        self.status_label = QLabel('')
        grid.addWidget(QLabel(_('Status') + ':'), 0, 0)
        grid.addWidget(self.status_label, 0, 1, 1, 3)
        grid.addWidget(HelpButton(msg), 0, 4)

        self.server_label = QLabel('')
        msg = _(
            "Electrum sends your wallet addresses to a single server, in order to receive your transaction history."
        )
        grid.addWidget(QLabel(_('Server') + ':'), 1, 0)
        grid.addWidget(self.server_label, 1, 1, 1, 3)
        grid.addWidget(HelpButton(msg), 1, 4)

        self.height_label = QLabel('')
        msg = _('This is the height of your local copy of the blockchain.')
        grid.addWidget(QLabel(_('Blockchain') + ':'), 2, 0)
        grid.addWidget(self.height_label, 2, 1)
        grid.addWidget(HelpButton(msg), 2, 4)

        self.split_label = QLabel('')
        grid.addWidget(self.split_label, 3, 0, 1, 3)

        self.nodes_list_widget = NodesListWidget(self)
        grid.addWidget(self.nodes_list_widget, 5, 0, 1, 5)

        vbox = QVBoxLayout()
        vbox.addWidget(tabs)
        self.layout_ = vbox
        # tor detector
        self.td = td = TorDetector()
        td.found_proxy.connect(self.suggest_proxy)
        td.start()

        self.fill_in_proxy_settings()
        self.proxy_cb.setChecked(True)
        self.tor_cb.setChecked(True)
        self.check_disable_proxy(9150)
        self.set_proxy()
        self.update()

    def check_disable_proxy(self, b):
        if not self.config.is_modifiable('proxy'):
            b = False
        for w in [
                self.proxy_mode, self.proxy_host, self.proxy_port,
                self.proxy_user, self.proxy_password
        ]:
            w.setEnabled(b)

    def enable_set_server(self):
        if self.config.is_modifiable('server'):
            enabled = not self.autoconnect_cb.isChecked()
            self.server_host.setEnabled(enabled)
            self.server_port.setEnabled(enabled)
            self.servers_list.setEnabled(enabled)
        else:
            for w in [
                    self.autoconnect_cb, self.server_host, self.server_port,
                    self.servers_list
            ]:
                w.setEnabled(False)

    def update(self):
        net_params = self.network.get_parameters()
        host, port, protocol = net_params.host, net_params.port, net_params.protocol
        proxy_config, auto_connect = net_params.proxy, net_params.auto_connect
        if not self.server_host.hasFocus() and not self.server_port.hasFocus():
            self.server_host.setText(host)
            self.server_port.setText(str(port))
        self.autoconnect_cb.setChecked(auto_connect)

        interface = self.network.interface
        host = interface.host if interface else _('None')
        self.server_label.setText(host)

        self.set_protocol(protocol)
        self.servers = self.network.get_servers()
        self.servers_list.update(self.servers, self.protocol,
                                 self.tor_cb.isChecked())
        self.enable_set_server()

        height_str = "%d " % (self.network.get_local_height()) + _('blocks')
        self.height_label.setText(height_str)
        n = len(self.network.get_interfaces())
        status = _("Connected to {0} nodes.").format(n) if n else _(
            "Not connected")
        self.status_label.setText(status)
        chains = self.network.get_blockchains()
        if len(chains) > 1:
            chain = self.network.blockchain()
            forkpoint = chain.get_max_forkpoint()
            name = chain.get_name()
            msg = _('Chain split detected at block {0}').format(
                forkpoint) + '\n'
            msg += (_('You are following branch') if auto_connect else
                    _('Your server is on branch')) + ' ' + name
            msg += ' (%d %s)' % (chain.get_branch_size(), _('blocks'))
        else:
            msg = ''
        self.split_label.setText(msg)
        self.nodes_list_widget.update(self.network)

    def fill_in_proxy_settings(self):
        proxy_config = self.network.get_parameters().proxy
        if not proxy_config:
            proxy_config = {
                "mode": "none",
                "host": "localhost",
                "port": "9150"
            }

        b = proxy_config.get('mode') != "none"
        self.check_disable_proxy(b)
        if b:
            self.proxy_cb.setChecked(True)
            self.proxy_mode.setCurrentIndex(
                self.proxy_mode.findText(str(
                    proxy_config.get("mode").upper())))

        self.proxy_host.setText(proxy_config.get("host"))
        self.proxy_port.setText(proxy_config.get("port"))
        self.proxy_user.setText(proxy_config.get("user", ""))
        self.proxy_password.setText(proxy_config.get("password", ""))

    def layout(self):
        return self.layout_

    def set_protocol(self, protocol):
        if protocol != self.protocol:
            self.protocol = protocol

    def change_protocol(self, use_ssl):
        p = 's' if use_ssl else 't'
        host = self.server_host.text()
        pp = self.servers.get(host, constants.net.DEFAULT_PORTS)
        if p not in pp.keys():
            p = list(pp.keys())[0]
        port = pp[p]
        self.server_host.setText(host)
        self.server_port.setText(port)
        self.set_protocol(p)
        self.set_server()

    def follow_branch(self, chain_id):
        self.network.run_from_another_thread(
            self.network.follow_chain_given_id(chain_id))
        self.update()

    def follow_server(self, server):
        self.network.run_from_another_thread(
            self.network.follow_chain_given_server(server))
        self.update()

    def server_changed(self, x):
        if x:
            self.change_server(str(x.text(0)), self.protocol)

    def change_server(self, host, protocol):
        pp = self.servers.get(host, constants.net.DEFAULT_PORTS)
        if protocol and protocol not in protocol_letters:
            protocol = None
        if protocol:
            port = pp.get(protocol)
            if port is None:
                protocol = None
        if not protocol:
            if 's' in pp.keys():
                protocol = 's'
                port = pp.get(protocol)
            else:
                protocol = list(pp.keys())[0]
                port = pp.get(protocol)
        self.server_host.setText(host)
        self.server_port.setText(port)

    def accept(self):
        pass

    def set_server(self):
        net_params = self.network.get_parameters()
        net_params = net_params._replace(
            host=str(self.server_host.text()),
            port=str(self.server_port.text()),
            auto_connect=self.autoconnect_cb.isChecked())
        self.network.run_from_another_thread(
            self.network.set_parameters(net_params))

    def set_proxy(self):
        net_params = self.network.get_parameters()
        if self.proxy_cb.isChecked():
            proxy = {
                'mode': str(self.proxy_mode.currentText()).lower(),
                'host': str(self.proxy_host.text()),
                'port': str(self.proxy_port.text()),
                'user': str(self.proxy_user.text()),
                'password': str(self.proxy_password.text())
            }
        else:
            proxy = None
            self.tor_cb.setChecked(False)
        net_params = net_params._replace(proxy=proxy)
        self.network.run_from_another_thread(
            self.network.set_parameters(net_params))

    def suggest_proxy(self, found_proxy):
        if found_proxy is None:
            self.tor_cb.hide()
            return
        self.tor_proxy = found_proxy
        self.tor_cb.setText("Use Tor proxy at port " + str(found_proxy[1]))
        if (self.proxy_cb.isChecked() and self.proxy_mode.currentIndex()
                == self.proxy_mode.findText('SOCKS5')
                and self.proxy_host.text() == "127.0.0.1"
                and self.proxy_port.text() == str(found_proxy[1])):
            self.tor_cb.setChecked(True)
        self.tor_cb.show()

    def use_tor_proxy(self, use_it):
        if not use_it:
            self.proxy_cb.setChecked(False)
        else:
            socks5_mode_index = self.proxy_mode.findText('SOCKS5')
            if socks5_mode_index == -1:
                _logger.info("can't find proxy_mode 'SOCKS5'")
                return
            self.proxy_mode.setCurrentIndex(socks5_mode_index)
            self.proxy_host.setText("127.0.0.1")
            self.proxy_port.setText(str(self.tor_proxy[1]))
            self.proxy_user.setText("")
            self.proxy_password.setText("")
            self.tor_cb.setChecked(True)
            self.proxy_cb.setChecked(True)
        self.check_disable_proxy(use_it)
        self.set_proxy()

    def proxy_settings_changed(self):
        self.tor_cb.setChecked(False)
Пример #36
0
class MainWindow(QMainWindow):

    loop_started = pyqtSignal()
    loop_finished = pyqtSignal()

    def __init__(self):
        super().__init__()

        # call a function that initializes user interface
        self.init_ui()
        # call a function that initializes menu bar
        self.init_menu_bar()

        # self.instruments is a dictionary containing all instruments that have been connected so far. Form of the dict
        # is: key:value where key is the name of the instrument assigned by you when creating the instrument, and value
        # contains that particular instance of that instrument.
        self.instruments = {}

        # station instruments are used to keep track of the instruments that were added to the instruments table on the
        # main window, each time an instrument is added to the table it is also added to this dict to keep track of
        # which instruments are already displayed
        self.station_instruments = {}

        # loops dictionary containing all loops that have been created so far. Form: key : value where key is the name
        # of the loop that is assigned automatically in order of creation of loops (loop1, loop2, loop3, ...), and the
        # value is an instance of that loop
        self.loops = {}

        # dividers dict holds data about all dividers created so far. Form of the data inside: key : value where key
        # is name of the parameter that the divider is attached to, and value is instance of that particular divider.
        self.dividers = {}

        # Keeping track of the loops that are already displayed in table on the main window (to avoid duplicate adding)
        self.shown_loops = []

        # actions is a list containing list of all loops and the last loop added to this list is the one that will get
        # ran by the run/plot button. I have created this because dictionaries do not have predefined way of puting data
        # into it, meaning that the order of adding items to the dictionary may or may not be the same as the order of
        # getting that same data from the dictionary
        self.actions = []

        # list of references to the EditInstrumentWidget windows that are currently open, used to start live updating
        # of parameters of each of those windows after a measurement has been started. That way only the ones that are
        # currently opened will be automatically self updating
        self.active_isntruments = []

        # instrument workers is a list of handles to the workers that do the above explained actions. Reason for keeping
        # this list is because these workers have to be stopped at some point.
        self.instrument_workers = []

        # contains references to buttons for editing
        self.edit_button_dict = {}

        # Thread pool for adding separate threads
        # (execute qcodes in another thread [to not freeze GUI thread while executing])
        self.thread_pool = QThreadPool()

        # Handles to all active workers (with the idea of stopping them). Contains only workers that run loops, other
        # other workers are stored in different lists
        self.workers = []

        # check this to see if stop has been requested
        self.stop_loop_requested = True

        # holds string representation of folder in which to save measurement data
        self.save_location = ""

        # keep track of number of line traces currently display. Used when loop in a loop is ran to draw the last n
        # line traces only
        self.line_trace_count = 0

        # keep track of live plots in case someone closes one of them that they can be reopened
        self.live_plots = []

        self.statusBar().showMessage("Ready")
        self.show()

    """""" """""" """""" """
    User interface
    """ """""" """""" """"""

    def init_ui(self):
        """
        Initializes the main window user interface, sets dimensions, position, etc. of a main window
        :return: NoneType
        """
        # get dimensions of the monitor, and position the window accordingly
        _, _, width, height = QDesktopWidget().screenGeometry().getCoords()
        self.setGeometry(int(0.02 * width), int(0.05 * height), 640, 440)
        # define the size, title and icon of the window
        self.setMinimumSize(640, 440)
        self.setWindowTitle("qcodes starter")
        self.setWindowIcon(QtGui.QIcon("img/osciloscope_icon.png"))

        self.grid_layout = QGridLayout()
        self.splitter = QSplitter(Qt.Vertical)
        self.grid_layout.addWidget(self.splitter, 0, 0, 9, 6)

        self.cw = QWidget(self)
        self.cw.setLayout(self.grid_layout)
        self.setCentralWidget(self.cw)

        # Create and define table for displaying instruments added to the self.instruments dictionary
        label = QLabel("Instruments:")
        self.splitter.addWidget(label)
        self.instruments_table = QTableWidget(0, 3)
        self.splitter.addWidget(self.instruments_table)
        self.instruments_table.setHorizontalHeaderLabels(
            ("Name", "Type", "Edit"))
        header = self.instruments_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        self.instruments_table.setSelectionBehavior(QTableView.SelectRows)

        horizontal = QSplitter()

        # Create and define table for displaying loops added to the self.loops dictionary
        label = QLabel("Loops")
        horizontal.addWidget(label)
        self.splitter.addWidget(horizontal)

        # Button for displaying data structure of each created loop
        self.show_loop_details_btn = QPushButton("Show tree", self.cw)
        horizontal.addWidget(self.show_loop_details_btn)
        icon = QtGui.QIcon("img/binary_tree_icon.png")
        self.show_loop_details_btn.setIcon(icon)
        self.show_loop_details_btn.clicked.connect(self.open_tree)

        # simple text editor
        self.open_text_edit_btn = QPushButton("Text", self.cw)
        horizontal.addWidget(self.open_text_edit_btn)
        self.open_text_edit_btn.clicked.connect(self.open_text_editor)
        icon = QtGui.QIcon("img/text_icon.png")
        self.open_text_edit_btn.setIcon(icon)

        self.loops_table = QTableWidget(0, 4)
        self.loops_table.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.splitter.addWidget(self.loops_table)
        self.loops_table.setHorizontalHeaderLabels(
            ("Name", "Edit", "Run", "Delete"))
        header = self.loops_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        self.instruments_table.setSelectionBehavior(QTableView.SelectRows)

        # Button for opening a new window that is used for connecting to instruments
        self.btn_add_instrument = QPushButton("Add instrument")
        self.grid_layout.addWidget(self.btn_add_instrument, 0, 6, 1, 2)
        self.btn_add_instrument.resize(200, 200)
        icon = QtGui.QIcon("img/osciloscope_icon.png")
        self.btn_add_instrument.setIcon(icon)
        self.btn_add_instrument.clicked.connect(
            lambda checked, name="DummyInstrument": self.add_new_instrument(
                name))

        # Button to open a window that is used to create and manage loops (measurements)
        self.btn_setup_loops = QPushButton("Setup loops")
        self.grid_layout.addWidget(self.btn_setup_loops, 1, 6, 1, 2)
        icon = QtGui.QIcon("img/measure.png")
        self.btn_setup_loops.setIcon(icon)
        self.btn_setup_loops.clicked.connect(self.setup_loops)

        # Button to open a new window that is used for creating, editing and deleting dividers
        self.btn_attach_dividers = QPushButton("Attach dividers")
        self.grid_layout.addWidget(self.btn_attach_dividers, 2, 6, 1, 2)
        icon = QtGui.QIcon("img/rheostat_icon.png")
        self.btn_attach_dividers.setIcon(icon)
        self.btn_attach_dividers.clicked.connect(self.open_attach_divider)

        # text box used to input the desired name of your output file produced by the loop
        label = QLabel("Output file name")
        self.grid_layout.addWidget(label, 4, 6, 1, 1)
        self.output_file_name = QLineEdit()
        self.grid_layout.addWidget(self.output_file_name, 5, 6, 1, 2)

        # btn that opens file dialog for selecting a desired location where to save the ouput file of the loop
        self.btn_select_save_location = QPushButton("Select save location")
        self.grid_layout.addWidget(self.btn_select_save_location, 6, 6, 1, 2)
        icon = QtGui.QIcon("img/save_icon.png")
        self.btn_select_save_location.setIcon(icon)
        self.btn_select_save_location.clicked.connect(
            self.select_save_location)

        # btn for stoping all currently active loops
        self.stop_btn = QPushButton("STOP")
        self.grid_layout.addWidget(self.stop_btn, 7, 6, 1, 2)
        icon = QtGui.QIcon("img/cancel_1-512.png")
        self.stop_btn.setIcon(icon)
        self.stop_btn.clicked.connect(self.stop_all_workers)

        # run a loop with live ploting as a backgroud task (new window with self updating plot will be opened)
        """self.plot_btn = QPushButton("Plot", self)
        self.plot_btn.move(480, 340)
        self.plot_btn.resize(60, 40)
        self.plot_btn.clicked.connect(self.run_with_plot)
        icon = QtGui.QIcon("img/plot_icon.png")
        self.plot_btn.setIcon(icon)"""

        self.select_loop_cb = QComboBox()
        self.grid_layout.addWidget(self.select_loop_cb, 8, 6, 1, 1)

        # run a loop without displaying the live plot
        self.btn_run = QPushButton("Run")
        self.grid_layout.addWidget(self.btn_run, 8, 7, 1, 1)
        self.btn_run.clicked.connect(self.run_with_plot)
        icon = QtGui.QIcon("img/play_icon.png")
        self.btn_run.setIcon(icon)

        self.statusBar().showMessage("Ready")

        # Defining all shortcuts
        add_shortcut = QShortcut(QtGui.QKeySequence(Qt.Key_F12), self.cw)
        add_shortcut.activated.connect(self.setup_loops)

        # self.setCentralWidget(self)

    def init_menu_bar(self):
        """
        Initializes menu bar, creates actions and submenus within menu bar, connects actions to menu items
        KNOWN PROBLEMS -> ["M3201A", "M3300A", "M4i", "ZIUHFLI"] list of instruments that produce bugs

        :return: NoneType
        """
        # Create action and bind it to a function that exits the application and closes all of its windows
        exit_action = QAction("&Exit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.setStatusTip("Exit the application")
        exit_action.triggered.connect(self.exit)

        # Action for adding a new instrument
        start_new_measurement_menu = QMenu("Add instrument", self)
        start_new_measurement_action = QAction("New", self)
        start_new_measurement_action.setShortcut("Ctrl+M")
        start_new_measurement_action.setStatusTip(
            "Open 'Add New Instrument' window")
        start_new_measurement_action.triggered.connect(
            lambda checked, name="DummyInstrument": self.add_new_instrument(
                name))

        start_new_measurement_menu.addAction(start_new_measurement_action)
        start_new_measurement_menu.addSeparator()

        # fetch all instruments defined in qcodes and add then to the Add Instrument menu. Clicking any of these will
        # open AddInstrumentWidget with data for this instrument already filled in that window
        path = os.path.dirname(inspect.getfile(qc)) + "\\instrument_drivers"
        brands = get_subfolders(path, True)
        for brand in brands:
            current_brand_menu = QMenu(brand, self)
            start_new_measurement_menu.addMenu(current_brand_menu)
            models = get_files_in_folder(path + "\\" + brand, True)
            for model in models:
                if model[0:-3] not in [
                        "M3201A", "M3300A", "M4i", "Keithley_2600_channels",
                        "AWGFileParser", "Keysight_33500B_channels",
                        "Infiniium", "KeysightAgilent_33XXX", "Model_336",
                        "Base_SPDT", "RC_SP4T", "RC_SPDT", "USB_SPDT",
                        "QDac_channels", "RTO1000", "ZNB", "SR860", "SR86x",
                        "AWG5208", "AWG70000A", "AWG70002A",
                        "Keithley_2600_channels"
                ]:
                    # above is the list of instruments that produce error when attempting to create them
                    current_model_action = QAction(model[0:-3], self)
                    current_model_action.setData(model[0:-3])
                    current_brand_menu.addAction(current_model_action)
                    current_model_action.triggered.connect(
                        lambda checked, name=current_model_action.data(
                        ): self.add_new_instrument(name))
                else:
                    current_model_action = QAction(model[0:-3], self)
                    current_model_action.setEnabled(False)
                    current_model_action.setIcon(
                        QtGui.QIcon("img/disabled.png"))
                    current_brand_menu.addAction(current_model_action)
                    current_model_action.triggered.connect(
                        lambda checked, name=current_model_action.data(
                        ): self.add_new_instrument(name))

        reopen_plot_window = QAction("Reopen plot", self)
        reopen_plot_window.triggered.connect(self.reopen_plot_windows)

        multi_param_measurement = QAction("Multi sweep", self)
        multi_param_measurement.triggered.connect(
            self.open_multi_sweep_measurement)

        file_menu = self.menuBar().addMenu("&File")
        file_menu.addAction(exit_action)
        file_menu.addMenu(start_new_measurement_menu)

        tools_menu = self.menuBar().addMenu("&Tools")
        tools_menu.addAction(reopen_plot_window)

        measurement_menu = self.menuBar().addMenu("&Measurement")
        measurement_menu.addAction(multi_param_measurement)

    """""" """""" """""" """
    Data manipulation
    """ """""" """""" """"""

    def update_station_preview(self):
        """
        When new instrument is added, add a line to instrument_table widget containing some data (name and type) about
        the instrument, as well as button to edit the instrument.

        :return: NoneType
        """
        # Go ahead and iterate through all instruments that have been created so far and if any of those instruments
        # hasn't been added to the table , add it to the table
        for instrument in self.instruments:
            if instrument not in self.station_instruments:
                current_instrument = self.instruments[instrument]
                rows = self.instruments_table.rowCount()
                self.instruments_table.insertRow(rows)
                item = QTableWidgetItem(instrument)
                item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self.instruments_table.setItem(rows, 0, item)
                item = QTableWidgetItem(str(current_instrument))
                item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self.instruments_table.setItem(rows, 1, item)
                current_instrument_btn = QPushButton("Edit")
                current_instrument_btn.clicked.connect(
                    self.make_open_instrument_edit(instrument))
                self.instruments_table.setCellWidget(rows, 2,
                                                     current_instrument_btn)
                self.edit_button_dict[instrument] = current_instrument_btn
                self.station_instruments[instrument] = self.instruments[
                    instrument]

                # Also bind a shortcut for opening that instrument coresponding to the number of the row that the
                # instrument is displayed in (Example: instrument in row 1 will have shortcut F1, row 2 -> F2, ....)
                key = "Key_F" + str(rows + 1)
                key_class = getattr(Qt, key)

                add_shortcut = QShortcut(QtGui.QKeySequence(key_class), self)
                add_shortcut.activated.connect(
                    self.make_open_instrument_edit(instrument))

    def update_loops_preview(self, edit=False):
        """
        This function is called from child class (SetupLoopsWidget) each time a new loop is created.
        Adds a loop to a loops_table widget which contains all loops as well as buttons to "Edit", "Run" and "Delete"
        a loop.

        Edit:
            opens "SetupLoopsWidget" with data from specified loop
        Run:
            runs the loop with current data (with plot)
        Delete:
            removes a loop from the table and from the self.loops dictionary, and also deletes action from self.actions
            that coresponds to this loop.

        :return: NoneType
        """
        # Iterate through all loops that have been created and added to self.loops dictionary, if any of those has not
        # been added to loops table (and shown loops dict) then add it to both so that it is visible in the window
        for name, loop in self.loops.items():
            if name not in self.shown_loops:
                rows = self.loops_table.rowCount()
                self.loops_table.insertRow(rows)

                # Model a string that will display loop values in the table.
                # Format: loop_name[lower_limit, upper_limit, num_of_steps, delay].action_parameter
                lower = str(loop.sweep_values[0])
                upper = str(loop.sweep_values[-1])
                steps = str(len(loop.sweep_values))
                delay = str(loop.delay)
                display_string = "{} [{}, {}, {}, {}].{}".format(
                    name, lower, upper, steps, delay, str(loop.actions[0]))
                item = QTableWidgetItem(display_string)
                item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self.loops_table.setItem(rows, 0, item)
                current_loop_btn = QPushButton("Edit")
                current_loop_btn.resize(35, 20)
                current_loop_btn.clicked.connect(
                    lambda checked, loop_name=name: self.setup_loops(loop_name
                                                                     ))
                self.loops_table.setCellWidget(rows, 1, current_loop_btn)

                # Button within a table that runs a loop that is in the same table row as the button
                run_current_loop_btn = QPushButton("Run")
                run_current_loop_btn.resize(35, 20)
                run_current_loop_btn.clicked.connect(
                    lambda checked, loop_name=name: self.run_specific_loop(
                        loop_name))
                self.loops_table.setCellWidget(rows, 2, run_current_loop_btn)

                # Button within the table that removes a loop that is in the same row as the button
                delete_current_loop = QPushButton("Delete")
                delete_current_loop.resize(35, 20)
                delete_current_loop.clicked.connect(
                    self.make_delete_loop(name, item))
                self.loops_table.setCellWidget(rows, 3, delete_current_loop)

                self.shown_loops.append(name)
                self.select_loop_cb.addItem(name, loop)

                # Create a shortcut for opening each loop. Loop in row1 opens with key combo: CTRL + F1, row2: CTRL+F2
                key_combo_string = "Ctrl+F" + str(rows + 1)
                add_shortcut = QShortcut(QtGui.QKeySequence(key_combo_string),
                                         self)
                add_shortcut.activated.connect(
                    lambda loop_name=name: self.setup_loops(loop_name))

            elif edit == name:
                for i in range(self.loops_table.rowCount()):
                    item = self.loops_table.item(i, 0)
                    if item.text()[:len(name) + 1] == name + " ":
                        rows = i
                        break

                # if a loop is being edited, just update the values of the edited loop
                lower = str(loop.sweep_values[0])
                upper = str(loop.sweep_values[-1])
                steps = str(len(loop.sweep_values))
                delay = str(loop.delay)
                display_string = "{} [{}, {}, {}, {}].{}".format(
                    name, lower, upper, steps, delay, str(loop.actions[0]))
                item = QTableWidgetItem(display_string)
                item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self.loops_table.setItem(rows, 0, item)
                self.loops_table.removeCellWidget(rows, 3)
                delete_current_loop = QPushButton("Delete")
                delete_current_loop.resize(35, 20)
                delete_current_loop.clicked.connect(
                    self.make_delete_loop(name, item))
                self.loops_table.setCellWidget(rows, 3, delete_current_loop)

    def run_qcodes(self, with_plot=False):
        """
        Runs qcodes with specified instruments and parameters. Checks for errors in data prior to runing qcodes
        Adds all instruments to qc.Station and runs the last created loop (i think this is not good, but hey theres a
        button for each loop to run that specific loop)

        Loop is ran in a separate thread so that it does not block GUI thread (and the program)

        :param with_plot: if set to true, runs (and saves) live plot while measurement is running
        :return: NoneType
        """
        self.stop_loop_requested = False
        self.loop_started.emit()
        self.line_trace_count = 0

        # first create a station and add all instruments to it, to have the data available in the output files
        station = qc.Station()
        for name, instrument in self.instruments.items():
            station.add_component(instrument, name)

        # grab the last action added to the actions list. Set its data_set to None in case that loop has already been
        # ran. Create a new data set with the name and location provided by user input
        if len(self.actions):
            loop = self.actions[-1]
            loop.data_set = None

            # adjust save location of the file
            if self.save_location != "":
                loc_provider = qc.data.location.FormatLocation(
                    fmt=self.save_location +
                    '/{date}/#{counter}_{name}_{time}')
                qc.data.data_set.DataSet.location_provider = loc_provider
            data = loop.get_data_set(name=self.output_file_name.text())

            # Check if the function was called with plot in background, if it was, create a new plot, delete backgroud
            # action of the loop (if a loop has been ran before with a background action [loop cannot have more then
            # 1 background action]), attach a new background action and run a loop by calling a worker to run it in a
            # separate thread
            if with_plot:
                # if you are running loop in a loop then create one more graph that will display 10 most recent line
                # traces
                if isinstance(loop.actions[0], ActiveLoop):
                    line_traces_plot = qc.QtPlot(fig_x_position=0.05,
                                                 fig_y_position=0.4,
                                                 window_title="Line traces")
                    self.live_plots.append(line_traces_plot)
                    if len(loop.actions) < 3:
                        loop.actions.append(
                            Task(lambda: self.update_line_traces(
                                line_traces_plot, data, parameter_name)))
                    else:
                        loop.actions[-1] = Task(
                            lambda: self.update_line_traces(
                                line_traces_plot, data, parameter_name))
                    loop.actions[0].progress_interval = None
                else:
                    if loop.progress_interval is None:
                        loop.progress_interval = 20
                parameter = get_plot_parameter(loop)
                plot = qc.QtPlot(fig_x_position=0.05,
                                 fig_y_position=0.4,
                                 window_title=self.output_file_name.text())
                self.live_plots.append(plot)
                parameter_name = str(parameter)
                plot.add(getattr(data, parameter_name))
                # loop.with_bg_task(plot.update, plot.save).run(use_threads=True)
                loop.bg_task = None
                worker = Worker(
                    loop.with_bg_task(plot.update, plot.save).run, False)
            else:
                # loop.run(use_threads=True) -> this has something to do with multiple gets at the same time
                #                               i guess it would get them all at the same time instead of one by one

                # otherwise if plot was not requested, just run a loop (also in separate thread)
                worker = Worker(loop.run, False)
            self.workers.append(worker)

            # connect the signals of a worker
            worker.signals.result.connect(print_output)
            worker.signals.finished.connect(self.cleanup)
            worker.signals.progress.connect(progress_func)

            # start the worker
            del self.workers[:]
            # starting live mode of all opened instruments
            # commented cause it causes collision in the instrument when two different sources send commands to the
            # instrument. Sometimes this causes crashing of the loop.
            """for widget in self.active_isntruments:
                # only if that instrument has this parameter, then start its live mode
                if self.actions[-1].sweep_values.name in widget.textboxes.keys():
                    widget.toggle_live()"""
            self.disable_run_buttons()
            self.thread_pool.start(worker)

        # Just in case someone presses run with no loops created
        else:
            show_error_message("Oops !",
                               "Looks like there is no loop to be ran !")

    def run_with_plot(self):
        """
        Call self.run_qcodes() with parameter with_plot set to True

        :return: NoneType
        """
        self.run_qcodes(with_plot=True)

    @pyqtSlot()
    def select_save_location(self):
        """
        Opens a QFileDialog for selecting a location on local machine, path to the selected location is set as a save
        location for results of the measurment

        :return: NoneType
        """
        self.save_location = str(
            QFileDialog.getExistingDirectory(self, "Select Directory"))

    """""" """""" """""" """
    Helper functions
    """ """""" """""" """"""

    @pyqtSlot()
    def exit(self):
        """
        Close the main window
        :return: NoneType
        """

        # Close all the instruments not to leave any hanging tails
        for name, instrument in self.instruments.items():
            print("Closing", instrument)
            instrument.close()
        # Close all other windows that are currently opened
        app = QtGui.QGuiApplication.instance()
        app.closeAllWindows()

    def closeEvent(self, a0: QtGui.QCloseEvent):
        are_you_sure = QMessageBox()
        close = are_you_sure.question(
            self, "Don't do it.",
            "Are you sure you want to close all windows and exit the application ?",
            are_you_sure.Yes | are_you_sure.No)

        if close == are_you_sure.Yes:
            self.exit()
            a0.accept()
        else:
            a0.ignore()
            return

    @pyqtSlot()
    def add_new_instrument(self, name):
        """
        Opens a new Widget (window) with text inputs for parameters of an instrument, creates new instrument(s)
        :return: NoneType
        """
        # AddInstrumentWidget need access to self.instruments dictionary in order to be able to add any newly created
        # instruments to it
        self.add_instrument = Widget(self.instruments,
                                     parent=self,
                                     default=name)
        self.add_instrument.submitted.connect(self.update_station_preview)
        self.add_instrument.show()

    @pyqtSlot()
    def open_tree(self):
        """
        Open a TreeView to inspect created loops

        :return: NoneType
        """
        self.view_tree = ViewTree(
            {name: loop.snapshot_base()
             for name, loop in self.loops.items()})
        self.view_tree.show()

    @pyqtSlot()
    def setup_loops(self, loop_name=""):
        """
        Open a new widget for creating loops based on instruments added to "instruments" dictionary trough
        AddInstrumentWidget. Loops created with this widget are added to MainWindows "loops" dictionary, also for each
        loop an action to be executed is created and added to MainWindows "actions" list

        :return:
        """
        self.setup_loops_widget = LoopsWidget(self.instruments,
                                              self.dividers,
                                              self.loops,
                                              self.actions,
                                              parent=self,
                                              loop_name=loop_name)
        self.setup_loops_widget.show()

    @pyqtSlot()
    def open_text_editor(self):
        """
        Open a simple text editor as a new widget (possible custom tool creation)

        :return: NoneType
        """
        msg = random[randint(1, len(random))]
        show_error_message("Do you need some motivation ?", msg)

    @pyqtSlot()
    def open_attach_divider(self):
        """
        Opens a new widget for setting up  dividers. Can attach a divider to any parameter of any instrument
        People are gonna add dividers to parameters that cannot have divider (like IDN) im sure of this.
        God help them.

        :return: NoneType
        """
        self.attach_divider_widget = DividerWidget(self.instruments,
                                                   self.dividers,
                                                   parent=self)
        self.attach_divider_widget.show()

    @pyqtSlot()
    def open_multi_sweep_measurement(self, name=""):
        self.msm = MultiSweep(self.instruments,
                              self.dividers,
                              self.loops,
                              self.actions,
                              parent=self,
                              loop_name=name)
        self.msm.show()

    def stop_all_workers(self):
        """
        Reworked: Stops all instruments that are currently being live updated and returns them to static mode

        :return:
        """
        print(self.workers)
        print("Emmiting the signal to all workers")
        for worker in self.instrument_workers:
            worker.stop_requested = True
        for widget in self.active_isntruments:
            if widget.live:
                widget.toggle_live()
        self.stop_loop_requested = True
        self.enable_run_buttons()

    # This is a function factory (wow, i'm so cool, i made a function factory)
    def make_open_instrument_edit(self, instrument):
        """
        Hi, i am a function factory, and for each button you see next to an instrument i create a new function to edit
        that particular instrument. After creating that function i return it so it can be called with a click on the
        button.

        :param instrument: refers to a name of the instrument to be edited
        :return: newly created function to open "EditInstrumentWidget" with this particular instrument
        """
        def open_instrument_edit():
            """
            Open a new widget and pass it an instrument that can be edited through the newly opened widget

            :return: NoneType
            """
            if hasattr(self.instruments[instrument], "timeout"):
                self.instruments[instrument].set("timeout", 50)
            # Parameters:
            # self. instruments: widget needs access to all instruments to be able to edit them and add new ones
            # self.dividers: widget needs access to dividers to be able to display them if they are attached
            # self.active_instruments: list of instrument edit windows that are opened, to be able to remove self
            # from that list when closing the window
            # self.thread_pool: To be able to run functions in a shared thread pool (get_all, set_all)
            # parent: reference to this widget
            # instrument_name: name of the instrument that is being edited, to be able to fetch it from instruments
            # dictionary that is also being passed to this widget
            self.edit_instrument = EditInstrumentWidget(
                self.instruments,
                self.dividers,
                self.active_isntruments,
                self.thread_pool,
                parent=self,
                instrument_name=instrument)
            # Add newly created window to a list of active windows
            self.active_isntruments.append(self.edit_instrument)
            self.edit_instrument.show()

        return open_instrument_edit

    def run_specific_loop(self, loop_name):
        """
        Place the action that coresponds to this loop to the last place in the actions queue so that its the one that
        gets ran by the run button, and then run it ... d'oh

        :param loop_name: name of the loop that is supposed to be ran
        :return: NoneType
        """

        # since name of the loop is a parameter of this function, get the loop from loops, find it in the actions list
        # put it in the last place of that list (remember, the last one is the one that get run), and then run it
        loop = self.loops[loop_name]
        loop_index = self.actions.index(loop)
        self.actions[loop_index], self.actions[-1] = self.actions[
            -1], self.actions[loop_index]
        self.run_with_plot()

    def make_delete_loop(self, loop_name, item):
        """
        Function factory, creates functions that delete each individual loop from tableWidget for loops

        :param loop_name: name of the loop (to be able to remove it from loops dictionary)
        :param item: use this item to find which row of the tabelWidget to delete
        :return: pointer to the newly created function
        """
        def delete_loop():
            """
            Remove a loop from loops_table widget
            :return: NoneType
            """
            self.loops_table.removeRow(self.loops_table.row(item))
            if loop_name in self.loops:
                if self.loops[loop_name] in self.actions:
                    self.actions.remove(self.loops[loop_name])
                del self.loops[loop_name]

        return delete_loop

    def check_stop_request(self):
        """
        This function is passed to a qcodes Task() to be checked on every measure point of the loop. Function checks if
        the class member stop_loop_requested is set to true, and if it is it raises an exception that stops the qcodes
        loop.

        :return:
        """
        if self.stop_loop_requested is True:
            self.enable_run_buttons()
            raise _QcodesBreak

    def disable_run_buttons(self):
        """
        This function is used to disable running other loops when one of the loops has started. Multiple loops running
        at the same time might try to send commands to the same instrument and cause an error.

        :return: NoneType
        """
        self.btn_run.setDisabled(True)

        for row_index in range(self.loops_table.rowCount()):
            run_button = self.loops_table.cellWidget(row_index, 2)
            run_button.setDisabled(True)
            delete_button = self.loops_table.cellWidget(row_index, 3)
            delete_button.setDisabled(True)
            edit_button = self.loops_table.cellWidget(row_index, 1)
            edit_button.setDisabled(True)

    def enable_run_buttons(self):
        """
        After a loop has finished enable running other loops.

        :return: NoneType
        """
        self.btn_run.setDisabled(False)
        for row_index in range(self.loops_table.rowCount()):
            run_button = self.loops_table.cellWidget(row_index, 2)
            run_button.setDisabled(False)
            delete_button = self.loops_table.cellWidget(row_index, 3)
            delete_button.setDisabled(False)
            edit_button = self.loops_table.cellWidget(row_index, 1)
            edit_button.setDisabled(False)

    def cleanup(self):
        """
        This function is called when a thread is finished to stop the workers and re enable run buttons.
        :return:
        """
        self.stop_all_workers()
        self.enable_run_buttons()
        self.loop_finished.emit()
        self.line_trace_count = 0
        self.live_plots = []

    def run_with_livedata(self):
        """
        ################################################################################################################
        LEGACY METHOD. Was used when i had no idea that each parameter hold the data of its last value so i dont need to
        get it everytime from the physical instrument, i can just get it from tha parameter object.
        ################################################################################################################

        This function appends a task to a loop. Task updates value of instruments parameter every iteration of the loop.
        After appending the task the loop gets started with plot option turned on.

        :return: NoneType
        """
        loop_name = self.select_loop_cb.currentText()
        loop = self.loops[loop_name]
        tsk = Task(self.update_opened_instruments)
        loop.actions.append(tsk)
        loop_index = self.actions.index(loop)
        self.actions[loop_index], self.actions[-1] = self.actions[
            -1], self.actions[loop_index]
        self.run_with_plot()

    def update_opened_instruments(self):
        """
        ################################################################################################################
        LEGACY METHOD. Was used when i had no idea that each parameter hold the data of its last value so i dont need to
        get it everytime from the physical instrument, i can just get it from tha parameter object.
        ################################################################################################################
        Function that updates the value of a parameter that is being swept if the EditWindow of that window is opened.

        :return: NoneType
        """
        for widget in self.active_isntruments:
            # only if that instrument has this parameter, then start its live mode
            name = self.actions[-1].sweep_values.name
            if name in widget.textboxes.keys():
                widget.update_parameters_data(name=name)

    def update_line_traces(self, plot, dataset, parameter_name):
        """
        Add 10 line traces to a graph, and then clear the graph and add 10 new line traces.

        :param plot: Instance of a graph that we want to add a line trace eto
        :param dataset: Dataset from which we extract the data
        :param parameter_name: Name of the parameter that is being plotted
        :return: NoneType
        """
        if self.line_trace_count % 10 == 0:
            plot.clear()
        plot.add(getattr(dataset, parameter_name)[self.line_trace_count])
        print(self.line_trace_count)
        self.line_trace_count += 1

    def resize_for_loop(self, decrease=False):
        """
        Legacy method, not used anymore since switching to layouts

        Method that resizes the window when a loop is added/removed from it.

        :param decrease: If loop is being removed decreas will be set to True and window size will be decreased
        :return: NoneType
        """

        if decrease == False:
            if self.loops_table.rowCount() > 2:
                self.loops_table.resize(self.loops_table.width(),
                                        self.loops_table.height() + 30)
                self.resize(self.width(), self.height() + 30)
        else:
            if self.loops_table.rowCount() > 1:
                self.loops_table.resize(self.loops_table.width(),
                                        self.loops_table.height() - 30)
                self.resize(self.width(), self.height() - 30)

    def reopen_plot_windows(self):
        for plot in self.live_plots:
            plot.win.show()
            print(plot)
Пример #37
0
class PaletteDocker(DockWidget):
    # Init the docker

    def __init__(self):
        super(PaletteDocker, self).__init__()
        # make base-widget and layout
        widget = QWidget()
        layout = QVBoxLayout()
        buttonLayout = QHBoxLayout()
        widget.setLayout(layout)
        self.setWindowTitle(i18n("Python Palette Docker"))

        # Make a combobox and add palettes
        self.cmb_palettes = QComboBox()
        allPalettes = Application.resources("palette")
        for palette_name in allPalettes:
            self.cmb_palettes.addItem(palette_name)
            self.cmb_palettes.model().sort(0)

        if len(allPalettes.keys()) > 0:
            self.currentPalette = Palette(list(allPalettes.values())[0])
        else:
            self.currentPalette = None

        self.cmb_palettes.currentTextChanged.connect(self.slot_paletteChanged)
        layout.addWidget(self.cmb_palettes)  # add combobox to the layout
        self.paletteView = PaletteView()
        self.paletteView.setPalette(self.currentPalette)
        layout.addWidget(self.paletteView)
        self.paletteView.entrySelectedForeGround.connect(
            self.slot_swatchSelected)

        self.colorComboBox = QComboBox()
        self.colorList = list()
        buttonLayout.addWidget(self.colorComboBox)
        self.bnSetColor = QToolButton()
        self.bnSetColor.setText(i18n("Set"))
        self.bnSetColor.clicked.connect(self.slot_get_color_from_combobox)
        buttonLayout.addWidget(self.bnSetColor)

        self.addEntry = QAction(self)
        self.addEntry.setIconText(i18n("+"))
        self.addEntry.triggered.connect(self.slot_add_entry)
        self.addGroup = QAction(self)
        self.addGroup.triggered.connect(self.slot_add_group)
        self.addGroup.setText(i18n("Add Group"))
        self.addGroup.setIconText(str("\U0001F4C2"))
        self.removeEntry = QAction(self)
        self.removeEntry.setText(i18n("Remove Entry"))
        self.removeEntry.setIconText("-")
        self.removeEntry.triggered.connect(self.slot_remove_entry)
        addEntryButton = QToolButton()
        addEntryButton.setDefaultAction(self.addEntry)
        buttonLayout.addWidget(addEntryButton)
        addGroupButton = QToolButton()
        addGroupButton.setDefaultAction(self.addGroup)
        buttonLayout.addWidget(addGroupButton)
        removeEntryButton = QToolButton()
        removeEntryButton.setDefaultAction(self.removeEntry)
        buttonLayout.addWidget(removeEntryButton)

        # QActions
        self.extra = QToolButton()
        self.editPaletteData = QAction(self)
        self.editPaletteData.setText(i18n("Edit Palette Settings"))
        self.editPaletteData.triggered.connect(self.slot_edit_palette_data)
        self.extra.setDefaultAction(self.editPaletteData)
        buttonLayout.addWidget(self.extra)
        self.actionMenu = QMenu()
        self.exportToGimp = QAction(self)
        self.exportToGimp.setText(i18n("Export as GIMP Palette File"))
        self.exportToGimp.triggered.connect(self.slot_export_to_gimp_palette)
        self.exportToInkscape = QAction(self)
        self.exportToInkscape.setText(
            i18n("Export as Inkscape SVG with Swatches"))
        self.exportToInkscape.triggered.connect(
            self.slot_export_to_inkscape_svg)
        self.sortColors = QAction(self)
        self.sortColors.setText(i18n("Sort Colors"))
        self.sortColors.triggered.connect(self.slot_sort_colors)
        self.actionMenu.addAction(self.editPaletteData)
        self.actionMenu.addAction(self.exportToGimp)
        self.actionMenu.addAction(self.exportToInkscape)
        # self.actionMenu.addAction(self.sortColors)

        self.extra.setMenu(self.actionMenu)

        layout.addLayout(buttonLayout)
        self.slot_fill_combobox()
        self.setWidget(widget)  # add widget to the docker

    def slot_paletteChanged(self, name):
        allPalettes = Application.resources("palette")
        if len(allPalettes) > 0 and name in allPalettes:
            self.currentPalette = Palette(
                Application.resources("palette")[name])
            self.paletteView.setPalette(self.currentPalette)
            self.slot_fill_combobox()

    @pyqtSlot('KisSwatch')
    def slot_swatchSelected(self, entry):
        if (self.canvas()) is not None:
            if (self.canvas().view()) is not None:
                name = entry.name()
                if len(entry.id) > 0:
                    name = entry.id() + " - " + entry.name()
                if len(name) > 0:
                    if name in self.colorList:
                        self.colorComboBox.setCurrentIndex(
                            self.colorList.index(name))
                color = self.currentPalette.colorForEntry(entry)
                self.canvas().view().setForeGroundColor(color)

    def slot_fill_combobox(self):
        '''A function for making a combobox with the available colors. We use
        QCompleter on the colorComboBox so that people can type in the
        name of a color to select it. This is useful for people with
        carefully made palettes where the colors are named properly,
        which makes it easier for them to find colors.
        '''

        if self.currentPalette is None:
            pass
        self.colorComboBox.clear()
        self.colorList = list()
        #        palette = self.currentPalette
        #        for info in palette.infoList():
        #            entry = info.swatch
        #            color = palette.colorForEntry(entry).colorForCanvas(self.canvas())
        #            colorSquare = QPixmap(12, 12)
        #            if entry.spotColor() is True:
        #                img = colorSquare.toImage()
        #                circlePainter = QPainter()
        #                img.fill(self.colorComboBox.palette().color(QPalette.Base))
        #                circlePainter.begin(img)
        #                brush = QBrush(Qt.SolidPattern)
        #                brush.setColor(color)
        #                circlePainter.setBrush(brush)
        #                circlePainter.pen().setWidth(0)
        #                circlePainter.drawEllipse(0, 0, 11, 11)
        #                circlePainter.end()
        #                colorSquare = QPixmap.fromImage(img)
        #            else:
        #                colorSquare.fill(color)
        #            name = entry.name()
        #            if len(entry.id()) > 0:
        #                name = entry.id() + " - " + entry.name()
        #            self.colorList.append(name)
        #            self.colorComboBox.addItem(QIcon(colorSquare), name)
        self.colorComboBox.setEditable(True)
        self.colorComboBox.setInsertPolicy(QComboBox.NoInsert)
        self.colorComboBox.completer().setCompletionMode(
            QCompleter.PopupCompletion)
        self.colorComboBox.completer().setCaseSensitivity(False)
        self.colorComboBox.completer().setFilterMode(Qt.MatchContains)

    def slot_get_color_from_combobox(self):
        if self.currentPalette is not None:
            entry = self.currentPalette.colorSetEntryByIndex(
                self.colorComboBox.currentIndex())
            self.slot_swatchSelected(entry)

    def slot_add_entry(self):
        if (self.canvas()) is not None:
            if (self.canvas().view()) is not None:
                color = self.canvas().view().foregroundColor()
                success = self.paletteView.addEntryWithDialog(color)
                if success is True:
                    self.slot_fill_combobox()

    def slot_add_group(self):
        success = self.paletteView.addGroupWithDialog()
        if success is True:
            self.slot_fill_combobox()

    def slot_remove_entry(self):
        success = self.paletteView.removeSelectedEntryWithDialog()
        if success is True:
            self.slot_fill_combobox()

    def slot_edit_palette_data(self):
        '''A function for giving a gui to edit palette metadata... I also
        want this to be the way to edit the settings of the palette
        docker.
        '''

        dialog = QDialog(self)
        tabWidget = QTabWidget()
        dialog.setWindowTitle(i18n("Edit Palette Data"))
        dialog.setLayout(QVBoxLayout())
        dialog.layout().addWidget(tabWidget)
        paletteWidget = QWidget()
        paletteWidget.setLayout(QVBoxLayout())
        tabWidget.addTab(paletteWidget, i18n("Palette Data"))
        paletteName = QLineEdit()
        paletteName.setText(self.cmb_palettes.currentText())
        paletteWidget.layout().addWidget(paletteName)
        paletteColumns = QSpinBox()
        paletteColumns.setValue(self.currentPalette.columnCount())
        paletteWidget.layout().addWidget(paletteColumns)
        paletteComment = QPlainTextEdit()
        paletteComment.appendPlainText(self.currentPalette.comment())
        paletteWidget.layout().addWidget(paletteComment)
        buttons = QDialogButtonBox(QDialogButtonBox.Ok)
        dialog.layout().addWidget(buttons)
        buttons.accepted.connect(dialog.accept)
        # buttons.rejected.connect(dialog.reject())

        if dialog.exec_() == QDialog.Accepted:
            Resource = Application.resources("palette")[
                self.cmb_palettes.currentText()]
            Resource.setName(paletteName.text())
            self.currentPalette = Palette(Resource)
            self.currentPalette.setColumnCount(paletteColumns.value())
            self.paletteView.setPalette(self.currentPalette)
            self.slot_fill_combobox()
            self.currentPalette.setComment(paletteComment.toPlainText())
            self.currentPalette.save()

    def slot_export_to_gimp_palette(self):
        palette_exporter_gimppalette.gimpPaletteExporter(
            self.cmb_palettes.currentText())

    def slot_export_to_inkscape_svg(self):
        palette_exporter_inkscapeSVG.inkscapeSVGExporter(
            self.cmb_palettes.currentText())

    def slot_sort_colors(self):
        colorSorter = palette_sortColors.sortColors(
            self.cmb_palettes.currentText())
        self.paletteView.setPalette(colorSorter.palette())

    def canvasChanged(self, canvas):
        self.cmb_palettes.clear()
        allPalettes = Application.resources("palette")
        for palette_name in allPalettes:
            self.cmb_palettes.addItem(palette_name)
            self.cmb_palettes.model().sort(0)

        if self.currentPalette is None and len(allPalettes.keys()) > 0:
            self.currentPalette = Palette(list(allPalettes.values())[0])
Пример #38
0
class SaveWindow(QDialog):
    def __init__(self, parent=None, file_name = None, MeasurementsLeft = None, MeasurementsRight = None, MeasurementsDeviation = None, MeasurementsPercentual = None):
        super(SaveWindow, self).__init__(parent)
        
        self._NewFile = True    #This variable defines if the user is 
                                #trying to save results in a new file or to a
                                #append results to an existing file
                                
        self._name_of_file = file_name  #this variable stores the name of the 
                                        #file, it won't be modified during 
                                        #execution                        
                                
        self._file_name = file_name     #this variable stores the name of the 
                                        #file to be displayed. It will be 
                                        #modified during execution 
        filename, file_extension = os.path.splitext(self._file_name) 
        delimiter = os.path.sep
        temp=filename.split(delimiter)
        photo_location = temp[0:-1]
        photo_location = delimiter.join(photo_location)
        photo_name=temp[-1]
        
        #measurements
        self._MeasurementsLeft = MeasurementsLeft
        self._MeasurementsRight = MeasurementsRight
        self._MeasurementsDeviation = MeasurementsDeviation
        self._MeasurementsPercentual = MeasurementsPercentual
        
        self._file_name = photo_name  #path + file name
        self._photo_location = photo_location
        self._ID = photo_name #unique identifier
        self._prevspost = '' #pre-treatment vs post-treatment
        self._surgery = '' #type of surgery
        self._expression = '' #type of expression
        self._other = '' #additional comments
        self._file_to_save = '' #file to add data 

        
        self.initUI()
        
    def initUI(self):
        
        self.setWindowTitle('Save')
        if os.name is 'posix': #is a mac or linux
            scriptDir = os.path.dirname(sys.argv[0])
        else: #is a  windows 
            scriptDir = os.getcwd()
            
        self.setWindowIcon(QtGui.QIcon(scriptDir + os.path.sep + 'include' +os.path.sep +'icon_color'+ os.path.sep + 'save_icon.ico'))
        
        self.main_Widget = QtWidgets.QWidget(self)
        
        spacerh = QtWidgets.QWidget(self)
        spacerh.setFixedSize(10,0)
        
        spacerv = QtWidgets.QWidget(self)
        spacerv.setFixedSize(0,10)
        
        
        
        
        
  
        file = QLabel('File Name:')
        self._file = QLineEdit(self)
        self._file.setText(self._file_name)
        
        self.SelectFolderButton = QPushButton('Select &Folder', self)
        self.SelectFolderButton.setFixedWidth(150)
        self.SelectFolderButton.clicked.connect(self.SelectFolder)
        self._SelectFolder = QLineEdit(self)
        self._SelectFolder.setText(self._photo_location) 
        self._SelectFolder.setFixedWidth(350)
        
        
        NewFileBox = QGroupBox('Create new File')
        NewFileBoxLayout = QGridLayout()
        NewFileBoxLayout.addWidget(file,0,0)
        NewFileBoxLayout.addWidget(spacerh,0,1)
        NewFileBoxLayout.addWidget(self._file,0,2)
        NewFileBoxLayout.addWidget(spacerv,1,0)
        NewFileBoxLayout.addWidget(self.SelectFolderButton,2,0)
        NewFileBoxLayout.addWidget(self._SelectFolder,2,2)
        NewFileBox.setLayout(NewFileBoxLayout)
        
        
        SelectFileButton = QPushButton('&Select File', self)
        SelectFileButton.setFixedWidth(150)
        SelectFileButton.clicked.connect(self.SelectFile)       
        self._SelectFile = QLineEdit(self)
        self._SelectFile.setText(self._file_to_save) 
        
        
        AppendFileBox = QGroupBox('Append to Existing File')
        AppendFileBoxLayout = QGridLayout()
        AppendFileBoxLayout.addWidget(SelectFileButton,0,0)
        AppendFileBoxLayout.addWidget(spacerh,0,1)
        AppendFileBoxLayout.addWidget(self._SelectFile,0,2)
        AppendFileBox.setLayout(AppendFileBoxLayout)
        
        
        Identifier = QLabel('Photo Identifier:')
        Identifier.setFixedWidth(120)
        self._Identifier = QLineEdit(self)
        self._Identifier.setText(self._ID)
        
        PrevsPost = QLabel('Pre or Post Procedure:')
        self._PrevsPost = QComboBox()
        self._PrevsPost.setFixedWidth(110)
        self._PrevsPost.addItem('')
        self._PrevsPost.addItem('Pre - Procedure')
        self._PrevsPost.addItem('Post - Procedure')


        SurgeryType = QLabel('Procedure:')
        self._SurgeryType = QLineEdit(self)
        self._SurgeryType.setText(self._surgery)
        
        ExpressionType = QLabel('Expression:')
        self._ExpressionType = QLineEdit(self)
        self._ExpressionType.setText(self._expression)
        
        AddtitionalComments = QLabel('Addtitional Comments:')
        self._AddtitionalComments = QLineEdit(self)
        self._AddtitionalComments.setText(self._other)       
        
        AdditionalInformationBox = QGroupBox('Optional Information')
        AdditionalInformationBoxLayout = QGridLayout()
        
        AdditionalInformationBoxLayout.addWidget(Identifier,0,0)
        AdditionalInformationBoxLayout.addWidget(spacerh,0,1)
        AdditionalInformationBoxLayout.addWidget(self._Identifier,0,2)
        
        AdditionalInformationBoxLayout.addWidget(spacerv,1,0)
        
        AdditionalInformationBoxLayout.addWidget(PrevsPost,2,0)
        AdditionalInformationBoxLayout.addWidget(self._PrevsPost,2,2)
        
        #AdditionalInformationBoxLayout.addWidget(spacerv,3,0) 
        
        AdditionalInformationBoxLayout.addWidget(SurgeryType,4,0)
        AdditionalInformationBoxLayout.addWidget(self._SurgeryType,4,2)
        
        #AdditionalInformationBoxLayout.addWidget(spacerv,5,0) 

        AdditionalInformationBoxLayout.addWidget(ExpressionType,6,0)
        AdditionalInformationBoxLayout.addWidget(self._ExpressionType,6,2)
        
        #AdditionalInformationBoxLayout.addWidget(spacerv,7,0)         

        AdditionalInformationBoxLayout.addWidget(AddtitionalComments,8,0)
        AdditionalInformationBoxLayout.addWidget(self._AddtitionalComments,8,2)    
        
        AdditionalInformationBox.setLayout(AdditionalInformationBoxLayout)
        
        
        
        SaveButton = QPushButton('&Save', self)
        SaveButton.setFixedWidth(150)
        SaveButton.clicked.connect(self.Save)
        
        CancelButton = QPushButton('&Cancel', self)
        CancelButton.setFixedWidth(150)
        CancelButton.clicked.connect(self.Cancel)
        
        
        ButtonBox = QGroupBox('')
        ButtonBoxLayout = QGridLayout()
        ButtonBoxLayout.addWidget(SaveButton,0,0,QtCore.Qt.AlignCenter)
        ButtonBoxLayout.addWidget(spacerh,0,1)
        ButtonBoxLayout.addWidget(CancelButton,0,2,QtCore.Qt.AlignCenter)
        ButtonBox.setLayout(ButtonBoxLayout)
        ButtonBox.setStyleSheet("QGroupBox {  border: 0px solid gray;}");
        
        layout = QGridLayout()

        layout.addWidget(NewFileBox,0,0,2,2)
        
        layout.addWidget(spacerv,1,0)
        
        layout.addWidget(AppendFileBox,2,0,1,2)
               
        
        layout.addWidget(AdditionalInformationBox,4,0,8,2)        
        
        layout.addWidget(ButtonBox,17,0,1,2)
        
        self.setLayout(layout)
        
        #self.show()
    

    def Cancel(self):
        self.close()  

        
    def SelectFolder(self):
        name = QtWidgets.QFileDialog.getExistingDirectory(self, 'Select directory')
        
        if not name:
            pass
        else:
            
            if not self._SelectFolder.isEnabled():        
                self._file.setEnabled(True)
                self._SelectFolder.setEnabled(True)
                self._SelectFile.setText('') 
                
                filename, file_extension = os.path.splitext(self._name_of_file) 
                delimiter = os.path.sep
                temp=filename.split(delimiter)
                photo_name=temp[-1]
                self._file.setText(photo_name)

            name = os.path.normpath(name)
            self._photo_location = name
            self._SelectFolder.setText(self._photo_location)                        
            self._NewFile = True  #a new file will be created
            self.update()
        
    def SelectFile(self):
        name,_ = QtWidgets.QFileDialog.getOpenFileName(
                self,'Load File',
                '',"Excel Spreadsheet  (*.xls *.xlsx)")
        
        if not name:
            pass
        else:
            name = os.path.normpath(name)
            delimiter = os.path.sep
            filename, file_extension = os.path.splitext(name)           
            temp=filename.split(delimiter)
            photo_location = temp[0:-1]
            photo_location = delimiter.join(photo_location)
            photo_name=temp[-1]
            
            self._file_name = photo_name
            
            self._file.setText(self._file_name)
            self._file.setEnabled(False)
            
            
            

            self._photo_location = photo_location
            self._SelectFolder.setText(self._photo_location) 
            self._SelectFolder.setEnabled(False)
            #self.SelectFolderButton.setEnabled(False)
            
            self._file_to_save = name
            self._SelectFile.setText(self._file_to_save) 
            self._NewFile = False  #data will be appended to an exisiting file
            self.update()


            
    def Save(self):
        
        
        number_of_measurements = 10
        Columns = ['Right','Left','Deviation (absolute)','Deviation (percent)']
        Columns = Columns * number_of_measurements
        
        Columns.insert(0,'')
        Columns.insert(0,'')
        Columns.insert(0,'')
        Columns.insert(0,'')
        
        Columns.append('')
        
        
        
        temp = ['Brow Height', 'Marginal Reflex Distance 1', 'Marginal Reflex Distance 2', 'Palpebral Fissure Height',
                'Commisure Excursion', 'Commisure Height Deviation', 'Smile Angle',
                'Upper Lip Height Deviation', 'Dental Show', 'Lower Lip Height Deviation']
        number_of_repetitions=4
        Header = [item for item in temp for i in range(number_of_repetitions)]
        
        
        Header.insert(0,'Expression')
        Header.insert(0,'Procedure')
        Header.insert(0,'Pre vs Post Procedure')
        Header.insert(0,'Unique Identifier')
        
        Header.append('Additional Comments')
        
        
        
        
        #measurements
        elements = ['BH', 'MRD1', 'MRD2', 'PFH', 'CE', 'CH', 'SA', 'UVH', 'DS', 'LVH']
        
        MeasurementsLeft = self._MeasurementsLeft
        MeasurementsRight = self._MeasurementsRight
        MeasurementsDeviation = self._MeasurementsDeviation
        MeasurementsPercentual = self._MeasurementsPercentual

        BH = np.array([[MeasurementsRight.BrowHeight,MeasurementsLeft.BrowHeight,MeasurementsDeviation.BrowHeight,MeasurementsPercentual.BrowHeight]],dtype=object)
        #BH=np.array([[1,1,1,1]],dtype = object)
        MRD1 = np.array([[MeasurementsRight.MarginalReflexDistance1, MeasurementsLeft.MarginalReflexDistance1,MeasurementsDeviation.MarginalReflexDistance1,MeasurementsPercentual.MarginalReflexDistance1]], dtype=object)
        #MRD1=np.array([[1,1,1,1]],dtype = object)
        MRD2 = np.array([[MeasurementsRight.MarginalReflexDistance2, MeasurementsLeft.MarginalReflexDistance2,MeasurementsDeviation.MarginalReflexDistance2,MeasurementsPercentual.MarginalReflexDistance2]],dtype=object)
        #MRD2=np.array([[1,1,1,1]],dtype = object)
        PFH = np.array([[MeasurementsRight.PalpebralFissureHeight, MeasurementsLeft.PalpebralFissureHeight,MeasurementsDeviation.PalpebralFissureHeight,MeasurementsPercentual.PalpebralFissureHeight]],dtype=object)
        
        CE = np.array([[MeasurementsRight.CommissureExcursion, MeasurementsLeft.CommissureExcursion,MeasurementsDeviation.CommissureExcursion,MeasurementsPercentual.CommissureExcursion]],dtype=object)
        #CE=np.array([[1,1,1,1]],dtype = object)
        CH = np.array([['', '',MeasurementsDeviation.CommisureHeightDeviation,'']],dtype=object)
        #CH=np.array([[1,1,1,1]],dtype = object)
        SA = np.array([[MeasurementsRight.SmileAngle, MeasurementsLeft.SmileAngle,MeasurementsDeviation.SmileAngle,MeasurementsPercentual.SmileAngle]],dtype=object)
        #SA=np.array([[1,1,1,1]],dtype = object)
        UVH = np.array([['', '',MeasurementsDeviation.UpperLipHeightDeviation,'']],dtype=object)
        #UVH=np.array([[1,1,1,1]],dtype = object)
        DS = np.array([[MeasurementsRight.DentalShow, MeasurementsLeft.DentalShow,MeasurementsDeviation.DentalShow,MeasurementsPercentual.DentalShow]],dtype=object)
        #DS=np.array([[1,1,1,1]],dtype = object)
        LVH = np.array([['', '',MeasurementsDeviation.LowerLipHeightDeviation,'']],dtype=object)
        #LVH=np.array([[1,1,1,1]],dtype = object)      
        
        
        UI = np.array([[self._Identifier.text()]],dtype = object)
        #UI = np.array([['uno']],dtype = object)
        PvsP = np.array([[str(self._PrevsPost.currentText())]],dtype = object)
        #PvsP = np.array([['dos']],dtype = object)
        PC = np.array([[self._SurgeryType.text()]],dtype = object)
        #PC = np.array([['tres']],dtype = object)
        EX = np.array([[self._ExpressionType.text()]],dtype = object)
        #EX = np.array([['cuatro']],dtype = object)
        AD = np.array([[self._AddtitionalComments.text()]],dtype = object)
        #AD = np.array([['cinco']],dtype = object)
        

        fill= UI
        fill= np.append(fill, PvsP, axis = 1)
        fill= np.append(fill, PC, axis = 1)
        fill= np.append(fill, EX, axis = 1)
        for i in elements:
                fill = np.append(fill, eval(i), axis = 1)
        
        fill= np.append(fill, AD, axis = 1)
        
        
        

        
        if self._NewFile: #the user wants to create a new file
                        
            filename, file_extension = os.path.splitext(self._name_of_file ) 
            delimiter = os.path.sep
            temp=filename.split(delimiter)
            photo_name=temp[-1] + file_extension
            
            
            file_no_ext = os.path.join(str(self._SelectFolder.text()),str(self._file.text()))  
            
            
            Index = [photo_name]
            #create data frame using data
            df = pd.DataFrame(fill, index = Index, columns = Columns)
            df.columns = pd.MultiIndex.from_tuples(list(zip(Header,df.columns)))
            #write data frame to an excel file 
            writer = pd.ExcelWriter(file_no_ext+'.xlsx', engine='xlsxwriter')
            
            df.to_excel(writer, sheet_name='Sheet1', index = True)

            #adjust the size of each column to fit the text
            size_list = [15,20,20,20,20,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,20]
            
            
            worksheet = writer.sheets['Sheet1']
            for k,m in enumerate(size_list):
                worksheet.set_column(k,k,m)

            writer.save()
            self.close() 
            
        else: #the user wants to appedn to an existing file
            
            
            filename, file_extension = os.path.splitext(self._name_of_file ) 
            delimiter = os.path.sep
            temp=filename.split(delimiter)
            photo_name=temp[-1] + file_extension
            
            #create data frame with new ata
            Index = [photo_name]
            df = pd.DataFrame(fill, index = Index, columns = Columns)
            df.columns = pd.MultiIndex.from_tuples(list(zip(Header,df.columns)))
            
            
            #load data from file and arrange its columns to fit the template
            old_df = pd.read_excel(str(self._SelectFile.text()), sheetname=0,header=[0, 1], index_col=0)
            
            
            #verify if the loaded file is valid
            if len(old_df.columns) is 45:
            
                old_df.columns = pd.MultiIndex.from_tuples(df.columns)
            
                #concatenate old and new data frame
                Frames = [old_df, df]
                
                resuls = pd.concat(Frames, axis=0)
                
                #write results in selected file 
                writer = pd.ExcelWriter(str(self._SelectFile.text()), engine='xlsxwriter')
                            
                resuls.to_excel(writer, sheet_name='Sheet1', index = True)
                
                #adjust the size of each column to fit the text
                size_list = [15,20,20,20,20,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,10,10,18,18,20]
                
                worksheet = writer.sheets['Sheet1']
                for k,m in enumerate(size_list):
                    worksheet.set_column(k,k,m)
                
                writer.save()
                self.close() 
            else:
                QtWidgets.QMessageBox.warning(self,"Warning",
                    "Invalid File",
                        QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton)
Пример #39
0
class ScoreDB(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()
        self.dbfilename = 'assignment6.dat'
        self.scoredb = []
        self.readScoreDB()
        self.showScoreDB(self.keyBox())

    def initUI(self):

        nameLabel = QLabel("Name:")
        ageLabel = QLabel("Age:")
        scoreLabel = QLabel("Score")
        self.writingName = QLineEdit()
        self.writingAge = QLineEdit()
        self.writingScore = QLineEdit()
        firstLine = QHBoxLayout()
        firstLine.addWidget(nameLabel)
        firstLine.addWidget(self.writingName)
        firstLine.addWidget(ageLabel)
        firstLine.addWidget(self.writingAge)
        firstLine.addWidget(scoreLabel)
        firstLine.addWidget(self.writingScore)

        amountLabel = QLabel("Amount:")
        keyLabel = QLabel("Key:")
        self.writingAmount = QLineEdit()
        self.keys = QComboBox()
        self.keys.addItem("Name")
        self.keys.addItem("Age")
        self.keys.addItem("Score")
        secondLine = QHBoxLayout()
        secondLine.addStretch(1)
        secondLine.addWidget(amountLabel)
        secondLine.addWidget(self.writingAmount)
        secondLine.addWidget(keyLabel)
        secondLine.addWidget(self.keys)

        addB = QPushButton("Add")
        delB = QPushButton("Del")
        findB = QPushButton("Find")
        incB = QPushButton("Inc")
        showB = QPushButton("Show")
        thrLine = QHBoxLayout()
        thrLine.addStretch(1)
        thrLine.addWidget(addB)
        thrLine.addWidget(delB)
        thrLine.addWidget(findB)
        thrLine.addWidget(incB)
        thrLine.addWidget(showB)

        resLabel = QLabel("Result:")
        fourLine = QHBoxLayout()
        fourLine.addWidget(resLabel)

        self.textBox = QTextEdit()
        fiveLine = QHBoxLayout()
        fiveLine.addWidget(self.textBox)

        vBox = QVBoxLayout()
        vBox.addLayout(firstLine)
        vBox.addLayout(secondLine)
        vBox.addLayout(thrLine)
        vBox.addLayout(fourLine)
        vBox.addLayout(fiveLine)

        addB.clicked.connect(lambda: self.add())
        showB.clicked.connect(lambda: self.showScoreDB(self.keyBox()))
        delB.clicked.connect(lambda: self.delete())
        findB.clicked.connect(lambda: self.finding())
        incB.clicked.connect(lambda: self.inc())

        self.setLayout(vBox)
        self.setGeometry(300, 300, 500, 250)
        self.setWindowTitle('Assignment6')
        self.show()

    def closeEvent(self, event):

        self.writeScoreDB()

    def readScoreDB(self):
        try:
            fH = open(self.dbfilename, 'rb')
        except FileNotFoundError as e:
            self.scoredb = []
            return

        try:
            self.scoredb = pickle.load(fH)
        except:
            pass
        else:
            pass
        fH.close()

    # write the data into person db
    def writeScoreDB(self):
        fH = open(self.dbfilename, 'wb')
        pickle.dump(self.scoredb, fH)
        fH.close()

    def showScoreDB(self, keyname):
        showText = ""
        for p in sorted(self.scoredb, key=lambda person: person[keyname]):
            for attr in sorted(p):
                showText += str(attr) + "=" + str(p[attr]) + "        \t"
            showText += "\n"
        self.textBox.setText(showText)

    def add(self):
        try:
            record = {
                'Name': self.writingName.text(),
                'Age': int(self.writingAge.text()),
                'Score': int(self.writingScore.text())
            }
        except:
            pass
        else:
            self.scoredb += [record]
            self.showScoreDB("Name")

    def keyBox(self):
        returnBox = self.keys.currentText()
        return returnBox

    def delete(self):
        del_list = []
        for p in self.scoredb:
            if p['Name'] == self.writingName.text():
                del_list.append(p)
        for name in del_list:
            self.scoredb.remove(name)
        self.showScoreDB("Name")

    def finding(self):
        finding_text = ""
        for p in self.scoredb:
            if p['Name'] != self.writingName.text():
                continue
            for attr in sorted(p):
                finding_text += str(attr) + "=" + str(p[attr]) + "        \t"
            finding_text += "\n"
        self.textBox.setText(finding_text)

    def inc(self):
        try:
            for p in self.scoredb:
                if p['Name'] == self.writingName.text():
                    p['Score'] = str(
                        int(p['Score']) + int(self.writingAmount.text()))
        except ValueError:
            pass
        self.showScoreDB("Name")
Пример #40
0
class PID_Tuner_Widget(QWidget):
    '''
    This class is a PyQt widget for tunning the 6 degree of freedom PID control system.
    '''
    def __init__(self):
        '''
        Initialize the layout for the widget by setting its color and instantiating its
        components:

        Parameters:
            N/A

        Returns:
            N/A
        '''
        QWidget.__init__(self)

        configs = MechOS_Network_Configs(
            MECHOS_CONFIG_FILE_PATH)._get_network_parameters()

        self.pid_gui_node = mechos.Node("PID_TUNER_GUI", '192.168.1.2',
                                        '192.168.1.14')

        #Publisher to tell the navigation/movement controller when new PID values are saved.
        self.pid_configs_update_publisher = self.pid_gui_node.create_publisher(
            "UPDATE_PID_CONFIGS", Bool(), protocol="tcp")

        #Subscriber to get PID ERRORS
        #self.pid_errors_subscriber = self.pid_gui_node.create_subscriber("PE", self._update_error_plot, configs["sub_port"])
        #self.pid_error_proto = pid_errors_pb2.PID_ERRORS()

        #Mechos parameter server
        #Initialize parameter server client to get and set parameters related to sub
        self.param_serv = mechos.Parameter_Server_Client(
            configs["param_ip"], configs["param_port"])
        self.param_serv.use_parameter_database(configs["param_server_path"])

        #Set background color of the widget
        #nav_gui_palette = self.palette()
        #nav_gui_palette.setColor(self.backgroundRole(), QColor(64, 64, 64))
        #self.setPalette(nav_gui_palette)

        #Create widgets main layout structure
        self.primary_linking_layout = QVBoxLayout(self)
        self.setLayout(self.primary_linking_layout)

        #Options widget
        self.options_linking_layout = QGridLayout()

        self._error_plotter()
        self._PID_controller_select()
        self._PID_sliders()
        self.set_desired_position = Set_Desired_Position_GUI()

        #Set up QTimer to update the PID errors
        self.pid_error_update_timer = QTimer()

        #self.pid_error_update_timer.timeout.connect(lambda: self.pid_gui_node.spinOnce(self.pid_errors_subscriber))

        self.primary_linking_layout.addLayout(self.options_linking_layout, 1)
        self.primary_linking_layout.addWidget(self.set_desired_position, 2)
        #Start PID errors update errors. Update 100 timers a second
        self.pid_error_update_timer.start(10)

    def _PID_controller_select(self):
        '''
        '''
        self.PID_controller_layout = QGridLayout()

        #A combo box to select which PID channel to tune
        self.pid_channel_select = QComboBox()
        self.pid_channel_select.addItem("roll_pid")
        self.pid_channel_select.addItem("pitch_pid")
        self.pid_channel_select.addItem("yaw_pid")
        self.pid_channel_select.addItem("x_pid")
        self.pid_channel_select.addItem("y_pid")
        self.pid_channel_select.addItem("z_pid")

        #Signal to change which PID controller is being tunned when selection changes
        self.pid_channel_select.currentIndexChanged.connect(
            self._PID_controller_change)
        self.pid_channel_select_label = QLabel("PID Controller:")
        self.pid_channel_select_label.setStyleSheet("color: black")

        #A button to save the PID values to the parameter server. This is how to sub
        #will update its PID values
        self.PID_save_values_layout = QVBoxLayout()
        self.pid_values_save = QPushButton("Save PID Values")
        self.pid_values_save.setStyleSheet(
            "background-color:#2C878F; color:#01535B")
        self.pid_values_save.setIcon(QIcon(QPixmap("save_symbol.png")))
        self.pid_values_save.clicked.connect(self._save_pid_values)
        self.PID_save_values_layout.addWidget(self.pid_values_save, 0)

        self.PID_controller_layout.addWidget(self.pid_channel_select_label, 0,
                                             0)
        self.PID_controller_layout.addWidget(self.pid_channel_select, 0, 1)
        self.PID_save_values_layout.addLayout(self.PID_controller_layout, 1)

        self.options_linking_layout.addLayout(self.PID_save_values_layout, 0,
                                              1)

    def _PID_sliders(self):
        '''
        Set up the proportional, integral, and derivatives gain sliders for tunning
        the PID controls.

        Parameters:
            N/A

        Returns:
            N/A
        '''
        self.slider_layout = QGridLayout()
        self.k_p_precision_layout = QGridLayout()
        self.k_i_precision_layout = QGridLayout()
        self.k_d_precision_layout = QGridLayout()

        self.k_p_slider = QSlider(Qt.Horizontal)
        self.k_p_slider.setMaximum(10)
        self.k_p_slider.setMinimum(0)
        self.k_p_slider.setValue(0)
        self.k_p_slider.valueChanged.connect(self._update_gains_with_slider)
        self.k_p_label = QLabel("K_P:")
        self.k_p_label.setStyleSheet("color: black")
        self.k_p_display = QLineEdit()
        self.k_p_display.editingFinished.connect(
            self._update_gain_with_line_edits)

        self.k_p_max_value_line_edit = QLineEdit()
        self.max_k_p = 10.0
        self.k_p_max_value_line_edit.setText(str(self.max_k_p))
        self.k_p_max_value_line_edit.editingFinished.connect(
            self._update_PID_precision)
        self.k_p_max_value_label = QLabel("Max K_P:")
        self.k_p_max_value_label.setStyleSheet("color: black")
        self.k_p_precision_combobox = QComboBox()
        self.k_p_precision_combobox.addItems(["1", "0.1", "0.01", "0.001"])
        self.precision_k_p = float(self.k_p_precision_combobox.currentText())
        self.k_p_precision_combobox.currentIndexChanged.connect(
            self._update_PID_precision)
        self.k_p_precision_label = QLabel("K_P Precision:")
        self.k_p_precision_label.setStyleSheet("color: black")

        self.k_i_slider = QSlider(Qt.Horizontal)
        self.k_i_slider.setMaximum(10)
        self.k_i_slider.setMinimum(0)
        self.k_i_slider.setValue(0)
        self.k_i_slider.valueChanged.connect(self._update_gains_with_slider)
        self.k_i_label = QLabel("K_I:")
        self.k_i_label.setStyleSheet("color: black")
        self.k_i_display = QLineEdit()
        self.k_i_display.editingFinished.connect(
            self._update_gain_with_line_edits)

        self.k_i_max_value_line_edit = QLineEdit()
        self.max_k_i = 10.0
        self.k_i_max_value_line_edit.setText(str(self.max_k_i))
        self.k_i_max_value_line_edit.editingFinished.connect(
            self._update_PID_precision)
        self.k_i_max_value_label = QLabel("Max K_I:")
        self.k_i_max_value_label.setStyleSheet("color: black")
        self.k_i_precision_combobox = QComboBox()
        self.k_i_precision_combobox.addItems(["1", "0.1", "0.01", "0.001"])
        self.precision_k_i = float(self.k_i_precision_combobox.currentText())
        self.k_i_precision_combobox.currentIndexChanged.connect(
            self._update_PID_precision)
        self.k_i_precision_label = QLabel("K_I Precision:")
        self.k_i_precision_label.setStyleSheet("color: black")

        self.k_d_slider = QSlider(Qt.Horizontal)
        self.k_d_slider.setMaximum(10)
        self.k_d_slider.setMinimum(0)
        self.k_d_slider.setValue(0)
        self.k_d_slider.valueChanged.connect(self._update_gains_with_slider)
        self.k_d_label = QLabel("K_D:")
        self.k_d_label.setStyleSheet("color: black")
        self.k_d_display = QLineEdit()
        self.k_d_display.editingFinished.connect(
            self._update_gain_with_line_edits)

        self.k_d_max_value_line_edit = QLineEdit()
        self.max_k_d = 10.0
        self.k_d_max_value_line_edit.setText(str(self.max_k_d))
        self.k_d_max_value_line_edit.editingFinished.connect(
            self._update_PID_precision)
        self.k_d_max_value_label = QLabel("Max K_D:")
        self.k_d_max_value_label.setStyleSheet("color: black")
        self.k_d_precision_combobox = QComboBox()
        self.k_d_precision_combobox.addItems(["1", "0.1", "0.01", "0.001"])
        self.precision_k_d = float(self.k_d_precision_combobox.currentText())
        self.k_d_precision_combobox.currentIndexChanged.connect(
            self._update_PID_precision)
        self.k_d_precision_label = QLabel("K_D Precision:")
        self.k_d_precision_label.setStyleSheet("color: black")

        self.k_p_precision_layout.addWidget(self.k_p_max_value_label, 0, 0)
        self.k_p_precision_layout.addWidget(self.k_p_max_value_line_edit, 0, 1)
        self.k_p_precision_layout.addWidget(self.k_p_precision_label, 1, 0)
        self.k_p_precision_layout.addWidget(self.k_p_precision_combobox, 1, 1)

        self.k_i_precision_layout.addWidget(self.k_i_max_value_label, 0, 0)
        self.k_i_precision_layout.addWidget(self.k_i_max_value_line_edit, 0, 1)
        self.k_i_precision_layout.addWidget(self.k_i_precision_label, 1, 0)
        self.k_i_precision_layout.addWidget(self.k_i_precision_combobox, 1, 1)

        self.k_d_precision_layout.addWidget(self.k_d_max_value_label, 0, 0)
        self.k_d_precision_layout.addWidget(self.k_d_max_value_line_edit, 0, 1)
        self.k_d_precision_layout.addWidget(self.k_d_precision_label, 1, 0)
        self.k_d_precision_layout.addWidget(self.k_d_precision_combobox, 1, 1)

        self.slider_layout.addWidget(self.k_p_label, 0, 0)
        self.slider_layout.addWidget(self.k_p_slider, 0, 1)
        self.slider_layout.addWidget(self.k_p_display, 0, 2)
        self.slider_layout.addLayout(self.k_p_precision_layout, 0, 3)

        self.slider_layout.addWidget(self.k_i_label, 1, 0)
        self.slider_layout.addWidget(self.k_i_slider, 1, 1)
        self.slider_layout.addWidget(self.k_i_display, 1, 2)
        self.slider_layout.addLayout(self.k_i_precision_layout, 1, 3)

        self.slider_layout.addWidget(self.k_d_label, 2, 0)
        self.slider_layout.addWidget(self.k_d_slider, 2, 1)
        self.slider_layout.addWidget(self.k_d_display, 2, 2)
        self.slider_layout.addLayout(self.k_d_precision_layout, 2, 3)

        self.options_linking_layout.addLayout(self.slider_layout, 0, 0)

        self._PID_controller_change()

    def _error_plotter(self):
        '''
        Initialize a real time plotter widget to display the PID error of the sub.

        Parameters:
            N/A

        Returns:
            N/A
        '''
        self.error_plot = Real_Time_Plotter(title="PID Error")
        self.error_plot.add_curve("Current Error", (255, 0, 0))
        self.error_plot.add_curve("Zero Error", (0, 255, 0))
        self.primary_linking_layout.addWidget(self.error_plot, 0)

    def _update_error_plot(self, pid_error_proto):
        '''
        Update the error plot by calling the pid error subscriber. This function is
        the callback function to the pid_error_suscriber.

        Parameters:
            pid_error_proto: The pid error protobuf recieved from the pid error
                                subscriber.
        Returns:
            N/A
        '''
        self.pid_error_proto.ParseFromString(pid_error_proto)

        self.channel = self.pid_channel_select.currentIndex()

        if (self.channel == 0):
            current_error = self.pid_error_proto.roll_error
        elif (self.channel == 1):
            current_error = self.pid_error_proto.pitch_error
        elif (self.channel == 2):
            current_error = self.pid_error_proto.yaw_error
        elif (self.channel == 3):
            current_error = self.pid_error_proto.x_pos_error
        elif (self.channel == 4):
            current_error = self.pid_error_proto.y_pos_error
        elif (self.channel == 5):
            current_error = self.pid_error_proto.z_pos_error
        self.error_plot.update_values(current_error, 0)

    def _PID_controller_change(self):
        '''
        If the PID controller desired to be tune changes, this callback is called
        to position the sliders in the last set PID control position.

        Parameters:
            N/A
        Returns:
            N/A
        '''
        self.channel = self.pid_channel_select.currentText()

        k_p = self.param_serv.get_param('Control/PID/' + self.channel + '/p')
        k_i = self.param_serv.get_param('Control/PID/' + self.channel + '/i')
        k_d = self.param_serv.get_param('Control/PID/' + self.channel + '/d')

        #Set the max of each channel as the value from the Parameter server

        k_p_disp = "%.3f" % (float(k_p) + 0.10 * float(k_p))
        k_i_disp = "%.3f" % (float(k_i) + 0.10 * float(k_i))
        k_d_disp = "%.3f" % (float(k_d) + 0.10 * float(k_d))

        self.k_p_max_value_line_edit.setText(k_p_disp)
        self.k_i_max_value_line_edit.setText(k_i_disp)
        self.k_d_max_value_line_edit.setText(k_d_disp)

        #Set the precision to the max precision of the
        self.k_p_precision_combobox.setCurrentIndex(3)
        self.k_i_precision_combobox.setCurrentIndex(3)
        self.k_d_precision_combobox.setCurrentIndex(3)

        self._update_PID_precision()

        self._update_gain_displays(k_p, k_i, k_d)
        self._update_sliders(k_p, k_i, k_d)

    def _save_pid_values(self):
        '''
        This is the callback for the save pid values button. When it is pressed,
        it sets the PID gain values currently selected on the sliders/gain displays
        and writes it to the parameter server. Then it tells the navigation controller
        to update these values.

        Parameters:
            N/A

        Returns:
            N/A
        '''

        channel = self.pid_channel_select.currentText()

        #Get the current PID values seen by the sliders/gain displays. Set it
        #to the parameter server.
        k_p = self.k_p_display.text()
        k_i = self.k_i_display.text()
        k_d = self.k_d_display.text()

        self.param_serv.set_param('Control/PID/' + channel + '/p', k_p)
        self.param_serv.set_param('Control/PID/' + channel + '/i', k_i)
        self.param_serv.set_param('Control/PID/' + channel + '/d', k_d)

        time.sleep(0.01)  #Make sure that the parameters are properly sent.

        #Tell the navigation controller/movement controller to update its PIDs

        self.pid_configs_update_publisher.publish(bytes(
            '1', 'utf-8'))  #The value that is sent does not matter
        print("[INFO]: Saving and Updating PID Configurations.")

    def _update_PID_precision(self):
        '''
        This function is the callback for when the desired PID gain floating point
        precision is changed. It allows for the selection of the max p, i, and d values
        for each channel.

        Parameters:
            N/A

        Returns:
            N/A
        '''
        k_p = self.k_p_display.text()
        k_i = self.k_i_display.text()
        k_d = self.k_d_display.text()

        self.max_k_p = float(self.k_p_max_value_line_edit.text())
        self.precision_k_p = float(self.k_p_precision_combobox.currentText())
        self.k_p_slider.setMaximum(self.max_k_p * (1 / self.precision_k_p))

        self.max_k_i = float(self.k_i_max_value_line_edit.text())
        self.precision_k_i = float(self.k_i_precision_combobox.currentText())
        self.k_i_slider.setMaximum(self.max_k_i * (1 / self.precision_k_i))

        self.max_k_d = float(self.k_d_max_value_line_edit.text())
        self.precision_k_d = float(self.k_d_precision_combobox.currentText())
        self.k_d_slider.setMaximum(self.max_k_d * (1 / self.precision_k_d))

        #self._update_gain_displays(k_p, k_i, k_d)
        #self._update_sliders(k_p, k_i, k_d)

    def _update_gains_with_slider(self):
        '''
        This function is the callback called when any of the sliders change in
        value. It will update the gain displays to view what the current gain is
        via number.

        Parameters:
            N/A

        Returns:
            N/A
        '''
        k_p = self.k_p_slider.value() * self.precision_k_p
        k_i = self.k_i_slider.value() * self.precision_k_i
        k_d = self.k_d_slider.value() * self.precision_k_d
        self._update_gain_displays(k_p, k_i, k_d)

    def _update_gain_with_line_edits(self):
        '''
        This function is the callback called when any of the gain displays change in
        value and the enter key is pressed. It will update the slider position to
        view what the current gain isvia number.

        Parameters:
            N/A

        Returns:
            N/A
        '''
        k_p = float(self.k_p_display.text())
        if (k_p > self.max_k_p):
            k_p = self.max_k_p
        k_i = float(self.k_i_display.text())
        if (k_i > self.max_k_i):
            k_i = self.max_k_i
        k_d = float(self.k_d_display.text())
        if (k_d > self.max_k_d):
            k_d = self.max_k_d

        self._update_sliders(k_p, k_i, k_d)
        self._update_gain_displays(k_p, k_i, k_d)

    def _update_gain_displays(self, k_p, k_i, k_d):
        '''
        Set the text for the gain displays.

        Parameters:
            k_p: The proportional gain
            k_i: Integral gain
            k_d: Derivative gain

        Returns:
            N/A
        '''
        self.k_p_display.setText(str(round(float(k_p), 3)))
        self.k_i_display.setText(str(round(float(k_i), 3)))
        self.k_d_display.setText(str(round(float(k_d), 3)))

    def _update_sliders(self, k_p, k_i, k_d):
        '''
        Set the position for the sliders.

        Parameters:
            k_p: The proportional gain
            k_i: Integral gain
            k_d: Derivative gain

        Returns:
            N/A
        '''
        self.k_p_slider.setValue(float(k_p) / self.precision_k_p)
        self.k_i_slider.setValue(float(k_i) / self.precision_k_i)
        self.k_d_slider.setValue(float(k_d) / self.precision_k_d)
Пример #41
0
class SettingMenu(QFrame):

    S_port_info = pyqtSignal(str, str, name='PortInfo')
    S_save_butt_clicked = pyqtSignal(bool, name='SaveButtClicked')
    S_update_ports = pyqtSignal(bool, name="UpdateButtClicked")

    def __init__(self, port, port_speed):
        super().__init__()
        self.setting_info_ = {'Port': port, 'Speed': port_speed}
        self.ports_ = {}
        speeds_ = {
            "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"
        }

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        portEditLabel = QLabel("Port Number:")
        portEditLabel.setObjectName("SettMenuLabel")

        self.portBox = QComboBox()
        self.portBox.addItems(self.ports_)
        self.portBox.setCurrentText(self.setting_info_["Port"])

        speedEditLabel = QLabel("Port Speed: ")
        speedEditLabel.setObjectName("SettMenuLabel")

        self.speedBox = QComboBox()
        self.speedBox.addItems(speeds_)
        self.speedBox.setCurrentText(self.setting_info_["Speed"])

        configSaveButt = QPushButton("SAVE")
        configSaveButt.setObjectName("SettMenuSaveButt")
        configSaveButt.clicked.connect(self.set_port_info)

        updateButt = QPushButton("Update")
        updateButt.clicked.connect(self.act_update_ports)

        hPortBoxLay = QHBoxLayout()

        hPortBoxLay.addWidget(portEditLabel)
        hPortBoxLay.addWidget(self.portBox)
        hPortBoxLay.addSpacing(20)
        hPortBoxLay.addWidget(speedEditLabel)
        hPortBoxLay.addWidget(self.speedBox)
        hPortBoxLay.addStretch()

        saveButtHBoxLay = QHBoxLayout()
        saveButtHBoxLay.addWidget(configSaveButt)

        updateButtHBoxLay = QHBoxLayout()
        updateButtHBoxLay.addWidget(updateButt)

        # Создаем вертикальное пространство
        vBoxLay = QVBoxLayout()
        # Прикрепляем пространство к левому верхнему краю
        vBoxLay.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        vBoxLay.addLayout(hPortBoxLay)
        vBoxLay.addStretch(1)
        vBoxLay.addLayout(saveButtHBoxLay)
        vBoxLay.addLayout(updateButtHBoxLay)

        self.setLayout(vBoxLay)

        self.hide()

    def set_port_info(self):
        self.setting_info_['Port'] = self.portBox.currentText()
        self.setting_info_['Speed'] = self.speedBox.currentText()
        self.S_port_info.emit(self.setting_info_["Port"],
                              self.setting_info_['Speed'])
        self.S_save_butt_clicked.emit(True)

    def update_ports(self, ports):
        print("ports updated")
        self.ports_ = ports
        self.portBox.clear()
        self.portBox.addItems(self.ports_)

    def act_update_ports(self):
        self.S_update_ports.emit(True)
Пример #42
0
 def combo_get(self, combo_name, c: QComboBox):
     if c.currentText():
         return self.combo_substitution_idx[combo_name][c.currentText()]
Пример #43
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.loadDB()
        self.initUI()

    ### 1. DB load ###
    def loadDB(self):
        self.toxic_db, self.msms_db = utils.load_db()

    ### 2. UI initialization ###
    def initUI(self):

        grid = QGridLayout()

        left_grid = QGridLayout()
        self.search_grid = self._create_search_grid()
        self.info_grid = self._create_info_grid()
        self.action_grid = self._create_action_grid()
        left_grid.addWidget(self.search_grid)
        left_grid.addWidget(self.info_grid)
        left_grid.addWidget(self.action_grid)

        right_grid = QGridLayout()
        self.poison_grid = self._create_poison_grid()
        self.mass_grid, self.mass_layout = self._create_mass_grid()
        right_grid.addWidget(self.poison_grid)
        right_grid.addWidget(self.mass_grid)

        grid.addLayout(left_grid, 0, 0, 1, 1)
        grid.addLayout(right_grid, 0, 1, 1, 3)

        ## (Added) Fix the left grid #################
        grid.setColumnStretch(0, 0.1)
        grid.setColumnStretch(1, 2)
        ##############################################

        self.setWindowTitle('TOXMASS 1.0')
        self.setLayout(grid)
        self.center()
        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    # 2.1 Create search grid
    def _create_search_grid(self):
        groupbox = QGroupBox('')

        # Search layout
        search_group = QGroupBox('Search')
        search_layout = QHBoxLayout()

        self.search_type_list = QComboBox()
        self.search_type_list.addItem('CAS')
        self.search_type_list.addItem('IUPAC')
        self.search_type_list.addItem('SMILES')

        search_btn = QPushButton('Search')
        search_btn.clicked.connect(
            self.search_btn_click_event)  # Refer to 2.1.3 function

        self.search_line = QLineEdit('')
        self.search_line.resize(self.search_line.sizeHint())
        self.search_line.returnPressed.connect(
            search_btn.click)  # Refer to 2.1.3 function

        search_layout.addWidget(self.search_type_list)
        search_layout.addWidget(self.search_line)
        search_layout.addWidget(search_btn)
        search_group.setLayout(search_layout)

        # Species layout
        species_group = QGroupBox('Species')
        species_layout = QVBoxLayout()

        self.species_all = QCheckBox('all')
        self.species_all.stateChanged.connect(
            self.species_all_btn_click_event)  # Refer to 2.1.1 function
        self.species_btn1 = QCheckBox('zebra fish')
        self.species_btn2 = QCheckBox('fathead minnow')
        self.species_btn3 = QCheckBox('medaka')
        self.species_btn4 = QCheckBox('daphnia')
        self.species_others = QCheckBox('others')

        species_layout.addWidget(self.species_all)
        species_layout.addWidget(self.species_btn1)
        species_layout.addWidget(self.species_btn2)
        species_layout.addWidget(self.species_btn3)
        species_layout.addWidget(self.species_btn4)
        species_layout.addWidget(self.species_others)
        species_group.setLayout(species_layout)

        # Endpoint layout
        endpoint_group = QGroupBox('End point')
        endpoint_layout = QVBoxLayout()

        self.ep_all = QCheckBox('all')
        self.ep_all.stateChanged.connect(
            self.endpoint_all_btn_click_event)  # Refer to 2.1.2 function
        self.ep_lc_btn = QCheckBox('LC50')
        self.ep_ec_btn = QCheckBox('EC50')
        self.ep_others = QCheckBox('others')

        endpoint_layout.addWidget(self.ep_all)
        endpoint_layout.addWidget(self.ep_lc_btn)
        endpoint_layout.addWidget(self.ep_ec_btn)
        endpoint_layout.addWidget(self.ep_others)
        endpoint_group.setLayout(endpoint_layout)

        vbox = QVBoxLayout()
        vbox.addWidget(search_group)
        vbox.addWidget(species_group)
        vbox.addWidget(endpoint_group)
        groupbox.setLayout(vbox)

        return groupbox

    # 2.2 Create info grid

    def _create_info_grid(self):

        groupbox = QGroupBox('Chemical Information')

        self.info_table = QTableWidget()
        self.info_table.setColumnCount(1)
        self.info_table.horizontalHeader().setVisible(False)
        self.info_table.setRowCount(4)

        self.info_table.setVerticalHeaderLabels(
            ["Name", "IUPAC name", "CAS number", "SMILES"])
        self.info_table.setEditTriggers(QTableWidget.NoEditTriggers)

        vbox = QVBoxLayout()

        vbox.addWidget(self.info_table)
        print("table", self.info_table.size())
        print("vbox", groupbox.size())

        groupbox.setLayout(vbox)
        #        QTableWidget.setMinimumSize(self.info_table, 357, 120)
        self.info_table.setRowHeight(0, groupbox.height() / 16)
        self.info_table.setRowHeight(1, groupbox.height() / 16)
        self.info_table.setRowHeight(2, groupbox.height() / 16)
        self.info_table.setRowHeight(3, groupbox.height() / 16)
        #        self.info_table.setColumnWidth(0, 300)
        QTableWidget.setMinimumSize(self.info_table, 357,
                                    groupbox.height() / 4)
        QTableWidget.setFixedSize(self.info_table, 357, groupbox.height() / 4)

        vbox.addStretch(0.001)

        return groupbox

    def _create_action_grid(self):
        groupbox = QGroupBox(' ')

        action_layout = QHBoxLayout()
        #
        save_btn = QPushButton('Save')
        save_btn.clicked.connect(
            partial(self.file_btn_click_event,
                    clicked_btn='save'))  # Refer to 2.4.1 function
        #
        print_btn = QPushButton('Print')
        print_btn.clicked.connect(
            partial(self.file_btn_click_event,
                    clicked_btn='print'))  # Refer to 2.4.1 function
        #
        action_layout.addWidget(save_btn)
        action_layout.addWidget(print_btn)
        groupbox.setLayout(action_layout)
        return groupbox

    # 2.3 Create poison grid
    def _create_poison_grid(self):
        groupbox = QGroupBox('')

        self.poison_text = QTextEdit('')
        self.poison_text.setReadOnly(True)

        vbox = QVBoxLayout()
        vbox.addWidget(self.poison_text)
        groupbox.setLayout(vbox)

        return groupbox

    # 2.4 Create mass grid
    def _create_mass_grid(self):
        groupbox = QGroupBox('')

        mass_layout = QVBoxLayout()

        self.mass_fig = plt.Figure()
        self.mass_canvas = FigureCanvas(self.mass_fig)

        self.mass_fig.clear()
        ax = self.mass_fig.add_subplot(111)
        ax.set_yticks([0, 20, 40, 60, 80, 100])
        ax.set_xlabel('m/z')
        ax.set_ylabel('Intensity')
        plt.tight_layout()
        self.mass_canvas.draw()

        # Create reference line
        self.reference_line = QLineEdit('')
        self.reference_line.setReadOnly(True)

        # Create save and print button
        #        self.save_print_group = QGroupBox('')
        #        save_print_layout = QHBoxLayout()

        #        info_btn = QPushButton('Info')
        #        info_btn.clicked.connect(partial(self.file_btn_click_event, clicked_btn='info'))

        #        save_btn = QPushButton('Save')
        #        save_btn.clicked.connect(partial(self.file_btn_click_event, clicked_btn='save'))  # Refer to 2.4.1 function

        #        print_btn = QPushButton('Print')
        #        print_btn.clicked.connect(partial(self.file_btn_click_event, clicked_btn='print'))  # Refer to 2.4.1 function

        #        save_print_layout.addWidget(info_btn)
        #        save_print_layout.addWidget(save_btn)
        #        save_print_layout.addWidget(print_btn)
        #        self.save_print_group.setLayout(save_print_layout)

        mass_layout.addWidget(self.mass_canvas)
        mass_layout.addWidget(self.reference_line)
        #       mass_layout.addWidget(self.save_print_group)
        groupbox.setLayout(mass_layout)

        return groupbox, mass_layout

    # 2.1.1 Connect species all button click event
    def species_all_btn_click_event(self):
        if self.species_all.isChecked():
            self.species_btn1.setChecked(True)
            self.species_btn2.setChecked(True)
            self.species_btn3.setChecked(True)
            self.species_btn4.setChecked(True)
            self.species_others.setChecked(True)

            self.species_btn1.setEnabled(False)
            self.species_btn2.setEnabled(False)
            self.species_btn3.setEnabled(False)
            self.species_btn4.setEnabled(False)
            self.species_others.setEnabled(False)

        else:
            self.species_btn1.setChecked(False)
            self.species_btn2.setChecked(False)
            self.species_btn3.setChecked(False)
            self.species_btn4.setChecked(False)
            self.species_others.setChecked(False)

            self.species_btn1.setEnabled(True)
            self.species_btn2.setEnabled(True)
            self.species_btn3.setEnabled(True)
            self.species_btn4.setEnabled(True)
            self.species_others.setEnabled(True)

    # 2.1.2 Connect endpoint all button click event
    def endpoint_all_btn_click_event(self):
        if self.ep_all.isChecked():
            self.ep_lc_btn.setChecked(True)
            self.ep_ec_btn.setChecked(True)
            self.ep_others.setChecked(True)

            self.ep_lc_btn.setEnabled(False)
            self.ep_ec_btn.setEnabled(False)
            self.ep_others.setEnabled(False)

        else:
            self.ep_lc_btn.setChecked(False)
            self.ep_ec_btn.setChecked(False)
            self.ep_others.setChecked(False)

            self.ep_lc_btn.setEnabled(True)
            self.ep_ec_btn.setEnabled(True)
            self.ep_others.setEnabled(True)

    # 2.1.3 Connect species all button click event
    def search_btn_click_event(self):
        ### related to search grid ###
        df = self.toxic_db
        searched_type = str(self.search_type_list.currentText())
        searched_input = self.search_line.text().replace(' ', '')

        if searched_type == 'CAS':
            try:
                searched_cid = df[list(
                    map(lambda f: searched_input in f,
                        df['CAS']))]['cid'].item()
            except:
                QMessageBox.about(
                    self, "No results found.",
                    "We do not have any datas for \"{}\"".format(
                        searched_input))
                return
        elif searched_type == 'IUPAC':
            try:
                searched_cid = df[df['IUPAC'] == searched_input]['cid'].item()
            except:
                QMessageBox.about(
                    self, "No results found.",
                    "We do not have any datas for \"{}\"".format(
                        searched_input))
                return
        elif searched_type == 'SMILES':
            try:
                searched_cid = df[df['SMILES'] == searched_input]['cid'].item()
            except:
                QMessageBox.about(
                    self, "No results found.",
                    "We do not have any datas for \"{}\"".format(
                        searched_input))
                return
        else:
            QMessageBox.about(
                self, "Error",
                "Please select search type (CAS, IUPAC, or SMILES)")
            return

        ### related to info grid ###
        searched_data = df[df['cid'] == searched_cid]
        cas = searched_data['CAS'].item()
        iupac_name = searched_data['IUPAC'].item()
        smiles = searched_data['SMILES'].item()
        name, all_poison_list = utils.load_poison_info(searched_cid)

        self.info_table.setItem(0, 0, QTableWidgetItem(name))
        self.info_table.setItem(1, 0, QTableWidgetItem(iupac_name))
        self.info_table.setItem(2, 0, QTableWidgetItem(', '.join(cas)))
        self.info_table.setItem(3, 0, QTableWidgetItem(smiles))
        self.info_table.resizeColumnsToContents()

        ### related to poison grid ###
        if not self.species_all.isChecked() \
                and not self.species_btn1.isChecked() \
                and not self.species_btn2.isChecked() \
                and not self.species_btn3.isChecked() \
                and not self.species_btn4.isChecked() \
                and not self.species_others.isChecked():
            self.species_all.setChecked(True)

        if not self.ep_all.isChecked() \
                and not self.ep_lc_btn.isChecked() \
                and not self.ep_ec_btn.isChecked() \
                and not self.ep_others.isChecked():
            self.ep_all.setChecked(True)

        filtered_poison_list = []

        if self.species_all.isChecked() and self.ep_all.isChecked():
            filtered_poison_list = all_poison_list
        elif self.species_all.isChecked() and not self.ep_all.isChecked():
            if self.ep_lc_btn.isChecked():
                filtered_poison_list += [
                    p for p in all_poison_list if 'LC50' in p
                ]
            if self.ep_ec_btn.isChecked():
                filtered_poison_list += [
                    p for p in all_poison_list if 'EC50' in p
                ]
            if self.ep_others.isChecked():
                filtered_poison_list += [
                    p for p in all_poison_list
                    if not 'LC50' in p and not 'EC50' in p
                ]
        elif not self.species_all.isChecked() and self.ep_all.isChecked():
            if self.species_btn1.isChecked():
                filtered_poison_list += [p for p in all_poison_list if 'zebra fish' in p.lower() or \
                                         'zebrafish' in p.lower() or \
                                         'danio rerio' in p.lower()]
            if self.species_btn2.isChecked():
                filtered_poison_list += [p for p in all_poison_list if 'fathead minnow' in p.lower() or \
                                         'pimephales promelas' in p.lower()]
            if self.species_btn3.isChecked():
                filtered_poison_list += [p for p in all_poison_list if 'medaka' in p.lower() or \
                                         'oryzias latipes' in p.lower()]
            if self.species_btn4.isChecked():
                filtered_poison_list += [
                    p for p in all_poison_list if 'daphnia' in p.lower()
                ]
            if self.species_others.isChecked():
                filtered_poison_list += [p for p in all_poison_list if 'zebra fish' not in p.lower() and \
                                         'zebrafish' not in p.lower() and \
                                         'danio rerio' not in p.lower() and \
                                         'fathead minnow' not in p.lower() and \
                                         'pimephales promelas' not in p.lower() and \
                                         'medaka' not in p.lower() and \
                                         'oryzias latipes' not in p.lower() and \
                                         'daphnia' not in p.lower()]
        else:
            ep_filtered_poison_list = []
            if self.ep_lc_btn.isChecked():
                ep_filtered_poison_list += [
                    p for p in all_poison_list if 'LC50' in p
                ]
            if self.ep_ec_btn.isChecked():
                ep_filtered_poison_list += [
                    p for p in all_poison_list if 'EC50' in p
                ]
            if self.ep_others.isChecked():
                ep_filtered_poison_list += [
                    p for p in all_poison_list
                    if not 'LC50' in p and not 'EC50' in p
                ]

            if self.species_btn1.isChecked():
                filtered_poison_list += [p for p in ep_filtered_poison_list if 'zebra fish' in p.lower() or \
                                         'zebrafish' in p.lower() or \
                                         'danio rerio' in p.lower()]
            if self.species_btn2.isChecked():
                filtered_poison_list += [p for p in ep_filtered_poison_list if 'fathead minnow' in p.lower() or \
                                         'pimephales promelas' in p.lower()]
            if self.species_btn3.isChecked():
                filtered_poison_list += [p for p in ep_filtered_poison_list if 'medaka' in p.lower() or \
                                         'oryzias latipes' in p.lower()]
            if self.species_btn4.isChecked():
                filtered_poison_list += [
                    p for p in ep_filtered_poison_list
                    if 'daphnia' in p.lower()
                ]
            if self.species_others.isChecked():
                filtered_poison_list += [p for p in ep_filtered_poison_list if 'zebra fish' not in p.lower() and \
                                         'zebrafish' not in p.lower() and \
                                         'danio rerio' not in p.lower() and \
                                         'fathead minnow' not in p.lower() and \
                                         'pimephales promelas' not in p.lower() and \
                                         'medaka' not in p.lower() and \
                                         'oryzias latipes' not in p.lower() and \
                                         'daphnia' not in p.lower()]

        filtered_poison_list = ['    ●  ' + f for f in filtered_poison_list]
        poison_text = 'pubchem.{}'.format(searched_cid) + '\n\n' + '\n\n'.join(
            filtered_poison_list)
        self.poison_text.setText(poison_text)

        ### related to mass grid ###
        try:
            searched_msms_data = self.msms_db[smiles][0]['spectrum']
            self.mz_array = [
                float(d.split(':')[0]) for d in searched_msms_data.split(' ')
            ]
            self.intensity_array = [
                float(d.split(':')[1]) for d in searched_msms_data.split(' ')
            ]

            self.mass_fig.clear()
            ax = self.mass_fig.add_subplot(111)
            ax = utils.plot_mass(ax, self.mz_array, self.intensity_array)
            self.mass_canvas.draw()

            reference = self.msms_db[smiles][0]['library']['link']
            self.reference_line.setText(reference)
        except:
            self.mass_fig.clear()
            ax = self.mass_fig.add_subplot(111)
            ax.set_yticks([0, 20, 40, 60, 80, 100])
            ax.set_xlabel('m/z')
            ax.set_ylabel('Intensity')
            plt.tight_layout()
            self.mass_canvas.draw()

            self.reference_line.setText('')
            QMessageBox.about(
                self, "Error",
                "There is no database corresponding to the {} in the mass spectrum DB"
                .format(smiles))
            return

    # 2.4.1 Connect save/print button click event
    def file_btn_click_event(self, clicked_btn):
        name = self.info_table.item(0, 0)
        if name is None:
            QMessageBox.about(self, "Error", "There is no searching history")
            return

        # search information
        searched_type = str(self.search_type_list.currentText())
        searched_input = self.search_line.text()

        selected_species = []
        if self.species_all.isChecked():
            selected_species.append('all')
        else:
            if self.species_btn1.isChecked():
                selected_species.append('zebra fish')
            if self.species_btn2.isChecked():
                selected_species.append('fathead minnow')
            if self.species_btn3.isChecked():
                selected_species.append('medaka')
            if self.species_btn4.isChecked():
                selected_species.append('daphnia')
            if self.species_others.isChecked():
                selected_species.append('others')
        selected_species = ', '.join(selected_species)

        selected_ep = []
        if self.ep_all.isChecked():
            selected_ep.append('all')
        else:
            if self.ep_lc_btn.isChecked():
                selected_ep.append('LC50')
            if self.ep_ec_btn.isChecked():
                selected_ep.append('EC50')
            if self.ep_others.isChecked():
                selected_ep.append('others')
        selected_ep = ', '.join(selected_ep)

        # chemical information
        name = self.info_table.item(0, 0).text()
        iupac_name = self.info_table.item(1, 0).text()
        cas = self.info_table.item(2, 0).text()
        smiles = self.info_table.item(3, 0).text()

        # toxic information
        poison_text = self.poison_text.toPlainText()

        # mass spectrum
        try:
            self.msms_db[smiles]
            self.mass_fig.savefig('mass_fig.png', dpi=100, bbox_inches='tight')
            reference = self.reference_line.text()
        except:
            pass

        # Make the entire text edit for save/print
        entire_text = QTextEdit('')
        entire_text.append('\n' + '=' * 10 + 'Search Information' + '=' * 10 +
                           '\n')
        entire_text.append('Searched type: {}'.format(searched_type))
        entire_text.append('Searched input: {}'.format(searched_input))
        entire_text.append('Selected species: {}'.format(selected_species))
        entire_text.append('Selected end point: {}'.format(selected_ep))
        entire_text.append('\n' + '=' * 10 + 'Chemical Information' +
                           '=' * 10 + '\n')
        entire_text.append('Name: {}'.format(name))
        entire_text.append('IUPAC name: {}'.format(iupac_name))
        entire_text.append('CAS number: {}'.format(cas))
        entire_text.append('SMILES: {}'.format(smiles))
        entire_text.append('\n' + '=' * 10 + 'Toxic Information' + '=' * 10 +
                           '\n')
        entire_text.append(poison_text)

        try:
            self.msms_db[smiles]
            entire_text.append('\n' + '=' * 10 + 'Mass Spectrum' + '=' * 10 +
                               '\n')
            entire_text.append('reference: {}'.format(reference) + '\n')

            cursor = entire_text.textCursor()
            entire_text.moveCursor(QTextCursor.End)
            cursor.insertImage('mass_fig.png')
        except:
            pass

        if clicked_btn == 'save':
            fn, _ = QFileDialog.getSaveFileName(
                self, 'Export PDF', None, 'PDF files (.pdf);;All Files()')
            if fn != '':
                if QFileInfo(fn).suffix() == "": fn += '.pdf'
                printer = QPrinter(QPrinter.HighResolution)
                printer.setOutputFormat(QPrinter.PdfFormat)
                printer.setOutputFileName(fn)
                entire_text.document().print_(printer)
            try:
                os.remove('mass_fig.png')
            except:
                pass

        elif clicked_btn == 'print':
            printer = QPrinter(QPrinter.HighResolution)
            dialog = QPrintDialog(printer, self)
            if dialog.exec_() == QPrintDialog.Accepted:
                entire_text.print_(printer)
            try:
                os.remove('mass_fig.png')
            except:
                pass
Пример #44
0
class Calculator(QWidget):
    def __init__(self, parent=None):
        super().__init__()

        # 자료처리 관련 함수
        self.dbfilename = 'assignment6.dat'
        self.scoredb = self.readScoreDB()
        self.writeScoreDB()

        # Display Window
        self.display = QLineEdit('0')
        self.display.setReadOnly(True)
        self.display.setAlignment(Qt.AlignRight)
        self.display.setMaxLength(10)

        # Layout
        mainLayout = QGridLayout()
        mainLayout.setSpacing(5)

        self.setLayout(mainLayout)
        self.setGeometry(300, 300, 500, 250)
        self.setWindowTitle("Assignment6")

        # grid1
        self.grid1 = QHBoxLayout()
        # grid2
        self.grid2 = QHBoxLayout()
        self.grid2.addStretch(1)
        self.grid2.setSpacing(10)
        #grid3
        self.grid3 = QHBoxLayout()
        self.grid3.setSpacing(10)
        #grid 4
        self.grid4 = QVBoxLayout()

        # QLabel
        self.name = QLabel('Name: ')
        self.age = QLabel('Age: ')
        self.score = QLabel('Score: ')
        self.amount = QLabel('Amount: ')
        self.key = QLabel('Key: ')
        self.result = QLabel('Result: ')

        # QCombobox
        self.cb = QComboBox()
        self.cb.addItems(["Age", "Name", "Score"])

        # QPushButton
        self.addbtn = QPushButton("Add")
        self.delbtn = QPushButton("Del")
        self.findbtn = QPushButton("Find")
        self.incbtn = QPushButton("Inc")
        self.showbtn = QPushButton("Show")

        #Event

        self.addbtn.clicked.connect(self.addclicked)
        self.delbtn.clicked.connect(self.delclicked)
        self.findbtn.clicked.connect(self.findclicked)
        self.incbtn.clicked.connect(self.incclicked)
        self.showbtn.clicked.connect(self.showclicked)

        # TextEdit
        self.te = QTextEdit()

        # LineEdit
        self.nameEdit = QLineEdit()
        self.ageEdit = QLineEdit()
        self.scoreEdit = QLineEdit()
        self.amountEdit = QLineEdit()

        # grid1 설정
        self.grid1.addWidget(self.name)
        self.grid1.addWidget(self.nameEdit)
        self.grid1.addWidget(self.age)
        self.grid1.addWidget(self.ageEdit)
        self.grid1.addWidget(self.score)
        self.grid1.addWidget(self.scoreEdit)
        self.grid1.setAlignment(Qt.AlignTop)

        # grid2 설정
        self.grid2.addWidget(self.amount)
        self.grid2.addWidget(self.amountEdit)
        self.grid2.addWidget(self.key)
        self.grid2.addWidget(self.cb)

        # grid3 설정
        self.grid3.addWidget(self.addbtn)
        self.grid3.addWidget(self.delbtn)
        self.grid3.addWidget(self.findbtn)
        self.grid3.addWidget(self.incbtn)
        self.grid3.addWidget(self.showbtn)

        #grid4 설정
        self.grid4.addWidget(self.result)
        self.grid4.addWidget(self.te)

        # mainLayout에 배치
        mainLayout.addLayout(self.grid1, 0, 0)
        mainLayout.addLayout(self.grid2, 1, 0)
        mainLayout.addLayout(self.grid3, 2, 0)
        mainLayout.addLayout(self.grid4, 3, 0)

        # Layout
        self.setLayout(mainLayout)
        self.show()

######################## 자료 관련 함수 #####################

    def closeEvent(self, event):
        self.writeScoreDB()

    def readScoreDB(self):
        try:
            fH = open(self.dbfilename, 'rb')
        except FileNotFoundError as e:
            self.scdb = []
            return

        try:
            self.scdb = pickle.load(fH)
        except:
            pass
        else:
            pass
        fH.close()
        return self.scdb

    def writeScoreDB(self):
        fH = open(self.dbfilename, 'wb')
        pickle.dump(self.scoredb, fH)
        fH.close()

    def showScoreDB(self, keyname):
        self.te.clear()
        for p in sorted(self.scdb, key=lambda person: str(person[keyname])):
            for attr in sorted(p):
                last = attr + " = " + str(p[attr]) + "  "
                self.te.insertPlainText(last)
            self.te.append("")


# 버튼 클릭연결

    def addclicked(self):
        self.name = self.nameEdit.text()
        self.age = self.ageEdit.text()
        self.score = self.scoreEdit.text()

        record = {'Name': self.name, 'Age': self.age, 'Score': self.score}
        self.scdb += [record]
        self.showScoreDB('Name')

    def delclicked(self):
        for p in self.scdb:
            if self.nameEdit.text() == p['Name']:
                self.scdb.remove(p)
                self.te.clear()
                self.showScoreDB('Name')

    def findclicked(self):
        self.te.clear()
        for p in self.scdb:
            for p in sorted(self.scdb, key=lambda person: person['Name']):
                if self.nameEdit.text() == p['Name']:
                    for attr in sorted(p):
                        last = attr + " = " + str(p[attr]) + "  "
                        self.te.insertPlainText(last)
            break
            self.te.append("")

    def incclicked(self):
        addamount = int(self.amountEdit.text())

        for p in self.scdb:
            if self.nameEdit.text() == p['Name']:
                p['Score'] += addamount
                self.te.clear()
                self.showScoreDB('Name')
                break

    def showclicked(self):

        self.sortkey = self.cb.currentText()
        self.showScoreDB(self.sortkey)
Пример #45
0
class Simulator(QWidget):
    def __init__(self, *args, **kwargs):
        super(Simulator, self).__init__(*args, **kwargs)
        self.__simulation = SimulationData()

        self.__manage_window()

        self.__create_layouts()

        self.__create_buttons_and_inputs()

        self.__create_canvas()

        self.__manage_layouts()

        self.__connect_buttons()

        self.__set_timer()

        self.__change_initial_configuration()

        self.show()

    def __manage_window(self):
        self.setWindowTitle("2D Wave Equation Simulator")
        self.setFixedSize(1000, 860)

    def __create_layouts(self):
        self.__main_layout = QtWidgets.QVBoxLayout(self)
        self.__form_layout = QFormLayout(self)
        self.__start_stop_layout = QFormLayout(self)

    def __create_buttons_and_inputs(self):
        self.__start_button = QtWidgets.QPushButton("Start simulation", self)
        self.__stop_button = QtWidgets.QPushButton("Stop simulation", self)
        self.__start_button.setFixedWidth(485)
        self.__stop_button.setFixedWidth(485)
        self.__stop_button.setEnabled(False)

        self.__only_float = QRegExpValidator(QRegExp("-?[0-9]+\.?[0-9]+"))
        self.__only_float_time = QRegExpValidator(QRegExp("[0-9]+\.?[0-9]+"))
        self.__only_int = QIntValidator()
        self.__only_int.setBottom(0)
        self.__only_int.setTop(99)

        self.__label1 = QLabel("Number of points (X-axis):")
        self.__line1 = QLineEdit()
        self.__line1.setValidator(self.__only_int)
        self.__line1.setText("25")

        self.__label2 = QLabel("Number of points (Y-axis):")
        self.__line2 = QLineEdit()
        self.__line2.setValidator(self.__only_int)
        self.__line2.setText("25")

        self.__label3 = QLabel("Maximum simulation time [s]:")
        self.__line3 = QLineEdit()
        self.__line3.setValidator(self.__only_float_time)
        self.__line3.setText("1.0")

        self.__label4 = QPushButton("Alpha:")
        self.__label4.setFixedWidth(135)
        self.__line4 = QLineEdit()
        self.__line4.setValidator(self.__only_float)
        self.__line4.setText("0.0")

        self.__label5 = QPushButton("Beta:")
        self.__label5.setFixedWidth(135)
        self.__line5 = QLineEdit()
        self.__line5.setValidator(self.__only_float)
        self.__line5.setText("0.25")

        self.__label6 = QPushButton("Gamma:")
        self.__label6.setFixedWidth(135)
        self.__line6 = QLineEdit()
        self.__line6.setValidator(self.__only_float)
        self.__line6.setText("0.5")

        self.__label7 = QLabel("Fixed boundary conditions:")
        self.__line7 = QComboBox()
        self.__line7.addItems(["True", "False"])

        self.__label8 = QLabel("Zero-displacement initial condition:")
        self.__line8 = QComboBox()
        self.__line8.addItems(["False", "True"])

        self.__label9 = QLabel("Forcing term:")
        self.__line9 = QComboBox()
        self.__line9.addItems(["False", "True"])

    def __create_canvas(self):
        self.__canvas = Canvas(self)
        self.__canvas.setFixedSize(980, 566)

    def __manage_layouts(self):
        self.__form_layout.addRow(self.__label1, self.__line1)
        self.__form_layout.addRow(self.__label2, self.__line2)
        self.__form_layout.addRow(self.__label3, self.__line3)
        self.__form_layout.addRow(self.__label4, self.__line4)
        self.__form_layout.addRow(self.__label5, self.__line5)
        self.__form_layout.addRow(self.__label6, self.__line6)
        self.__form_layout.addRow(self.__label7, self.__line7)
        self.__form_layout.addRow(self.__label8, self.__line8)
        self.__form_layout.addRow(self.__label9, self.__line9)

        self.__start_stop_layout.addRow(self.__start_button,
                                        self.__stop_button)

        self.__main_layout.addWidget(self.__canvas)
        self.__main_layout.addLayout(self.__form_layout)
        self.__main_layout.addLayout(self.__start_stop_layout)

    def __connect_buttons(self):
        self.__start_button.clicked.connect(lambda: self.__start_simulation())
        self.__stop_button.clicked.connect(lambda: self.__stop_simulation())
        self.__label4.clicked.connect(lambda: self.__show_alpha_description())
        self.__label5.clicked.connect(lambda: self.__show_beta_description())
        self.__label6.clicked.connect(lambda: self.__show_gamma_description())
        self.__line1.textChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line2.textChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line3.textChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line4.textChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line5.textChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line6.textChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line7.currentTextChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line8.currentTextChanged.connect(
            lambda: self.__change_initial_configuration())
        self.__line9.currentTextChanged.connect(
            lambda: self.__change_initial_configuration())

    def __show_alpha_description(self):
        title = "Description of Alpha parameter"
        description = "Alpha is the factor responsible for damping the membrane movement"
        self.__show_message(QMessageBox.Information, title, description)

    def __show_beta_description(self):
        title = "Description of Beta parameter"
        description = "Beta is the scalar parameter of the Newmark algorithm"
        self.__show_message(QMessageBox.Information, title, description)

    def __show_gamma_description(self):
        title = "Description of Gamma parameter"
        description = "Gamma is the scalar parameter of the Newmark algorithm"
        self.__show_message(QMessageBox.Information, title, description)

    def __show_message(self, message_type, title, description):
        self.__msg = QMessageBox()
        self.__msg.setIcon(message_type)
        self.__msg.setWindowTitle(title)
        self.__msg.setText(description)
        self.__msg.exec_()

    def __disable_gui(self):
        self.__stop_button.setEnabled(True)
        self.__start_button.setEnabled(False)
        self.__line1.setEnabled(False)
        self.__line2.setEnabled(False)
        self.__line3.setEnabled(False)
        self.__line4.setEnabled(False)
        self.__line5.setEnabled(False)
        self.__line6.setEnabled(False)
        self.__line7.setEnabled(False)
        self.__line8.setEnabled(False)
        self.__line9.setEnabled(False)
        self.__label4.setEnabled(False)
        self.__label5.setEnabled(False)
        self.__label6.setEnabled(False)

    def __enable_gui(self):
        self.__stop_button.setEnabled(False)
        self.__start_button.setEnabled(True)
        self.__line1.setEnabled(True)
        self.__line2.setEnabled(True)
        self.__line3.setEnabled(True)
        self.__line4.setEnabled(True)
        self.__line5.setEnabled(True)
        self.__line6.setEnabled(True)
        self.__line7.setEnabled(True)
        self.__line8.setEnabled(True)
        self.__line9.setEnabled(True)
        self.__label4.setEnabled(True)
        self.__label5.setEnabled(True)
        self.__label6.setEnabled(True)

    def __set_timer(self):
        self.__timer = QtCore.QTimer()
        self.__timer.setInterval(100)
        self.__timer.timeout.connect(self.__continue_simulation)

    def __change_initial_configuration(self):
        try:
            self.__n_x = int(self.__line1.text())
            self.__n_y = int(self.__line2.text())
        except:
            return

        if self.__n_x < 3 or self.__n_y < 3:
            return

        if self.__line8.currentText() == "False":
            self.__zero_diaphragm_displacement = False
        elif self.__line8.currentText() == "True":
            self.__zero_diaphragm_displacement = True

        self.__x_net = np.zeros(self.__n_x * self.__n_y, dtype=np.float64)
        self.__y_net = np.zeros(self.__n_x * self.__n_y, dtype=np.float64)

        for j in range(self.__n_y):
            for i in range(self.__n_x):
                self.__x_net[j * self.__n_x + i] = i * 1.0 / self.__n_x
                self.__y_net[j * self.__n_x + i] = j * 1.0 / self.__n_y

        first_step = self.__simulation.get_first_step(
            self.__n_x, self.__n_y, self.__zero_diaphragm_displacement)

        self.__max_value = first_step.max() + 0.0001
        self.__min_value = -self.__max_value

        self.__canvas.axes.cla()
        self.__canvas.axes.set_xlabel("x [m]")
        self.__canvas.axes.set_ylabel("y [m]")
        self.__canvas.axes.set_zlabel("u [m]")
        if not self.__zero_diaphragm_displacement:
            self.__canvas.axes.set_zlim(self.__min_value, self.__max_value)
        else:
            self.__canvas.axes.set_zlim(-0.075, 0.075)

        self.__canvas.axes.set_title(
            "Diaphragm displacement diagram u(x, y, t) \n t = 0.0 s")
        self.__canvas.axes.scatter(self.__x_net,
                                   self.__y_net,
                                   first_step,
                                   linewidth=0,
                                   antialiased=False)
        self.__canvas.draw()

    def __start_simulation(self):
        self.__n_x = int(self.__line1.text())
        self.__n_y = int(self.__line2.text())

        if self.__n_x < 3 or self.__n_y < 3:
            title = "Warning"
            description = "Number of points for X-axis and Y-axis must be at least 3"
            self.__show_message(QMessageBox.Warning, title, description)
            return

        self.__t = float(self.__line3.text())
        self.__alpha = float(self.__line4.text())
        self.__beta = float(self.__line5.text())
        self.__gamma = float(self.__line6.text())

        if self.__line7.currentText() == "False":
            self.__fixed_boundary_conditions = False
        elif self.__line7.currentText() == "True":
            self.__fixed_boundary_conditions = True

        if self.__line8.currentText() == "False":
            self.__zero_diaphragm_displacement = False
        elif self.__line8.currentText() == "True":
            self.__zero_diaphragm_displacement = True

        if self.__line9.currentText() == "False":
            self.__forcing_term_check = False
        elif self.__line9.currentText() == "True":
            self.__forcing_term_check = True

        self.__delta_t = 0.01
        self.__n_t = int(self.__t / self.__delta_t)
        self.__counter = 1

        self.__simulation.change_initial_configuration(
            self.__n_x, self.__n_y, self.__t, self.__alpha, self.__beta,
            self.__gamma, self.__fixed_boundary_conditions,
            self.__zero_diaphragm_displacement, self.__forcing_term_check)

        self.__disable_gui()

        self.__simulation.start_simulation()

        self.__canvas.axes.cla()
        self.__canvas.axes.set_xlabel("x [m]")
        self.__canvas.axes.set_ylabel("y [m]")
        self.__canvas.axes.set_zlabel("u [m]")
        if not self.__zero_diaphragm_displacement:
            self.__canvas.axes.set_zlim(self.__min_value, self.__max_value)
        else:
            self.__canvas.axes.set_zlim(-0.075, 0.075)

        self.__canvas.axes.set_title(
            "Diaphragm displacement diagram u(x, y, t) \n t = 0.0 s")
        self.__canvas.axes.scatter(self.__x_net,
                                   self.__y_net,
                                   self.__simulation.get_actual_step(),
                                   linewidth=0,
                                   antialiased=False)
        self.__canvas.draw()

        self.__timer.start()

    def __continue_simulation(self):
        self.__canvas.axes.cla()
        self.__canvas.axes.set_xlabel("x [m]")
        self.__canvas.axes.set_ylabel("y [m]")
        self.__canvas.axes.set_zlabel("u [m]")
        if not self.__forcing_term_check:
            self.__canvas.axes.set_zlim(self.__min_value, self.__max_value)
        else:
            if self.__fixed_boundary_conditions or self.__simulation.get_actual_step(
            ).mean() < 0.05:
                self.__canvas.axes.set_zlim(-0.075, 0.075)
        self.__canvas.axes.set_title(
            "Diaphragm displacement diagram u(x, y, t) \n t = " +
            str(round(self.__counter * self.__delta_t, 2)) + " s")
        self.__canvas.axes.scatter(self.__x_net,
                                   self.__y_net,
                                   self.__simulation.get_actual_step(),
                                   linewidth=0,
                                   antialiased=False)
        self.__canvas.draw()
        if self.__counter < self.__n_t:
            self.__counter += 1
            self.__simulation.calculate_next_step(self.__counter)
        else:
            self.__stop_simulation()

    def __stop_simulation(self):
        self.__timer.stop()
        self.__enable_gui()
Пример #46
0
class FilterEditor(QWidget):
    def __init__(self, parent: QWidget = None):
        super(FilterEditor, self).__init__(parent)

        self.__history = None

        self.__sources = []
        self.__includes = []
        self.__excludes = []

        self.__combo_focus = QComboBox()
        self.__list_source = EasyQListSuite()
        self.__list_include = EasyQListSuite()
        self.__list_exclude = EasyQListSuite()

        self.__button_save_filter = QPushButton('Save')
        self.__button_load_filter = QPushButton('Load')
        self.__button_check_match = QPushButton('Check')
        self.__button_gen_index = QPushButton('Generate Index')

        self.__init_ui()
        self.__config_ui()

    def get_filter(self):
        pass

    def set_filter(self):
        pass

    def set_history_core(self, history: History):
        self.__history = history

    # --------------------------------------------- Private ---------------------------------------------

    def __init_ui(self):
        main_layout = QVBoxLayout()
        self.setLayout(main_layout)

        group, layout = create_v_group_box('Source Selector')
        layout.addWidget(self.__list_source)
        main_layout.addWidget(group)

        group_in, layout_in = create_v_group_box('Include Label Tags')
        group_ex, layout_ex = create_v_group_box('Exclude Label Tags')
        layout_in.addWidget(self.__list_include)
        layout_ex.addWidget(self.__list_exclude)
        main_layout.addLayout(horizon_layout([group_in, group_ex]))

        group, layout = create_v_group_box('Focus Label')
        layout.addWidget(self.__combo_focus)
        main_layout.addWidget(group)

        main_layout.addLayout(horizon_layout([self.__button_save_filter,
                                              self.__button_load_filter,
                                              self.__button_check_match,
                                              self.__button_gen_index]))

    def __config_ui(self):
        self.__combo_focus.setEditable(True)
        self.__combo_focus.addItem('')
        self.__combo_focus.addItem('event')
        self.__combo_focus.addItem('people')
        self.__combo_focus.addItem('location')
        self.__combo_focus.addItem('organization')

        self.__list_source.set_add_handler(self.__on_source_add)
        self.__list_source.set_remove_handler(self.__on_source_remove)

        self.__list_include.set_add_handler(self.__on_include_add)
        self.__list_include.set_remove_handler(self.__on_include_remove)

        self.__list_exclude.set_add_handler(self.__on_exclude_add)
        self.__list_exclude.set_remove_handler(self.__on_exclude_remove)

        self.__button_save_filter.clicked.connect(self.__on_btn_click_save)
        self.__button_load_filter.clicked.connect(self.__on_btn_click_load)
        self.__button_check_match.clicked.connect(self.__on_btn_click_chk)
        self.__button_gen_index.clicked.connect(self.__on_btn_click_gen)

    # ---------------------------------------------------------------

    def __on_source_add(self):
        root_path = HistoricalRecordLoader.get_local_depot_root()
        fname, ftype = QFileDialog.getOpenFileNames(self,
                                                    'Select History Files',
                                                    root_path,
                                                    'History Files (*.his)')
        fname = [f[len(root_path):] if f.startswith(root_path) else f for f in fname]
        self.__sources.extend(fname)
        self.__sources = list(set(self.__sources))
        self.__list_source.update_item([(s, s) for s in self.__sources])

    def __on_source_remove(self):
        items = self.__list_source.get_select_items()
        for item in items:
            self.__sources.remove(item)
        self.__list_source.update_item([(s, s) for s in self.__sources])

    def __on_include_add(self):
        text, ok = QInputDialog.getText(self, 'Include Tags', 'Include: ', QLineEdit.Normal, '')
        if not ok:
            return
        self.__includes.append(text)
        self.__includes = list(set(self.__includes))
        self.__list_include.update_item([(s, s) for s in self.__includes])

    def __on_include_remove(self):
        items = self.__list_include.get_select_items()
        for item in items:
            self.__includes.remove(item)
        self.__list_include.update_item([(s, s) for s in self.__includes])

    def __on_exclude_add(self):
        text, ok = QInputDialog.getText(self, 'Exclude Tags', 'Exclude: ', QLineEdit.Normal, '')
        if not ok:
            return
        self.__excludes.append(text)
        self.__excludes = list(set(self.__excludes))
        self.__list_exclude.update_item([(s, s) for s in self.__excludes])

    def __on_exclude_remove(self):
        items = self.__list_exclude.get_select_items()
        for item in items:
            self.__excludes.remove(item)
        self.__list_exclude.update_item([(s, s) for s in self.__excludes])

    # ---------------------------------------------------------------

    def __on_btn_click_save(self):
        fileName_choose, filetype = QFileDialog.getSaveFileName(self,
                                                                'Save Filter',
                                                                HistoricalRecordLoader.get_local_depot_root(),
                                                                'Filter Files (*.hisfilter)')
        if fileName_choose == '':
            return

        his_filter = self.ui_to_filter()
        text = his_filter.dump_text()

        with open(fileName_choose, 'wt') as f:
            f.write(text)

    def __on_btn_click_load(self):
        fileName_choose, filetype = QFileDialog.getOpenFileName(self,
                                                                'Load Filter',
                                                                HistoricalRecordLoader.get_local_depot_root(),
                                                                'Filter Files (*.hisfilter)')
        if fileName_choose == '':
            return

        with open(fileName_choose, 'rt') as f:
            text = f.read()

        parser = LabelTagParser()
        if not parser.parse(text):
            print('Load from (' + fileName_choose + ') failed.')
            return

        his_filter = HistoricalFilter()
        his_filter.attach(parser.get_label_tags())

        self.filter_to_ui(his_filter)

    def __on_btn_click_chk(self):
        pass

    def __on_btn_click_gen(self):
        fileName_choose, filetype = QFileDialog.getSaveFileName(self,
                                                                'Generate Index',
                                                                HistoricalRecordLoader.get_local_depot_root(),
                                                                'Filter Files (*.index)')
        if fileName_choose == '':
            return

        records = self.load_filter_records()
        indexer = HistoricalRecordIndexer()
        indexer.index_records(records)
        indexer.dump_to_file(fileName_choose)

        QMessageBox.information(self, 'Generate Done', 'Generate index for ' + str(len(records)) + ' records Done.')

    # ---------------------------------------------------------------

    def filter_to_ui(self, his_filter: HistoricalFilter):
        self.__combo_focus.setCurrentText(his_filter.get_focus_label())

        self.__sources = his_filter.get_sources()
        self.__includes = self.__label_tag_dict_to_text(his_filter.get_include_tags())
        self.__excludes = self.__label_tag_dict_to_text(his_filter.get_exclude_tags())

        self.__list_source.update_item([(s, s) for s in self.__sources])
        self.__list_include.update_item([(s, s) for s in self.__includes])
        self.__list_exclude.update_item([(s, s) for s in self.__excludes])

    def ui_to_filter(self) -> HistoricalFilter:
        his_filter = HistoricalFilter()
        his_filter.set_sources(self.__sources)
        his_filter.set_focus_label(self.__combo_focus.currentText())
        his_filter.set_include_tags_str(self.__includes)
        his_filter.set_exclude_tags_str(self.__excludes)
        return his_filter

    def load_source_records(self) -> [HistoricalRecord]:
        records = []
        for source in self.__sources:
            loader = HistoricalRecordLoader()
            if path.isabs(source):
                ret = loader.from_file(source)
            else:
                ret = loader.from_source(source)
            if not ret:
                continue
            records.extend(loader.get_loaded_records())
        return records

    def load_filter_records(self) -> [HistoricalRecord]:
        history = self.__history if self.__history is not None else History()

        records = self.load_source_records()
        history.set_records(records)

        his_filter = self.ui_to_filter()
        return history.select_records(sources=his_filter.get_sources(),
                                      focus_label=his_filter.get_focus_label(),
                                      include_label_tags=his_filter.get_include_tags(), include_all=False,
                                      exclude_label_tags=his_filter.get_exclude_tags(), exclude_any=True)

    def __label_tag_dict_to_text(self, label_tags_dict: dict):
        return [key + ': ' + ', '.join(label_tags_dict[key]) for key in label_tags_dict.keys()]
Пример #47
0
class calcGui(QMainWindow): # QMainWindow Class for the calculator GUI

    def __init__(self):
        super().__init__()
        #self.setStyleSheet(open('css/style.css').read())
        self.model = evaluateProblem
        self.cc = CalcController(self.model, self)

        # Set Main Window Title
        self.setWindowTitle("Calculator")
        #Setting the main widget and the layout that will be used for the calculator
        self.mainWidget = QWidget(self)
        self.setCentralWidget(self.mainWidget)
        #Main layout for the window
        self.mainLayout = QVBoxLayout()
        #Put the two dropdowns side by side in horizontal layout
        self.selectionLayout = QHBoxLayout()
        #Grid layout for the buttons
        self.buttonsGrid = QGridLayout()
        #set layout for the widget
        self.mainWidget.setLayout(self.mainLayout)
    
        #create the buttons, dropdown, screen, etc.
        self.createDisplay()
        self.createDropDowns()
        self.createInitialButtons()
        
        #self.color_message = QLabel("Welcome to Calculator.")

        #Create the coloring options section
        #self.coloring_options.addWidget(self.color_message)

        
    def createDropDowns(self):
        
        #dropdown for calculator mode
        self.modeDropDown = QVBoxLayout()
        self.selectModeLabel = QLabel("Select Mode")
        calcType = ["Basic", "Scientific", "Subnet"]
        self.choose_calc = QComboBox()
        self.choose_calc.setFixedHeight(40)
        self.choose_calc.addItems(calcType)
        self.choose_calc.currentIndexChanged.connect(self.calc_chosen)
        self.modeDropDown.addWidget(self.selectModeLabel)
        self.modeDropDown.addWidget(self.choose_calc)
        self.selectionLayout.addLayout(self.modeDropDown)
        
        #dropdown for color theme
        self.colorDropDown = QVBoxLayout()
        self.selectColorLabel = QLabel("Select Theme")
        calcTheme = ["Default", "Peanut Butter Mood", "Orange Berry Blitz!", "Watermelon Breeze", "Razzmatazz", "BananaBerry"]
        self.choose_theme = QComboBox()
        self.choose_theme.setFixedHeight(40)
        self.choose_theme.addItems(calcTheme)
        self.choose_theme.currentIndexChanged.connect(self.theme_chosen)
        self.colorDropDown.addWidget(self.selectColorLabel)
        self.colorDropDown.addWidget(self.choose_theme)
        self.selectionLayout.addLayout(self.colorDropDown)
        
        #add the dropdowns horizontal layout to the main layout
        self.mainLayout.addLayout(self.selectionLayout)

        
    def createDisplay(self):
        # Create the display widget
        self.display = QTextEdit()
        # Set some display's properties
        self.display.setFixedHeight(60)
        self.display.setAlignment(Qt.AlignRight)
        # Add the display to the main layout
        self.mainLayout.addWidget(self.display)

    @pyqtSlot()
    def theme_chosen(self):
        calcChosen = self.choose_calc.currentText()
        themeChosen = self.choose_theme.currentText()
        
        if(themeChosen == 'Default'):
            self.setStyleSheet("")
            
        elif(themeChosen == 'Peanut Butter Mood'):
            self.setStyleSheet(open('css/style.css').read())
            
        elif themeChosen == 'Orange Berry Blitz!':
            self.setStyleSheet(open('css/style2.css').read())
            
        elif themeChosen == 'Watermelon Breeze':
            self.setStyleSheet(open('css/style3.css').read())
            
        elif themeChosen == 'Razzmatazz':
            self.setStyleSheet(open('css/style4.css').read())
        
        elif themeChosen == 'BananaBerry':
            self.setStyleSheet(open('css/style5.css').read())



    @pyqtSlot()
    def calc_chosen(self):
        calcChosen = self.choose_calc.currentText()
        
        if(calcChosen == 'Basic'):
        
            self.setWindowTitle('Basic Calculator')
            self.display.setFixedHeight(60)
            self.destroyButtons()
            self.clearDisplay()
            self.createBasicButtons()
            
        elif calcChosen == 'Scientific':
            self.setWindowTitle('Scientific Calculator')
            self.destroyButtons()
            self.clearDisplay()
            self.createScientificButtons()
        elif calcChosen == 'Subnet':
            self.setWindowTitle('Subnet Calculator')
            self.display.setFixedHeight(180)
            self.destroyButtons()
            self.createSubnetButtons()
            self.clearDisplay()
            
            
            
    def setDisplayText(self, text):
        self.display.setText(text)
        self.display.repaint()
        
    def getDisplayText(self):
        """Get display's text."""
        displayText = self.display.toPlainText()
        return displayText

    def clearDisplay(self):
        """Clear the display."""
        self.setDisplayText("")
        
    @pyqtSlot()
    def destroyButtons(self):
        for i in reversed(range(self.buttonsGrid.count())):
            widgetToRemove = self.buttonsGrid.itemAt(i).widget()
            # remove it from the layout list
            self.buttonsGrid.removeWidget(widgetToRemove)
            # remove it from the gui
            widgetToRemove.setParent(None)
    
    def createInitialButtons(self):
        """Create the buttons."""
        self.buttons = {}
        # Button text | position on the QGridLayout
        buttons = {
            "7": (0, 0),
            "8": (0, 1),
            "9": (0, 2),
            "/": (0, 3),
            "C": (0, 4),
            "4": (1, 0),
            "5": (1, 1),
            "6": (1, 2),
            "*": (1, 3),
            "(": (1, 4),
            "1": (2, 0),
            "2": (2, 1),
            "3": (2, 2),
            "-": (2, 3),
            ")": (2, 4),
            "0": (3, 0),
            "00": (3, 1),
            ".": (3, 2),
            "+": (3, 3),
            "=": (3, 4),
        }
        # Create the buttons and add them to the button grid layout
        for btnText, pos in buttons.items():
            self.buttons[btnText] = QPushButton(btnText)
            self.buttons[btnText].setFixedSize(80, 80)
            self.buttonsGrid.addWidget(self.buttons[btnText], pos[0], pos[1])
            

        # Add buttonsGrid to the Main layout
        self.mainLayout.addLayout(self.buttonsGrid)
        self.cc.connectButtons()
        self.buttons["="].clicked.connect(self.cc._calculateResult)

    
    @pyqtSlot()
    def createBasicButtons(self):
        """Create the buttons."""
        self.buttons = {}
        #buttonsGrid = QGridLayout()
        # Button text | position on the QGridLayout
        buttons = {
            "7": (0, 0),
            "8": (0, 1),
            "9": (0, 2),
            "/": (0, 3),
            "C": (0, 4),
            "4": (1, 0),
            "5": (1, 1),
            "6": (1, 2),
            "*": (1, 3),
            "(": (1, 4),
            "1": (2, 0),
            "2": (2, 1),
            "3": (2, 2),
            "-": (2, 3),
            ")": (2, 4),
            "0": (3, 0),
            "00": (3, 1),
            ".": (3, 2),
            "+": (3, 3),
            "=": (3, 4),
        }
        # Create the buttons and add them to the button grid layout
        for btnText, pos in buttons.items():
            self.buttons[btnText] = QPushButton(btnText)
            self.buttons[btnText].setFixedSize(80, 80)
            self.buttonsGrid.addWidget(self.buttons[btnText], pos[0], pos[1])
            
        self.cc.connectButtons()
        self.buttons["="].clicked.connect(self.cc._calculateResult)

    @pyqtSlot()
    def createScientificButtons(self):
        """Create the buttons."""
        self.buttons = {}
        #buttonsGrid = QGridLayout()
        # Button text | position on the QGridLayout
        buttons = {
            "π": (0,0),
            "√": (0,1),
            "log": (0,2),
            "ln": (0,3),
            "e": (0,4),
            "%": (0,5),
            "7": (1, 0),
            "8": (1, 1),
            "9": (1, 2),
            "sin": (1,3),
            "/": (1, 4),
            "C": (1, 5),
            "4": (2, 0),
            "5": (2, 1),
            "6": (2, 2),
            "cos": (2,3),
            "*": (2, 4),
            "(": (2, 5),
            "1": (3, 0),
            "2": (3, 1),
            "3": (3, 2),
            "tan": (3,3),
            "-": (3, 4),
            ")": (3, 5),
            "0": (4, 0),
            "00": (4, 1),
            ".": (4, 2),
            "^": (4,3),
            "+": (4, 4),
            "=": (4, 5),
            
        }
        # Create the buttons and add them to the button grid layout
        for btnText, pos in buttons.items():
            self.buttons[btnText] = QPushButton(btnText)
            self.buttons[btnText].setFixedSize(80, 80)
            self.buttonsGrid.addWidget(self.buttons[btnText], pos[0], pos[1])
            
        self.cc.connectButtons()
        self.buttons["="].clicked.connect(self.cc._calculateResult)
        #self.buttons
        
    @pyqtSlot()
    def createSubnetButtons(self):
        """Create the buttons."""
        self.buttons = {}
        # Button text | position on the QGridLayout
        buttons = {
            "7": (0, 0),
            "8": (0, 1),
            "9": (0, 2),
            "/": (0, 3),
            "C": (0, 4),
            "4": (1, 0),
            "5": (1, 1),
            "6": (1, 2),
            "0": (1, 3),
            "00": (1, 4),
            "1": (2, 0),
            "2": (2, 1),
            "3": (2, 2),
            ".": (2, 3),
            "GO!": (2, 4),
        }
        # Create the buttons and add them to the button grid layout
        for btnText, pos in buttons.items():
            self.buttons[btnText] = QPushButton(btnText)
            self.buttons[btnText].setFixedSize(80, 80)
            self.buttonsGrid.addWidget(self.buttons[btnText], pos[0], pos[1])
            
        self.cc.connectButtons()
        self.buttons["GO!"].clicked.connect(self.cc._subnetResult)
Пример #48
0
class Window2(QDialog):
    def __init__(self, model, parent=None):
        super(Window2, self).__init__(parent)

        self.model = model
        self.mainLayout = QGridLayout()
        self.mainLayout.setColumnStretch(0, 1)
        self.mainLayout.setColumnStretch(1, 3)
        self.mainLayout.setColumnStretch(2, 3)

        self.flayout = QFormLayout()
        self.flayout.addRow('title', QLineEdit())
        self.flayout.addRow('author', QLineEdit())
        self.flayout.addRow('abstract', QLineEdit())
        self.comboBox = QComboBox()
        self.comboBox.addItems(Scraper.scrapers)
        self.flayout.addRow('source', self.comboBox)

        self.table = TableWidget()
        self.table.doubleClicked.connect(self.openDocument)

        self.setFixedSize(1000, 600)

        button1 = QPushButton()
        button1.setText("Search")
        button1.clicked.connect(self.search)

        button2 = QPushButton()
        button2.setText("Save")
        button2.clicked.connect(self.save)

        self.button3 = QPushButton()
        self.button3.setText("Next")
        self.button3.clicked.connect(self.next_results)
        self.button3.setVisible(False)

        self.button4 = QPushButton()
        self.button4.setText("Previous")
        self.button4.clicked.connect(self.previous_results)
        self.button4.setVisible(False)

        self.label = QLabel()
        self.label.setVisible(False)

        self.setWindowTitle('Search')
        self.mainLayout.addLayout(self.flayout, 0, 0)
        self.mainLayout.addWidget(self.table, 0, 1, 1, 2)
        self.mainLayout.addWidget(self.label, 1, 0)
        self.mainLayout.addWidget(self.button4, 1, 1)
        self.mainLayout.addWidget(self.button3, 1, 2)
        self.mainLayout.addWidget(button1, 2, 0)
        self.mainLayout.addWidget(button2, 2, 1, 1, 2)

        self.setLayout(self.mainLayout)

    def getInputData(self):
        inputData = {
            self.flayout.itemAt(2 * i).widget().text():
            self.flayout.itemAt(2 * i + 1).widget().text()
            for i in range(int(self.flayout.count() / 2) - 1)
        }
        inputData['source'] = self.comboBox.currentText()
        return inputData

    def search(self):
        inputData = self.getInputData()
        source = inputData.pop('source')
        self.scraper = Scraper(inputData, source)
        logging.info('Scraper search' + str(inputData))
        results = self.scraper.search()
        self.table.fillTable(results)
        if self.scraper.total > 10:
            self.button3.setVisible(True)
        self.update_label()

    def update_label(self):
        self.label.setText('Page {} of {}'.format(
            self.scraper.page,
            int(self.scraper.total / 10) + 1))
        self.label.setVisible(True)

    def next_results(self):
        self.scraper.page += 1
        results = self.scraper.search()
        self.table.fillTable(results)
        self.button4.setVisible(True)
        if self.scraper.total <= 10 * self.scraper.page:
            self.button3.setVisible(False)
        self.update_label()

    def previous_results(self):
        self.scraper.page -= 1
        results = self.scraper.search()
        self.table.fillTable(results)
        self.button3.setVisible(True)
        if self.scraper.page <= 1:
            self.button4.setVisible(False)
        self.update_label()

    def openDocument(self, y):
        if 'http' in y.data():
            webbrowser.open(y.data(), new=2)

    def save(self):
        index = self.table.selectionModel().selectedRows()
        if len(index) > 0:
            new_data = {
                self.table.horizontalHeaderItem(i).text():
                str(self.table.model().index(index[0].row(), i).data())
                for i in range(self.table.columnCount())
            }
            if 'document' in new_data and 'pdf' in new_data['document']:
                new_data = self.save_file(new_data)
            row_index = self.model.rowCount(QModelIndex())
            record = self.model.record()
            record.setGenerated('id', False)
            record.setValue('created', QDateTime.currentDateTime())
            for column in new_data:
                record.setValue(column, new_data[column])
            self.model.insertRecord(-1, record)

    def save_file(self, new_data):
        if 'document' in new_data and len(new_data['document']) > 0:
            author = ', '.join(
                re.findall(r'(\w*)(?:$|,)', new_data.get('author'))[:-1])
            title = re.sub(r"[^a-zA-Z0-9]+", ' ', new_data.get('title'))
            date = new_data.get('date') if new_data.get('date') else ''
            filename = date + ' ' + title + ' - ' + author + '.pdf'
            path = os.path.join(cfg['temp'], filename)
            logging.info('Trying to save file ' + filename)
            if not os.path.exists(path):
                response = requests.get(new_data['document'], headers=_HEADERS)
                if response.ok:
                    try:
                        with open(path, 'wb') as f:
                            f.write(response.content)
                        try:
                            new_data['length'] = PdfFileReader(open(
                                path, 'rb')).getNumPages()
                        except:
                            display_text = 'Corrupted document ' + filename
                        new_data['document'] = filename
                        display_text = 'Saved document ' + filename
                    except:
                        display_text = 'Dowload document successful, but not possible to save.'
                        new_data['document'] = ''
                else:
                    display_text = 'Dowload document not successful.'
                    new_data['document'] = ''
            else:
                display_text = 'File ' + filename + 'already exists.'
        else:
            display_text = 'There is no document to save.'
        msgBox = QMessageBox()
        msgBox.setText(display_text)
        msgBox.exec_()
        logging.info(display_text)
        return new_data
Пример #49
0
class TestStripsDialog(QDialog):
    GHBox = None
    KHBox = None
    pHBox = None
    NO2Box = None
    NO3Box = None
 
    def __init__(self):
        super(TestStripsDialog, self).__init__()

        self.GHBox = QComboBox()
        self.KHBox = QComboBox()
        self.pHBox = QComboBox()
        self.NO2Box = QComboBox()
        self.NO3Box = QComboBox()

        self.createFormGroupBox()
 
        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)
 
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.formGroupBox)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)
 
        self.setWindowTitle("Aquarium Data Form")
 
    def createFormGroupBox(self):
        self.formGroupBox = QGroupBox("5-in-1 Test Strips")
        layout = QFormLayout()

        # Create the GH combobox
        GHItems = ['0','30','60','120','180']
        self.GHBox.addItems(GHItems)

        # Create the KH combobox
        KHItems = ['0','40','80','120','180','240']
        self.KHBox.addItems(KHItems)

        # Create the pH combobox
        pHItems = ['6.0','6.5','7.0','7.5','8.0','8.5','9.0']
        self.pHBox.addItems(pHItems)

        # Create the Nitrite combobox
        NO2Items = ['0 ppm','0.50 ppm','1.0 ppm','3.0 ppm','5.0 ppm','10.0 ppm']
        self.NO2Box.addItems(NO2Items)

        # Create the Nitrate combobox
        NO3Items = ['20 ppm','40 ppm','80 ppm','160 ppm','200 ppm']
        self.NO3Box.addItems(NO3Items)

        layout.addRow(QLabel("General Hardness (GH):"), self.GHBox)
        layout.addRow(QLabel("Carbonate Hardness (KH):"), self.KHBox)
        layout.addRow(QLabel("pH"), self.pHBox)
        layout.addRow(QLabel("Nitrite (NO2-):"), self.NO2Box)
        layout.addRow(QLabel("Nitrate (NO3-):"), self.NO3Box)
        self.formGroupBox.setLayout(layout)

    def accept(self):
        date = datetime.datetime.now()
        print("\n5-in-1 Test Strip Results - " + str(date))
        print("  GH Level:\t\t" + self.GHBox.currentText()) 
        print("  KH Level:\t\t" + self.KHBox.currentText()) 
        print("  pH Level:\t\t" + self.pHBox.currentText()) 
        print("  Nitrite Level:\t" + self.NO2Box.currentText()) 
        print("  Nitrate Level:\t" + self.NO3Box.currentText()) 

        self.writeTestStrips(self.GHBox.currentText(), self.KHBox.currentText(), self.pHBox.currentText(), self.NO2Box.currentText(), self.NO3Box.currentText())

        self.done(0)

    def writeTestStrips(self, GH, KH, pH, NO2, NO3):
        with open(".aquadata", "r") as fp:
            tsLine   = fp.readline()
            fmtkLine = fp.readline()
            tempLine = fp.readline()

        fmtkLine = GH + "," + KH + "," + pH + "," + NO2 + "," + NO3 + "\n"

        with open(".aquadata", "w") as fp:
            fp.write(tsLine)
            fp.write(fmtkLine)
            fp.write(tempLine)
Пример #50
0
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.showUI()
        self.show()

    def initUI(self):
        self.setGeometry(100, 50, 850, 600)
        self.setWindowTitle('Neural Network Interface Solver')
        self.setWindowIcon(QIcon('brainGUI.png'))
        self.toolbar = self.addToolBar('Toolbar')
        self.functions = [sigmoid, sigmoid, sigmoid]
        self.erf = error

    def showUI(self):
        # Central widget and layout
        wid = QWidget()
        self.setCentralWidget(wid)
        grid = QGridLayout()
        wid.setLayout(grid)
        grid.setSpacing(5)

        # Creamos las cuatro cajas que vamos a usar
        Caja1 = QGroupBox('Dimensión de los datos del entrenamiento')
        Caja2 = QGroupBox('Área de la representación del error')
        Caja3 = QGroupBox('Parámetros de la red neuronal')
        Caja4 = QGroupBox('Zona de resultados')
        Caja5 = QGroupBox('Zona de botones')
        Caja1.setObjectName('PrimeraCaja')

        # Creamos los cuatro layouts. Son 4 Grids, al fin y al cabo.
        Caja1Layout = QGridLayout()
        Caja2Layout = QGridLayout()
        Caja3Layout = QGridLayout()
        Caja4Layout = QGridLayout()
        Caja5Layout = QGridLayout()

        Caja1.setLayout(Caja1Layout)
        Caja2.setLayout(Caja2Layout)
        Caja3.setLayout(Caja3Layout)
        Caja4.setLayout(Caja4Layout)
        Caja5.setLayout(Caja5Layout)

        grid.addWidget(Caja1, 0, 0, 1, 2)  # 1 Fila - 2 Columnas
        grid.addWidget(Caja2, 1, 0, 1, 4)  # 1 Fila - 4 Columnas
        grid.addWidget(Caja3, 2, 0, 1, 4)  # 1 Fila - 2 Columnas
        grid.addWidget(Caja4, 0, 4, 2, 1)  # 2 Filas - 1 Columna
        grid.addWidget(Caja5, 3, 0, 3, 4)  # 3 Filas - 4 Columnas

        grid.setColumnStretch(0, 2)
        Caja1.setSizePolicy(
            QSizePolicy.Maximum, QSizePolicy.Maximum
        )  # Con esto se consigue dejar pequeña la mierda esa
        Caja3.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        # Objects
        # Plot object
        self.figure = plt.figure(tight_layout=True)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setMinimumSize(
            200, 200)  # Esto hace que no se pueda hacer el widget to pequeño
        ax = self.figure.add_subplot(111)
        plt.xlabel('Iteración')
        plt.ylabel('Error')
        plt.title('Error vs Iteración')
        self.canvas.draw()
        # Labels for the functions
        label1 = QLabel('Input - H1')
        label2 = QLabel('H1 - H(-1)')
        label3 = QLabel('H(-1) - Output')
        label4 = QLabel('Error')
        label5 = QLabel('Layers')
        label6 = QLabel('Neurons')
        label7 = QLabel('Learning rate')
        label8 = QLabel('Regularization')
        label9 = QLabel('Resultados:')
        label10 = QLabel('Dimensión de inputs')
        label11 = QLabel('Dimensión de outputs')
        # Selectors for the functions
        self.combo1 = QComboBox(self)
        self.combo1.addItem('Sigmoid')
        self.combo1.addItem('ReLu')
        self.combo1.addItem('Linear')
        self.combo1.addItem('SoftMax')
        self.combo2 = QComboBox(self)
        self.combo2.addItem('Sigmoid')
        self.combo2.addItem('ReLu')
        self.combo2.addItem('Linear')
        self.combo2.addItem('SoftMax')
        self.combo3 = QComboBox(self)
        self.combo3.addItem('Sigmoid')
        self.combo3.addItem('ReLu')
        self.combo3.addItem('Linear')
        self.combo3.addItem('SoftMax')
        self.combo4 = QComboBox(self)
        self.combo4.addItem('Quadratic Error')
        self.combo4.addItem('Cross-Entropy function')
        # Botones
        btn = QPushButton('Cargar parámetros')
        btn.clicked.connect(self.checkParameters)
        btn2 = QPushButton('Crear Redes Neuronales')
        btn2.clicked.connect(self.initNetwork)
        btn3 = QPushButton('Resolver red')
        btn3.clicked.connect(self.solveNetwork)
        btn3.setStyleSheet(
            "font: bold; background-color: cyan; font-size: 26px; border-width: 100px; border-color: black"
        )
        btn3.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        btn4 = QPushButton('Cargar Inputs y Outputs')
        btn4.clicked.connect(self.readInputs)
        # Edit Texts
        self.ed1 = QLineEdit(' ')
        self.ed2 = QLineEdit(' ')
        self.ed3 = QLineEdit(' ')
        self.ed4 = QLineEdit(' ')
        self.ed1.setText('1')
        self.ed2.setText('1')
        self.ed3.setText('1')
        self.ed4.setText('1')
        self.ed5 = QLineEdit('1')
        self.ed6 = QLineEdit('1')
        self.ed5.setMaximumWidth(30)
        self.ed6.setMaximumWidth(30)
        # Bloque de texto
        self.block = QTextEdit('Status:')
        self.block.moveCursor(QTextCursor.End)
        self.block.insertPlainText('\n' + 'Run for results')
        self.block.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # Colocamos los objetos
        # Labels
        Caja1Layout.addWidget(label10, 0, 0)
        Caja1Layout.addWidget(label11, 1, 0)
        Caja1Layout.addWidget(self.ed5, 0, 1)
        Caja1Layout.addWidget(self.ed6, 1, 1)
        Caja1Layout.setColumnStretch(1, 3)
        # Plot
        Caja2Layout.addWidget(self.canvas, 0, 0)  # 1 fila, 4 columnas
        # Parametros a introducir
        Caja3Layout.addWidget(label1, 0, 0)
        Caja3Layout.addWidget(self.combo1, 0, 1)
        Caja3Layout.addWidget(label2, 1, 0)
        Caja3Layout.addWidget(self.combo2, 1, 1)
        Caja3Layout.addWidget(label3, 2, 0)
        Caja3Layout.addWidget(self.combo3, 2, 1)
        Caja3Layout.addWidget(label4, 3, 0)
        Caja3Layout.addWidget(self.combo4, 3, 1)
        Caja3Layout.addWidget(label5, 0, 2)
        Caja3Layout.addWidget(self.ed1, 0, 3)
        Caja3Layout.addWidget(label6, 1, 2)
        Caja3Layout.addWidget(self.ed2, 1, 3)
        Caja3Layout.addWidget(label7, 2, 2)
        Caja3Layout.addWidget(self.ed3, 2, 3)
        Caja3Layout.addWidget(label8, 3, 2)
        Caja3Layout.addWidget(self.ed4, 3, 3)
        # Bloque de texto
        Caja4Layout.addWidget(label9, 0, 0, 1, 1)
        Caja4Layout.addWidget(self.block, 1, 0, 1, 1)
        # Botones
        Caja5Layout.addWidget(btn, 0, 0)
        Caja5Layout.addWidget(btn2, 2, 0)
        Caja5Layout.addWidget(btn3, 0, 1, 3, 3)
        Caja5Layout.addWidget(btn4, 1, 0)

    def checkParameters(self):
        f1s = str(self.combo1.currentText())
        f2s = str(self.combo2.currentText())
        f3s = str(self.combo3.currentText())
        f4s = str(self.combo4.currentText())
        if f1s[:2] == 'Si':
            f1 = sigmoid
        elif f1s[0] == 'R':
            f1 = relu
        elif f1s[0] == 'L':
            f1 = lin
        elif f1s[:2] == 'So':
            f1 = soft

        if f2s[:2] == 'Si':
            f2 = sigmoid
        elif f2s[0] == 'R':
            f2 = relu
        elif f2s[0] == 'L':
            f2 = lin
        elif f2s[:2] == 'So':
            f2 = soft

        if f3s[:2] == 'Si':
            f3 = sigmoid
        elif f3s[0] == 'R':
            f3 = relu
        elif f3s[0] == 'L':
            f3 = lin
        elif f3s[:2] == 'So':
            f3 = soft

        if f4s[:2] == 'Qu':
            f4 = error
        elif f4s[0] == 'C':
            f4 = crossEntrop

        self.functions = [f1, f2, f3]
        self.erf = f4
        self.NI = int(self.ed5.text())
        self.NO = int(self.ed6.text())
        self.NL = int(self.ed1.text())
        self.NN = int(self.ed2.text())
        self.lr = float(self.ed3.text())
        self.reg = float(self.ed4.text())
        print('The functions are: ', self.functions)
        print('The error calculus is: ', self.erf)
        print('The dimension of the inputs is: ', self.NI)
        print('The dimension of the outputs is: ', self.NO)
        print('The number of layers is: ', self.NL)
        print('The number of neurons per hidden layer is: ', self.NN)
        print('The learning rate is: ', self.lr)
        print('The reg parameter is: ', self.reg)

    def readInputs(self):
        fname = QFileDialog.getOpenFileName(self, 'Open File')
        Inputs_df = read_excel(fname[0])
        self.Inputs = np.array(Inputs_df.iloc[:, :self.NI])
        self.Outputs = np.array(Inputs_df.iloc[:, self.NI:])
        print(self.Inputs.shape)
        print(self.Outputs.shape)
        if self.NO != self.Outputs.shape[1]:
            print(
                'AVISO: EL NUMERO DE OUTPUTS NO COINCIDE CON LOS DATOS DADOS')

    def initNetwork(self):
        self.Layers = HiddenLayers(self.functions[0], self.functions[1],
                                   self.functions[2])
        self.Layers.setlayers(self.Inputs.shape[1], self.Outputs.shape[1],
                              self.NL, self.NN)
        print(self.Layers.f)

    def solveNetwork(self):
        self.block.clear()
        self.calculo = CalculoNeural(
            NeuralNetwork(self.Inputs, self.Layers.W, self.Layers.b,
                          self.Layers.f, self.lr, self.Outputs), self.erf,
            self.reg)
        self.calculo.mySignal.connect(
            self.setText
        )  # Se conecta el objeto de señal con el slot de setText, definido abajo
        # Creamos las listas para guardar los errores
        self.IterPlot = []
        self.ErrorPlot = []
        self.calculo.PlotSignal.connect(
            self.setPlot
        )  # Lo mismo. Se conecta la señal PlotSignal con el slot de setPlot.
        self.calculo.start()

    def setText(self, text):  # Este text es lo que se envia con la señal
        self.block.moveCursor(QTextCursor.End)
        self.block.insertPlainText('\n' + text)

    def setPlot(self, value, iteration):
        print('Iteración: ', iteration, ' Valor del error : ', value)
        if iteration > 1:
            self.IterPlot.append(iteration / 10000)
            self.ErrorPlot.append(value)
        self.figure.clear()
        ax = self.figure.add_subplot(111)
        if iteration > 10000:
            ax.plot(self.IterPlot, self.ErrorPlot, '-*r')
        plt.xlabel('Iteración')
        plt.ylabel('Error')
        plt.title('Error vs Iteración')
        self.canvas.draw()
Пример #51
0
def edit_contact_dialog(wallet_api, contact_key=None):
    editing = contact_key is not None
    if editing:
        title = _("Edit Contact")
    else:
        title = _("New Contact")

    d = WindowModalDialog(wallet_api.wallet_window, title)
    vbox = QVBoxLayout(d)
    vbox.addWidget(QLabel(title + ':'))

    def _contact_insert_completion(text):
        if text:
            index = combo1.findText(text)
            combo1.setCurrentIndex(index)

    identity_line = QLineEdit()
    name_line = QLineEdit()
    combo1 = QComboBox()
    combo1.setFixedWidth(280)
    combo1.setEditable(True)

    # add a filter model to filter matching items
    contact_filter_model = QSortFilterProxyModel(combo1)
    contact_filter_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
    contact_filter_model.setSourceModel(combo1.model())

    contact_completer = QCompleter(contact_filter_model, combo1)
    contact_completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
    combo1.setCompleter(contact_completer)

    ok_button = OkButton(d)
    ok_button.setEnabled(False)

    def _validate_form() -> None:
        def _set_validation_state(element, is_valid) -> None:
            if not is_valid:
                element.setStyleSheet("border: 1px solid red")
            else:
                element.setStyleSheet("")

        can_submit = True

        system_name = combo1.currentText().lower().strip()
        is_valid = True
        try:
            system_id = get_system_id(system_name)
        except ContactDataError:
            system_id = None
            is_valid = False
        _set_validation_state(combo1, is_valid)
        can_submit = can_submit and is_valid

        identity_text = identity_line.text().strip()
        if system_id is None:
            identity_result = IdentityCheckResult.Invalid
        else:
            identity_result = wallet_api.check_identity_valid(
                system_id, identity_text, skip_exists=editing)
        is_valid = identity_result == IdentityCheckResult.Ok
        _set_validation_state(identity_line, is_valid)
        if is_valid:
            identity_line.setToolTip("")
        elif identity_result == IdentityCheckResult.Invalid:
            if system_id == IdentitySystem.OnChain:
                identity_line.setToolTip(_("Not a valid Bitcoin address"))
            else:
                identity_line.setToolTip(_("Incorrect format"))
        elif identity_result == IdentityCheckResult.InUse:
            identity_line.setToolTip(_("Already in use"))
        can_submit = can_submit and is_valid

        name_text = name_line.text().strip()
        name_result = wallet_api.check_label(name_text)
        is_valid = (name_result == IdentityCheckResult.Ok
                    or editing and name_result == IdentityCheckResult.InUse)
        _set_validation_state(name_line, is_valid)
        if is_valid:
            name_line.setToolTip("")
        elif name_result == IdentityCheckResult.Invalid:
            name_line.setToolTip(_("Name too short"))
        elif name_result == IdentityCheckResult.InUse:
            name_line.setToolTip(_("Name already in use"))
        can_submit = can_submit and is_valid

        ok_button.setEnabled(can_submit)

    def _contact_text_changed(text: str) -> None:
        _validate_form()

    combo1.lineEdit().textEdited.connect(
        contact_filter_model.setFilterFixedString)
    combo1.editTextChanged.connect(_contact_text_changed)
    identity_line.textChanged.connect(_contact_text_changed)
    name_line.textChanged.connect(_contact_text_changed)
    contact_completer.activated.connect(_contact_insert_completion)

    combo1.addItems(list(IDENTITY_SYSTEM_NAMES.values()))

    grid = QGridLayout()
    identity_line.setFixedWidth(280)
    name_line.setFixedWidth(280)
    grid.addWidget(QLabel(_("Identity Type")), 1, 0)
    grid.addWidget(combo1, 1, 1)
    grid.addWidget(QLabel(_("Identity")), 2, 0)
    grid.addWidget(identity_line, 2, 1)
    grid.addWidget(QLabel(_("Name")), 3, 0)
    grid.addWidget(name_line, 3, 1)

    vbox.addLayout(grid)
    vbox.addLayout(Buttons(CancelButton(d), ok_button))

    if contact_key is None:
        combo1.lineEdit().setText(
            IDENTITY_SYSTEM_NAMES[IdentitySystem.OnChain])
        identity_line.setFocus()
    else:
        entry = wallet_api.get_contact(contact_key[0])
        identity = [
            ci for ci in entry.identities if ci.identity_id == contact_key[1]
        ][0]
        combo1.lineEdit().setText(IDENTITY_SYSTEM_NAMES[identity.system_id])
        identity_line.setText(identity.system_data)
        name_line.setText(entry.label)
        name_line.setFocus()

    if d.exec_():
        name_text = name_line.text().strip()
        identity_text = identity_line.text().strip()
        system_id = get_system_id(combo1.currentText())
        if contact_key is not None:
            contact = wallet_api.get_contact(contact_key[0])
            identity = [
                ci for ci in contact.identities
                if ci.identity_id == contact_key[1]
            ][0]
            if contact_key[1] != identity.identity_id:
                wallet_api.remove_identity(contact_key[0], contact_key[1])
                wallet_api.add_identity(contact_key[0], system_id,
                                        identity_text)
            if contact.label != name_text:
                wallet_api.set_label(contact_key[0], name_text)
        else:
            wallet_api.add_contact(system_id, name_text, identity_text)
Пример #52
0
class UnicodeSearch(QDialog):
    def __init__(self, parent):
        super(UnicodeSearch, self).__init__(parent)

        self.parent = parent

        self.selected_item = None
        self.selected_code = -1
        self.recent_searches = []

        # таблица с результатами поиска
        self.results = QTableWidget()
        self.results.verticalHeader().hide()
        self.results.horizontalHeader().hide()
        self.results.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.results.setColumnCount(4)
        self.results.horizontalHeader().setSectionResizeMode(
            3, QHeaderView.Stretch)
        self.results.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.results.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.results.cellActivated.connect(self.selectItem)

        # строка поиска, сохраняет введенные ранее строки
        self.combo = QComboBox()
        self.combo.setEditable(True)
        self.combo.setInsertPolicy(QComboBox.NoInsert)
        self.combo.lineEdit().setClearButtonEnabled(True)
        self.combo.currentIndexChanged.connect(self.searchClicked)
        self.search_mode = QComboBox()
        self.search_mode.addItems(SEARCH_MODES)
        self.lang_select = QComboBox()
        self.lang_select.addItems(parent.LANG_STRINGS)
        current_lang_index = parent.LANG_STRINGS.index(parent.table.lang)
        self.lang_select.setCurrentIndex(current_lang_index)
        self.lang_select.currentIndexChanged.connect(self.reloadUT)
        search_button = QPushButton(parent.search_icon, '')
        search_button.setToolTip('начать поиск')
        search_button.clicked.connect(self.searchClicked)

        top_bar = QHBoxLayout()
        top_bar.addWidget(self.combo, 1)
        top_bar.addWidget(self.search_mode)
        top_bar.addWidget(self.lang_select)
        top_bar.addWidget(search_button)

        main_box = QVBoxLayout()
        main_box.addLayout(top_bar)
        main_box.addWidget(self.results)

        self.setLayout(main_box)
        self.resize(680, 680)
        self.searchClicked()

    # перезагрузка имен разделов/символов на указанном языке
    def reloadUT(self):
        self.parent.table = UnicodeTable(self.parent.UT_FILENAME,
                                         self.lang_select.currentText())
        self.search_mode.setCurrentIndex(0)
        self.combo.setCurrentText('')
        self.searchClicked()

    def searchClicked(self):
        items = []
        ut = self.parent.table
        self.block_mode = False
        text = self.combo.currentText()
        if text not in self.recent_searches:
            self.recent_searches.append(text)
            self.combo.addItem(text)
        mode = self.search_mode.currentIndex()
        if mode == 0:
            items = ut.find_block_name(text)
            self.block_mode = True
        if mode == 1:
            if len(text) < 3:
                self.combo.setCurrentText('не меньше 3 букв')
            else:
                items = ut.find_symbol_name(text)
        if mode == 2:
            items = ut.find_symbols(text)
        if mode == 3:
            items = ut.find_codes(text, 16)
        if mode == 4:
            items = ut.find_codes(text, 10)

        self.results.setRowCount(0)
        for entry in items:
            row = self.results.rowCount()
            self.results.insertRow(row)
            self.results.setItem(row, 0, QTableWidgetItem(entry[0]))
            self.results.setItem(row, 3, QTableWidgetItem(entry[2]))
            self.results.setItem(row, 1,
                                 QTableWidgetItem(' {:05X}'.format(entry[1])))
            self.results.setItem(row, 2, QTableWidgetItem(chr(entry[1])))

        self.results.sortByColumn(1, Qt.AscendingOrder)

        if self.block_mode:
            self.setWindowTitle('{0} — {1} разделов'.format(
                self.parent.APP_NAME, len(items)))
        else:
            self.setWindowTitle('{0} — {1} символов'.format(
                self.parent.APP_NAME, len(items)))

    # выбор одной строки из результатов поиска и
    # возвращение в главное окно к выбранной позиции, сохраняемой в закладки
    def selectItem(self, row, column):
        if self.block_mode:
            self.selected_item = self.results.item(row, 0).text()
        else:
            self.selected_item = '{0} ({1})'.format(
                self.results.item(row, 3).text(),
                self.results.item(row, 0).text())
        self.selected_code = int(self.results.item(row, 1).text(), 16)
        self.accept()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Return:
            self.searchClicked()
class finance_entry(QWidget):
    def __init__(self, home_button: QPushButton, parent=None):
        super().__init__(parent)

        intValidator = QIntValidator()
        self.setStyleSheet(QSS)

        self.current_pending_months = []
        self.current_advance_months = []

        self.home_button = home_button
        # -- LEVEL TWO GRID
        self.grid = QGridLayout()
        self.grid.setSpacing(20)
        self.setLayout(self.grid)

        # -- CELL ZERO
        self.receipt_label = QLabel("RECEIPT ID :")
        self.receipt_label.setWordWrap(True)

        self.receipt_id = QLabel()
        self.receipt_id.setStyleSheet("font: bold")
        self.receipt_id.setAlignment(Qt.AlignCenter)

        currentMonth = datetime.now().month
        currentYear = datetime.now().year

        currentReceipt = db_tools.generate_receipt_id(str(currentMonth),
                                                      str(currentYear))
        self.receipt_id.setText(currentReceipt)

        # ---
        self.flat_label = QLabel("FLAT NO. :")
        self.flat_combo = QComboBox()
        model = self.flat_combo.model()

        for flat in flats:
            model.appendRow(QStandardItem(flat))

        self.flat_combo.setStyleSheet(
            'text-color: black; selection-background-color: rgb(215,215,215)')

        self.flat_combo.currentIndexChanged['QString'].connect(self.set_name)

        # ---
        self.name_label = QLabel("NAME :")
        self.name_value = QLabel("Mr D. S. Patil")
        self.name_value.setFixedWidth(200)

        # ---
        self.finance_entry_layout0 = QFormLayout()
        self.finance_entry_layout0.addRow(self.receipt_label, self.receipt_id)
        self.finance_entry_layout0.addRow(self.flat_label, self.flat_combo)
        self.finance_entry_layout0.addRow(self.name_label, self.name_value)
        self.finance_entry_layout0.setVerticalSpacing(90)

        # -- CELL ONE
        self.date_label = QLabel("DATE OF TRANSACTION :")
        self.date_label.setWordWrap(True)

        self.date_line = QDateEdit()
        self.date_line.setCalendarPopup(True)
        self.date_line.setDate(QDate.currentDate())
        self.date_line.setDisplayFormat("dd MMMM, yyyy")

        self.single_radio = QRadioButton("Single Month")
        self.multiple_radio = QRadioButton("Multiple Months")
        self.single_radio.setChecked(True)

        self.single_radio.toggled.connect(
            lambda: self.months(button=self.single_radio))
        self.multiple_radio.toggled.connect(
            lambda: self.months(button=self.multiple_radio))

        self.finance_entry_layout1_h1 = QHBoxLayout()
        self.finance_entry_layout1_h1.addWidget(self.date_line)
        self.finance_entry_layout1_h1.addWidget(self.single_radio)
        self.finance_entry_layout1_h1.addWidget(self.multiple_radio)
        self.finance_entry_layout1_h1.setSpacing(90)

        # ---
        self.month_label = QLabel("FEES FOR :")
        self.month_combo = QComboBox()
        self.set_pending_months()

        self.month_combo.setStyleSheet(
            'text-color: black; selection-background-color: rgb(215,215,215)')

        # ---
        self.month_till_label = QLabel("FEES TILL :")
        self.month_till_label.setAlignment(Qt.AlignCenter)
        self.month_till_combo = QComboBox()

        self.set_advance_months()

        self.month_till_combo.setStyleSheet(
            'text-color: black; selection-background-color: rgb(215,215,215)')

        self.finance_entry_layout1_h2 = QHBoxLayout()
        self.finance_entry_layout1_h2.addWidget(self.month_combo)
        self.finance_entry_layout1_h2.addWidget(self.month_till_label)
        self.finance_entry_layout1_h2.addWidget(self.month_till_combo)
        self.finance_entry_layout1_h2.setSpacing(90)

        self.month_till_label.setEnabled(False)
        self.month_till_combo.setEnabled(False)

        # ---
        self.amount_label = QLabel("AMOUNT :")
        self.amount_label.setAlignment(Qt.AlignCenter)
        self.amount_line = QLineEdit()
        self.amount_line.setText("1500")

        self.amount_line.setValidator(intValidator)

        # ---
        self.fine_label = QLabel("FINE :")
        self.fine_label.setAlignment(Qt.AlignCenter)
        self.fine_line = QLineEdit()

        if int(self.date_line.text().split(" ")[0]) <= 5:
            self.fine_line.setText("0")
        else:
            self.fine_line.setText("50")

        self.fine_line.setValidator(intValidator)
        self.fine_line.setStyleSheet("border: 1px solid red; color: red")

        self.finance_entry_layout1_h3 = QHBoxLayout()
        self.finance_entry_layout1_h3.addWidget(self.amount_line)
        self.finance_entry_layout1_h3.addWidget(self.fine_label)
        self.finance_entry_layout1_h3.addWidget(self.fine_line)
        self.finance_entry_layout1_h3.setSpacing(90)

        # ---
        self.finance_entry_layout1 = QFormLayout()
        self.finance_entry_layout1.addRow(self.date_label,
                                          self.finance_entry_layout1_h1)
        self.finance_entry_layout1.addRow(self.month_label,
                                          self.finance_entry_layout1_h2)
        self.finance_entry_layout1.addRow(self.amount_label,
                                          self.finance_entry_layout1_h3)
        self.finance_entry_layout1.setVerticalSpacing(90)

        # -- CELL TWO
        self.mode_label = QLabel("PAYMENT MODE :")
        self.mode_label.setWordWrap(True)

        # ---
        self.mode_combo = QComboBox()
        self.mode_combo.addItem("Cash")
        self.mode_combo.addItem("Online Funds Transfer")
        self.mode_combo.addItem("Cheque")

        self.mode_combo.setStyleSheet(
            'text-color: black; selection-background-color: rgb(215,215,215)')
        self.mode_combo.currentIndexChanged['QString'].connect(
            self.mode_selection)

        # ---
        self.ref_label = QLabel("REFERENCE ID :")
        self.ref_label.setWordWrap(True)
        self.ref_line = QLineEdit()

        self.ref_label.setDisabled(True)
        self.ref_line.setDisabled(True)

        self.total_label = QLabel(
            f"TOTAL PAYABLE AMOUNT : {int(self.amount_line.text()) + int(self.fine_line.text())}"
        )
        self.total_label.setWordWrap(True)
        self.total_label.setAlignment(Qt.AlignCenter)

        self.save_button = QPushButton("SAVE")
        self.save_button.setStyleSheet("font: bold")
        self.save_button.clicked.connect(lambda: self.check_form())

        self.status = QLabel("Ready")
        self.status.setStyleSheet("font: 8pt")
        self.status.setAlignment(Qt.AlignCenter)

        self.bar = QProgressBar(self)
        self.bar.setMaximum(100)
        self.bar.setValue(0)
        self.bar.setToolTip("Please wait until the process is completed.")

        # ---
        self.finance_entry_layout2 = QFormLayout()
        self.finance_entry_layout2.addRow(self.mode_label, self.mode_combo)
        self.finance_entry_layout2.addRow(self.ref_label, self.ref_line)
        self.finance_entry_layout2.addItem(create_spacer_item(w=5, h=30))
        self.finance_entry_layout2.addRow(self.total_label)
        self.finance_entry_layout2.addRow(self.save_button)
        self.finance_entry_layout2.addRow(self.status)
        self.finance_entry_layout2.addRow(self.bar)
        self.finance_entry_layout2.setVerticalSpacing(50)

        self.finance_entry_group0 = QGroupBox()
        self.finance_entry_group0.setLayout(self.finance_entry_layout0)

        self.finance_entry_group1 = QGroupBox()
        self.finance_entry_group1.setLayout(self.finance_entry_layout1)

        self.finance_entry_group2 = QGroupBox()
        self.finance_entry_group2.setLayout(self.finance_entry_layout2)
        self.finance_entry_group2.setFixedWidth(550)

        # -- FUNCTIONALITY:
        self.date_line.dateChanged.connect(lambda: self.set_pending_months(
            date=str(self.date_line.date().toPyDate())))

        self.month_combo.currentIndexChanged['QString'].connect(
            self.set_advance_months)

        self.month_combo.currentIndexChanged['QString'].connect(
            lambda ind: self.calculate_fine('from', ind))
        self.month_till_combo.currentIndexChanged['QString'].connect(
            lambda ind: self.calculate_fine('till', ind))

        self.month_combo.currentTextChanged.connect(self.calculate_amount)
        self.month_till_combo.currentTextChanged.connect(self.calculate_amount)

        self.amount_line.textChanged.connect(self.set_total)
        self.fine_line.textChanged.connect(self.set_total)

        # -- FINANCE ENTRY GRID
        self.grid.addWidget(self.finance_entry_group0, 0, 0, 2, 1)
        self.grid.addWidget(self.finance_entry_group1, 0, 1, 2, 1)
        self.grid.addWidget(self.finance_entry_group2, 0, 2, 2, 1)

    def months(self, button):
        if button.isChecked():
            if button.text() == "Single Month":
                self.month_till_label.setEnabled(False)
                self.month_till_combo.setEnabled(False)

            elif button.text() == "Multiple Months":
                self.month_till_label.setEnabled(True)
                self.month_till_combo.setEnabled(True)

        self.calculate_amount()

    def mode_selection(self, selection):
        if selection == "Cash":
            self.ref_label.setText("REFERENCE ID :")
            self.ref_label.setDisabled(True)
            self.ref_line.setDisabled(True)

        elif selection == "Cheque":
            self.ref_label.setText("CHEQUE NO. :")
            self.ref_label.setDisabled(False)
            self.ref_line.setDisabled(False)

        elif selection == "Online Funds Transfer":
            self.ref_label.setText("REFERENCE ID :")
            self.ref_label.setDisabled(False)
            self.ref_line.setDisabled(False)

    def check_form(self):
        reply = QMessageBox()

        if len(self.amount_line.text()) == 0:
            reply.setIcon(QMessageBox.Warning)
            reply.setText("AMOUNTS field cannot be left empty.")
            reply.setStandardButtons(QMessageBox.Retry)
            reply.setWindowTitle("INVALID ENTRY")
            reply.exec_()

        elif len(self.fine_line.text()) == 0:
            reply.setIcon(QMessageBox.Warning)
            reply.setText("FINE field cannot be left empty.")
            reply.setStandardButtons(QMessageBox.Retry)
            reply.setWindowTitle("INVALID ENTRY")
            reply.exec_()

        elif self.ref_line.isEnabled() and len(self.ref_line.text()) == 0:
            reply.setIcon(QMessageBox.Warning)
            reply.setText(
                "Please enter the REFERENCE INFORMATION for the transaction.")
            reply.setStandardButtons(QMessageBox.Retry)
            reply.setWindowTitle("INVALID ENTRY")
            reply.exec_()

        elif payment_exists(flat=self.flat_combo.currentText(),
                            month=self.month_combo.currentText()):
            reply.setIcon(QMessageBox.Warning)
            reply.setText(
                f"This member ({self.flat_combo.currentText()}) has already paid the fees for the month of {self.month_combo.currentText()}"
            )
            reply.setStandardButtons(QMessageBox.Retry)
            reply.setWindowTitle("INVALID ENTRY")
            reply.exec_()

        else:
            if self.month_till_combo.isEnabled():
                fee_till = f" - {self.month_till_combo.currentText()}"
            else:
                fee_till = ''

            if self.ref_line.isEnabled():
                ref = f" - ({self.ref_line.text()})"
            else:
                ref = ''

            detailed_text = f"Date : {fix_date(str(self.date_line.date().toPyDate()))}\n" \
                            f"Fee for : {str(self.month_combo.currentText())}{fee_till}\n" \
                            f"Flat No : {str(self.flat_combo.currentText())}\n" \
                            f"Amount : {float(self.amount_line.text())}\n" \
                            f"Fine : {float(self.fine_line.text())}\n" \
                            f"    -> TOTAL : {str(int(self.amount_line.text()) + int(self.fine_line.text()))} <-\n" \
                            f"Payment Mode : {str(self.mode_combo.currentText())}{ref}"

            reply.setWindowTitle("SUCCESSFUL ENTRY")
            reply.setIcon(QMessageBox.Information)
            reply.setText("ENTRY HAS BEEN RECORDED.\n")
            reply.setInformativeText("Please confirm the details below.")
            reply.setDetailedText(detailed_text)
            confirm_button = reply.addButton('Confirm', QMessageBox.AcceptRole)
            edit_button = reply.addButton('Edit', QMessageBox.RejectRole)

            confirm_button.clicked.connect(
                lambda: self.final_clicked(button=confirm_button))
            edit_button.clicked.connect(
                lambda: self.final_clicked(button=edit_button))
            reply.exec_()

    def set_name(self, flat):
        name = get_name(flat)
        self.name_value.setText(str(name))

    def add_entry(self):
        receipt_id = self.receipt_id.text()
        date = str(self.date_line.date().toPyDate())
        fee_month = self.month_combo.currentText()

        if self.month_till_combo.isEnabled():
            fee_till = self.month_till_combo.currentText()
            month = f"{fee_month}-{fee_till}"
        else:
            fee_till = ''
            month = fee_month

        flat = str(self.flat_combo.currentText())
        amount = float(self.amount_line.text())
        fine = float(self.fine_line.text())
        mode = str(self.mode_combo.currentText())

        if self.ref_line.isEnabled():
            ref = self.ref_line.text()
        else:
            ref = ''

        print(fee_month)
        new_receipt = receipt.receipt(date=fix_date(date),
                                      flat=flat,
                                      month=fee_month,
                                      month_till=fee_till,
                                      amount=amount,
                                      fine=fine,
                                      mode=mode,
                                      ref=ref)
        self.disable()
        self.total_label.setText(
            "Confirming.. PLEASE DO NOT PERFORM ANY OTHER OPERATIONS.")
        new_receipt.add_to_db()

        self.status.setText("Adding to databse & Generating receipt")
        self.bar.setValue(40)

        design_receipt(receipt_id=f"0{receipt_id}")

        self.status.setText(
            "Sending the receipt to the member. (Depends on your internet connection)"
        )
        self.bar.setValue(75)
        email_status = send_receipt(flat=flat, month=month)

        self.enable()
        self.set_total()

        if email_status:
            self.bar.setValue(100)

        else:
            reply = QMessageBox()
            reply.setIcon(QMessageBox.Warning)
            reply.setText(
                "The system cannot access the internet. Make sure you have an active connection, or any firewall"
                "feature blocking the access.")
            reply.setStandardButtons(QMessageBox.Retry)
            reply.setWindowTitle("INTERNET")
            reply.exec_()

    def final_clicked(self, button):
        if button.text() == "Confirm":
            self.add_entry()

            currentReceipt = db_tools.generate_receipt_id(
                str(datetime.now().month), str(datetime.now().year))
            self.receipt_id.setText(currentReceipt)
            self.flat_combo.setCurrentIndex(0)
            self.name_value.setText("Mr D. S. Patil")
            self.amount_line.setText('1500')
            if int(self.date_line.text().split(" ")[0]) <= 5:
                self.fine_line.setText("0")
            else:
                self.fine_line.setText("50")
            self.bar.setValue(0)
            self.status.setText("Done !")
            self.ref_line.clear()

    def set_pending_months(self, date: str = None):
        if date is None:
            date = str(self.date_line.date().toPyDate())

        months = calculate_months(month=date, pending=True, advance=False)

        self.current_pending_months = months

        self.month_combo.clear()

        model = self.month_combo.model()
        for month in months:
            model.appendRow(QStandardItem(month))

    def set_advance_months(self, date: str = None):
        if date is None or date == '':
            date = fix_date_back(self.current_pending_months[0])
        else:
            date = fix_date_back(date)

        months = calculate_months(month=date, pending=False, advance=True)

        self.current_advance_months = months

        self.month_till_combo.clear()
        model = self.month_till_combo.model()

        for month in months:
            model.appendRow(QStandardItem(month))

    def calculate_amount(self):
        if self.month_combo.count() == 0 or self.month_till_combo.count() == 0:
            self.amount_line.setText('0')
            return

        else:
            all_possible_months = self.current_advance_months.copy()
            all_possible_months = all_possible_months[::-1]

            all_possible_months.extend([
                x for x in self.current_pending_months
                if x not in self.current_advance_months
            ])

            if self.month_till_combo.isEnabled():
                from_index = all_possible_months.index(
                    self.month_combo.currentText())
                till_index = all_possible_months.index(
                    self.month_till_combo.currentText())

                amount = (from_index - till_index + 1) * 1500

            else:
                amount = 1500

            self.amount_line.setText(str(amount))
            self.amount_line.setToolTip(f"Total months : {amount//1500}")

    def calculate_fine(self, from_where: str, month):
        if month == '' and self.month_combo.count(
        ) == 0 or self.month_till_combo.count() == 0:
            self.fine_line.setText('0')
            return

        else:
            if self.month_till_combo.isEnabled():
                try:
                    till_index = self.current_pending_months.index(
                        str(self.month_till_combo.currentText()))
                except ValueError:
                    till_index = 0
            else:
                try:
                    till_index = self.current_pending_months.index(
                        str(self.month_combo.currentText()))
                except ValueError:
                    self.fine_line.setText('0')
                    return

            try:
                from_index = self.current_pending_months.index(
                    str(self.month_combo.currentText()))
            except ValueError:
                self.fine_line.setText('0')
                return

            all_fine_months = []

            for month in self.current_pending_months[till_index:from_index +
                                                     1]:
                all_fine_months.append([month])

            transact_date = str(self.date_line.date().toPyDate())

            total_fine = 0
            for month in all_fine_months:
                fine = calculate_fine(month=month[0],
                                      transact_date=fix_date(transact_date))
                month = month.append(fine)

                total_fine += fine * 50

            self.fine_line.setText(str(total_fine))
            self.set_fine_tip(all_fine_months=all_fine_months)

    def set_fine_tip(self, all_fine_months: list):
        tool_line = ''

        for month in all_fine_months:
            tool_line += f"{month[0]} x {month[1]}\n"

        self.fine_line.setToolTip(tool_line)

    def set_total(self):
        if len(self.amount_line.text()) > 0:
            amount = float(self.amount_line.text())
        else:
            amount = 0

        if len(self.fine_line.text()) > 0:
            fine = int(self.fine_line.text())
        else:
            fine = 0

        self.total_label.setText(f"TOTAL PAYABLE AMOUNT : {amount + fine}")

    def disable(self):
        self.finance_entry_group0.setEnabled(False)
        self.finance_entry_group1.setEnabled(False)
        self.home_button.setEnabled(False)
        self.mode_label.setEnabled(False)
        self.mode_combo.setEnabled(False)
        self.ref_label.setEnabled(False)
        self.ref_line.setEnabled(False)
        self.save_button.setEnabled(False)

    def enable(self):
        self.finance_entry_group0.setEnabled(True)
        self.finance_entry_group1.setEnabled(True)
        self.home_button.setEnabled(True)
        self.home_button.setEnabled(True)
        self.mode_label.setEnabled(True)
        self.mode_combo.setEnabled(True)
        self.ref_label.setEnabled(True)
        self.ref_line.setEnabled(True)
        self.save_button.setEnabled(True)
Пример #54
0
class RedditScraperWindow(QWidget):
    """The main window of the program."""

    ########### Setup ##################################
    def __init__(self):
        super().__init__()

        self.read_user_config()
        self.load_assets()
        self.initialize_ui()

    def load_assets(self):
        script_folder = os.path.dirname(
            os.path.dirname(os.path.abspath(__file__)))
        asset_folder = os.path.join(script_folder, "assets")
        if os.path.isdir(asset_folder):
            self.download_icon = QIcon(
                os.path.join(asset_folder, 'download_icon.png'))
            self.stop_icon = QIcon(os.path.join(asset_folder, 'stop_icon.png'))
            self.reddit_icon = QIcon(
                os.path.join(asset_folder, 'reddit_icon.png'))
        else:
            self.download_icon = QIcon(
                os.path.join("assets", 'download_icon.png'))
            self.stop_icon = QIcon(os.path.join("assets", 'stop_icon.png'))
            self.reddit_icon = QIcon(os.path.join("assets", 'reddit_icon.png'))

    def initialize_ui(self):
        """sets up the user interface, connects all the signals and shows the window. """

        self.init_components()
        self.read_settings_config()
        self.connect_signals()

        self.setGeometry(100, 100, 1000, 800)
        self.setWindowTitle('Reddit Image Scraper')
        self.setWindowIcon(self.reddit_icon)

        self.show()

    def init_components(self):
        """initializes all components and sets up the layout"""
        internalWidgetInput = QWidget()
        internalWidgetTree = QWidget()

        ############ define components ####################
        self.subredditInput = QComboBox()
        self.subredditInput.setEditable(True)
        self.subredditInput.addItems(self.get_downloaded_subreddits())

        self.numInput = QLineEdit()
        self.onlyInt = QIntValidator()
        self.numInput.setValidator(self.onlyInt)
        subredditLabel = QLabel('subreddit')
        numLabel = QLabel('number of images')
        self.dirLabel = QLabel('choose a directory')
        scale_label = QLabel("Scale images?")
        self.imgView = QLabel()

        self.outputText = QTextEdit('')
        self.outputText.setReadOnly(True)

        self.scale_cb = QCheckBox()

        self.sortingCb = QComboBox()
        self.sortingCb.addItems([
            "Hot", "Top all time", "Top this month", "Top past year", "New",
            "Controversial"
        ])
        sortingLabel = QLabel('sorting method')
        self.runButton = QPushButton('Download')
        self.runButton.setIcon(self.download_icon)
        self.chooseDirButton = QPushButton('Save dir')
        self.stopButton = QPushButton('Stop')
        self.stopButton.setIcon(self.stop_icon)

        self.fileModel = QFileSystemModel()
        self.tree = QTreeView()

        self.tree.setModel(self.fileModel)
        self.tree.setColumnHidden(1, True)
        self.tree.setColumnHidden(2, True)
        self.tree.setColumnHidden(3, True)

        ############## Menu stuff ###################
        menu_bar = QMenuBar()
        file_menu = menu_bar.addMenu('File')
        help_menu = menu_bar.addMenu('Help')

        self.exit_action = QAction('Exit', self)

        file_menu.addAction(self.exit_action)
        self.help_action = QAction('Help', self)
        help_menu.addAction(self.help_action)
        menu_bar.setFixedHeight(30)

        ############# Setup the grid layout###############################
        grid = QGridLayout()
        # grid.addWidget(menu_bar, 1, 0, 1, 4)
        grid.setSpacing(4)
        grid.addWidget(subredditLabel, 1, 0)
        grid.addWidget(self.subredditInput, 1, 1)
        grid.addWidget(numLabel, 2, 0)
        grid.addWidget(self.numInput, 2, 1)
        grid.addWidget(sortingLabel, 3, 0)
        grid.addWidget(self.sortingCb, 3, 1)

        grid.addWidget(self.chooseDirButton, 4, 0)
        grid.addWidget(self.dirLabel, 4, 1)
        grid.addWidget(self.stopButton, 5, 0)
        grid.addWidget(self.runButton, 5, 1)
        grid.addWidget(self.outputText, 7, 0, 7, 2)
        # grid.addWidget(self.tree,1,2, 11,7)

        grid.addWidget(scale_label, 6, 0)
        grid.addWidget(self.scale_cb, 6, 1)

        hboxTree = QVBoxLayout()
        hboxTree.addWidget(self.tree)

        #the image viewer, setting how it behaves under resizing.
        self.imgView.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.imgView.setMaximumHeight(MAX_IMAGE_HEIGHT)

        self.imgView.setAlignment(Qt.AlignmentFlag.AlignCenter)

        img_scroll_area = QScrollArea()
        img_scroll_area.setMinimumHeight(MAX_IMAGE_HEIGHT)
        img_scroll_area.setMinimumWidth(MAX_IMAGE_HEIGHT)
        img_scroll_area.setWidget(self.imgView)

        internalWidgetInput.setLayout(grid)
        # internalWidgetInput.setMinimumWidth(300)
        internalWidgetInput.setFixedWidth(300)
        internalWidgetInput.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding))

        internalWidgetTree.setLayout(hboxTree)
        internalWidgetTree.setFixedWidth(360)
        internalWidgetTree.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding))

        #construct layout of main window.
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setMenuBar(menu_bar)
        hbox.addWidget(internalWidgetInput)
        hbox.addWidget(internalWidgetTree)
        hbox.addWidget(img_scroll_area)
        self.setLayout(hbox)

    def connect_signals(self):
        """connects all the signals to the right functions"""
        self.chooseDirButton.clicked.connect(self.show_dir_dialog)
        self.runButton.clicked.connect(self.run_download_threaded)
        self.tree.clicked.connect(self.on_treeView_clicked)
        self.stopButton.clicked.connect(self.stop_download)
        self.scale_cb.clicked.connect(self.refresh_image)
        self.exit_action.triggered.connect(exit)

        #self.edit_login_action.triggered.connect(self.edit_login_info)
        self.help_action.triggered.connect(self.show_help)

        self.tree.selectionModel().selectionChanged.connect(
            self.on_selection_change)

    def read_user_config(self):
        """reads in the users username and password from the config file, or if there is no config file,
        shows an input dialog.
        Also tests so that only valid login information gets saved to the config file. """
        config = configparser.ConfigParser()
        self.redditScraper = redditScraper()
        if os.path.exists('redditScraper.ini'):
            config.read('redditScraper.ini')

            if 'DIR' in config:
                self.folder = config['DIR']['root_folder']

        else:
            config['REDDIT'] = {
                'subreddit': "wallpapers",
                'num': 10,
                'sorting': "Hot",
                'downloaded_subreddits': ""
            }

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

        self.config = config

    def read_settings_config(self):
        """reads the saved settings from the config file, if they're there."""
        if 'DIR' in self.config:
            self.folder = self.config['DIR']['root_folder']
            idx = self.fileModel.setRootPath(str(self.folder))
            self.tree.setRootIndex(idx)
            self.dirLabel.setText(self.folder)

        if 'REDDIT' in self.config:
            self.subredditInput.setCurrentText(
                self.config['REDDIT']['subreddit'])
            self.numInput.setText(self.config['REDDIT']['num'])
            self.sortingCb.setCurrentText(self.config['REDDIT']['sorting'])

    ################### Actions: ##################
    @pyqtSlot(QModelIndex)
    def on_treeView_clicked(self, index):
        """triggers when the user clicks on a file item shown in the treeView, and shows that file in the picture viewer."""
        index = self.fileModel.index(index.row(), 0, index.parent())
        self.show_image(index)

    def on_selection_change(self, selected: QItemSelection,
                            deselected: QItemSelection):
        """ Triggers when the selected item in the treeview changes, and updates the shown picture. """
        self.refresh_image()

    def refresh_image(self):
        selected_image_index = self.tree.selectedIndexes()[0]
        self.show_image(selected_image_index)

    def show_image(self, index: QModelIndex):
        filePath = self.fileModel.filePath(index)
        if os.path.isfile(filePath) and filePath.split(".")[-1] in [
                "jpg", "gif", "png", "jpeg"
        ]:
            pixmap = QPixmap(filePath)
            if self.scale_cb.isChecked():
                self.imgView.setFixedHeight(MAX_IMAGE_HEIGHT)
                scaled_img = pixmap.scaledToHeight(MAX_IMAGE_HEIGHT)
                self.imgView.setFixedWidth(scaled_img.width())
                self.imgView.setPixmap(scaled_img)
            else:
                self.imgView.setFixedHeight(pixmap.height())
                self.imgView.setFixedWidth(pixmap.width())
                self.imgView.setPixmap(pixmap)

    def show_dir_dialog(self):
        """lets the user select the root folder, and saves the choice to the config file."""

        self.folder = QFileDialog.getExistingDirectory(
            self, 'Choose base directory', '/home')
        self.dirLabel.setText(self.folder)

        self.config['DIR'] = {'root_folder': self.folder}
        with open('redditScraper.ini', 'w') as configfile:
            self.config.write(configfile)

        idx = self.fileModel.setRootPath(self.folder)
        self.tree.setRootIndex(idx)

        return self.folder

    @pyqtSlot(str)
    def update_output_text(self, message: str):
        """updates the output text area, to show progress on downloads."""
        self.outputText.setText(message + self.outputText.toPlainText())

    def save_subreddit(self, subreddit: str, num: int, sorting: str):
        """helper function to save the current settings to the config file."""
        downloaded_subreddits = self.get_downloaded_subreddits()
        if subreddit not in downloaded_subreddits:
            downloaded_subreddits.append(subreddit)
            self.subredditInput.addItem(subreddit)

        downloaded_subreddits = ','.join(downloaded_subreddits)
        self.config['REDDIT'] = {
            'subreddit': subreddit,
            'num': str(num),
            'sorting': sorting,
            'downloaded_subreddits': downloaded_subreddits
        }

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

    def get_downloaded_subreddits(self) -> list:
        if 'downloaded_subreddits' in self.config['REDDIT'].keys():
            subreddits = self.config['REDDIT']['downloaded_subreddits'].split(
                ',')
            return subreddits
        return []

    def run_download_threaded(self):
        """downloads the pictures. Runs in a QThread, so that the program does not freeze.
        Also checks whether the specified subreddit exists. """
        subreddit = self.subredditInput.currentText()
        num = int(self.numInput.text())
        sorting = self.sortingCb.currentText()

        if self.redditScraper.sub_exists(subreddit):

            if not hasattr(self, "folder"):
                msgBox = QMessageBox()
                msgBox.setText('You need to set a download folder!')
                msgBox.setWindowTitle("Pick a download folder")
                msgBox.exec_()
                return

            self.save_subreddit(subreddit, num, sorting)
            self.get_thread = RedditDownloadThread(
                self.redditScraper, subreddit, num,
                num * LOOKUP_LIMIT_MULTIPLIER, sorting, self.folder)
            self.get_thread.changeText.connect(self.update_output_text)
            self.get_thread.start()
        else:
            msgBox = QMessageBox()
            msgBox.setText('That subreddit does not exist, please try again')
            msgBox.setWindowTitle("Invalid subreddit")
            msgBox.exec_()

        pass

    def stop_download(self):
        """Stops the download thread and prints a message to the output."""
        try:
            if self.get_thread.isRunning():
                self.get_thread.terminate()
                self.outputText.setText(self.outputText.toPlainText() +
                                        ' Aborted!\n')
        except Exception:
            pass

    ############### Menu actions: ###############

    def show_help(self):
        msgBox = QMessageBox()

        msgBox.setWindowIcon(self.reddit_icon)
        msgBox.setText(
            'This program downloads images posted to reddit.com, or more specifically, to subreddits'
            +
            '(i.e. sub-forums). To use it, one needs a valid reddit account, which one can sign up for '
            +
            'on reddit.com. One also needs to know some names of subreddits. \n Some suggestions for subreddits: '
            + 'wallpapers , earthporn , nature , and pics . \n \n ' +
            "This program will download up to the specified number of images. It can handle png, jpg and gif,"
            +
            "so links to gyf-files, videos or anything else will be ignored. Therefore the number of images actually "
            +
            "downloaded will usually be less than the specified number. So if you want a lot of images, just put"
            +
            " a large limit.\n The images will be placed in a subfolder of the chosen base folder, named after the subreddit. This folder will be created if it does not exist.\n \n "
            +
            "To view the images, click on them in the tree-view, and they will appear on the right"
        )
        msgBox.setWindowTitle("Help")
        msgBox.exec_()
Пример #55
0
class BookManage(QGroupBox):
    def __init__(self):
        super().__init__()
        self.book_list = []
        self.body = QVBoxLayout()
        self.table = None
        self.setTitleBar()
        self.setSearchBar()
        self.searchFunction()

        self.setLayout(self.body)
        self.initUI()


    def errorBox(self, mes: str):
        msgBox = QMessageBox(
            QMessageBox.Warning,
            "警告!",
            mes,
            QMessageBox.NoButton,
            self
        )
        msgBox.addButton("确认", QMessageBox.AcceptRole)
        msgBox.exec_()

    # 标题栏
    def setTitleBar(self):
        self.title = QLabel()
        self.title.setText('书籍信息管理')
        self.title.setFixedHeight(25)
        titleLayout = QHBoxLayout()
        titleLayout.addSpacing(50)
        titleLayout.addWidget(self.title)
        self.titleBar = QWidget()
        self.titleBar.setFixedSize(1000, 50)
        self.titleBar.setLayout(titleLayout)
        self.body.addWidget(self.titleBar)

    # 设置搜索框
    def setSearchBar(self):
        self.selectBox = QComboBox()
        self.selectBox.addItems(['书号', '分类', '出版社', '作者', '书名'])
        self.selectBox.setFixedHeight(30)
        self.searchTitle = QLabel()
        self.searchTitle.setText('搜索书籍')
        self.searchInput = QLineEdit()
        self.searchInput.setText('')
        self.searchInput.setClearButtonEnabled(True)
        self.searchInput.setFixedSize(400, 40)
        self.searchButton = QToolButton()
        self.searchButton.setFixedSize(100, 40)
        self.searchButton.setText('搜索')
        self.searchButton.clicked.connect(self.searchFunction)
        self.addNewBookButton = QToolButton()
        self.addNewBookButton.setFixedSize(120, 40)
        self.addNewBookButton.setText('插入新书')
        self.addNewBookButton.clicked.connect(self.addNewBookFunction)
        searchLayout = QHBoxLayout()
        searchLayout.addStretch()
        searchLayout.addWidget(self.selectBox)
        searchLayout.addWidget(self.searchTitle)
        searchLayout.addWidget(self.searchInput)
        searchLayout.addWidget(self.searchButton)
        searchLayout.addWidget(self.addNewBookButton)
        searchLayout.addStretch()
        self.searchWidget = QWidget()
        self.searchWidget.setLayout(searchLayout)
        self.body.addWidget(self.searchWidget)

    # 搜索方法
    def searchFunction(self):
        convert = {'书号': 'BID', '分类': 'CLASSIFICATION', '出版社': 'PRESS', '作者': 'AUTHOR', '书名': 'BNAME', '': 'BNAME'}
        self.book_list = database.search_book(self.searchInput.text(), convert[self.selectBox.currentText()])
        if self.book_list == []:
            self.errorBox('未找到')
        if self.table is not None:
            self.table.deleteLater()
        self.setTable()

    # 设置表格
    def setTable(self):
        self.table = QTableWidget(1, 9)
        self.table.setContentsMargins(10, 10, 10, 10)
        self.table.verticalHeader().setVisible(False)
        self.table.horizontalHeader().setVisible(False)
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setFocusPolicy(Qt.NoFocus)
        self.table.setColumnWidth(0, 80)
        # self.table.setColumnWidth(1, 150)
        # self.table.setColumnWidth(2, 125)
        # self.table.setColumnWidth(3, 125)
        # self.table.setColumnWidth(4, 100)
        self.table.setColumnWidth(6, 80)

        self.table.setItem(0, 0, QTableWidgetItem('书号'))
        self.table.setItem(0, 1, QTableWidgetItem('书名'))
        self.table.setItem(0, 2, QTableWidgetItem('作者'))
        self.table.setItem(0, 3, QTableWidgetItem('出版日期'))
        self.table.setItem(0, 4, QTableWidgetItem('出版社'))
        self.table.setItem(0, 5, QTableWidgetItem('分类'))
        self.table.setItem(0, 6, QTableWidgetItem('位置'))
        self.table.setItem(0, 7, QTableWidgetItem('总数/剩余'))
        self.table.setItem(0, 8, QTableWidgetItem('操作'))

        for i in range(9):
            self.table.item(0, i).setTextAlignment(Qt.AlignCenter)
            self.table.item(0, i).setFont(QFont('微软雅黑', 15))

        # 显示借阅详情
        for i in self.book_list:
            self.insertRow(i)
        self.body.addWidget(self.table)

    # 插入行
    def insertRow(self, val: list):
        itemBID = QTableWidgetItem(val[0])
        itemBID.setTextAlignment(Qt.AlignCenter)

        itemNAME = QTableWidgetItem('《' + val[1] + '》')
        itemNAME.setTextAlignment(Qt.AlignCenter)

        itemAUTHOR = QTableWidgetItem(val[2])
        itemAUTHOR.setTextAlignment(Qt.AlignCenter)

        itemDATE = QTableWidgetItem(val[3])
        itemDATE.setTextAlignment(Qt.AlignCenter)

        itemPRESS = QTableWidgetItem(val[4])
        itemPRESS.setTextAlignment(Qt.AlignCenter)

        itemPOSITION = QTableWidgetItem(val[5])
        itemPOSITION.setTextAlignment(Qt.AlignCenter)

        itemSUM = QTableWidgetItem(str(val[6])+'/'+str(val[7]))
        itemSUM.setTextAlignment(Qt.AlignCenter)

        itemCLASSIFICATION = QTableWidgetItem(val[8])
        itemCLASSIFICATION.setTextAlignment(Qt.AlignCenter)

        itemModify = QToolButton(self.table)
        itemModify.setFixedSize(50, 25)
        itemModify.setText('修改')
        itemModify.clicked.connect(lambda: self.updateBookFunction(val[0]))
        itemModify.setStyleSheet('''
        *{
            color: white;
            font-family: 微软雅黑;
            background: rgba(38, 175, 217, 1);
            border: 0;
            border-radius: 10px;
        }
        ''')
        itemDelete = QToolButton(self.table)
        itemDelete.setFixedSize(50, 25)
        itemDelete.setText('删除')
        itemDelete.clicked.connect(lambda: self.deleteBookFunction(val[0]))
        itemDelete.setStyleSheet('''
        *{
            color: white;
                font-family: 微软雅黑;
                background: rgba(222, 52, 65, 1);
                border: 0;
                border-radius: 10px;
        }
        ''')

        itemLayout = QHBoxLayout()
        itemLayout.setContentsMargins(0, 0, 0, 0)
        itemLayout.addWidget(itemModify)
        itemLayout.addWidget(itemDelete)
        itemWidget = QWidget()
        itemWidget.setLayout(itemLayout)

        self.table.insertRow(1)
        self.table.setItem(1, 0, itemBID)
        self.table.setItem(1, 1, itemNAME)
        self.table.setItem(1, 2, itemAUTHOR)
        self.table.setItem(1, 3, itemDATE)
        self.table.setItem(1, 4, itemPRESS)
        self.table.setItem(1, 5, itemCLASSIFICATION)
        self.table.setItem(1, 6, itemPOSITION)
        self.table.setItem(1, 7, itemSUM)
        self.table.setCellWidget(1, 8, itemWidget)

    def updateBookFunction(self, BID: str):
        book_info = database.get_book_info(BID)
        if book_info is None:
            return
        self.sum = book_info['SUM']
        self.updateBookDialog = book_information.BookInfo(book_info)
        self.updateBookDialog.after_close.connect(self.updateBook)
        self.updateBookDialog.show()

    def updateBook(self, book_info: dict):
        change = self.sum - book_info['SUM']
        # 书本减少的数量不能大于未借出的书本数
        if change > book_info['NUM']:
            book_info['SUM'] = self.sum - book_info['NUM']
            book_info['NUM'] = 0
        else:
            book_info['NUM'] -= change
        ans = database.update_book(book_info)
        if ans:
            self.searchFunction()

    def addNewBookFunction(self):
        self.newBookDialog = book_information.BookInfo()
        self.newBookDialog.show()
        self.newBookDialog.after_close.connect(self.addNewBook)

    def addNewBook(self, book_info: dict):
        ans = database.new_book(book_info)
        if ans:
            self.searchFunction()

    def deleteBookFunction(self, BID: str):
        msgBox = QMessageBox(QMessageBox.Warning, "警告!", '您将会永久删除这本书以及相关信息!',
                             QMessageBox.NoButton, self)
        msgBox.addButton("确认", QMessageBox.AcceptRole)
        msgBox.addButton("取消", QMessageBox.RejectRole)
        if msgBox.exec_() == QMessageBox.AcceptRole:
            ans = database.delete_book(BID)
            if ans:
                self.searchFunction()

    def initUI(self):
        self.setFixedSize(1100, 600)
        self.setStyleSheet('''
        *{
            background-color: white;
            border:0px;
        }
        ''')
        self.titleBar.setStyleSheet('''
        QWidget {
            border:0;
            background-color: rgba(216, 216, 216, 1);
            border-radius: 20px;
            color: rgba(113, 118, 121, 1);
        }
        QLabel{
            font-size: 25px;
            font-family: 微软雅黑;
        }
        ''')
        self.searchTitle.setStyleSheet('''
            QLabel{
                font-size:25px;
                color: black;
                font-family: 微软雅黑;
            }
        ''')
        self.searchInput.setStyleSheet('''
            QLineEdit{
                border: 1px solid rgba(201, 201, 201, 1);
                border-radius: 5px;
                color: rgba(120, 120, 120, 1)
            }
        ''')
        self.searchButton.setStyleSheet('''
            QToolButton{
                border-radius: 10px;
                background-color:rgba(135, 206, 235, 1);
                color: white;
                font-size: 25px;
                font-family: 微软雅黑;
            }
        ''')
        self.addNewBookButton.setStyleSheet('''
            QToolButton{
                border-radius: 10px;
                background-color:rgba(135, 206, 235, 1);
                color: white;
                font-size: 25px;
                font-family: 微软雅黑;
            }
        ''')
        self.selectBox.setStyleSheet('''
        *{
            border: 0px;
        }
        QComboBox{
            border: 1px solid rgba(201, 201, 201, 1);
        }
        ''')
Пример #56
0
class CourseInputDialog(QWidget):
    loaddashlayout = pyqtSignal(int)
    refreshCourses_request = pyqtSignal()

    def __init__(self, user: User, parent=None):
        super(CourseInputDialog, self).__init__(parent)
        self.controller = CourseInputController()
        self.user = user
        if (isinstance(user, Professor) == True):
            self.StartProf()
        elif (isinstance(user, Student) == True):
            self.StartStud()

#*****************************************************************************************************

    def StartStud(self):

        self.setWindowTitle("Enroll in a Course")
        layout = QVBoxLayout()
        self.Hbox = QHBoxLayout()
        self.fram = QFrame()
        self.cb = QComboBox()
        self.cb_courses = QComboBox()
        self.enroll_button = QPushButton("Enroll In Course")
        self.enroll_button.setObjectName("enroll_button")
        self.enroll_button.setFixedWidth(200)
        self.Hbox.addWidget(self.enroll_button)
        self.fram.setLayout(self.Hbox)
        self.enroll_button.clicked.connect(lambda: self.enrollStudent())
        self.error_message = QLabel("")

        self.info = self.controller.getAllCourses()
        self.item = []

        for courseID, faculty, courseName in self.info:
            if ((str(faculty) in self.item) == False):
                self.cb.addItem(str(faculty))
                self.item.append(faculty)

        self.courses = self.controller.getCoursePerFaculty(
            self.cb.currentText())
        self.cb_courses.clear()
        self.courseIDs = []
        for courseIds, coursenames in self.courses:
            self.cb_courses.addItem(coursenames)
            self.courseIDs.append(courseIds)

        self.cb.currentIndexChanged.connect(self.selectionchange)
        self.cb_courses.currentIndexChanged.connect(
            self.selectionchangeCourses)
        layout.addWidget(self.cb)
        layout.addWidget(self.cb_courses)
        layout.addWidget(self.fram)
        layout.addWidget(self.error_message)

        #self.cb.setStyleSheet("QComboBox { background-color: white; }")
        #self.cb_courses.setStyleSheet("QComboBox { background-color: white; }")
        self.setLayout(layout)

    def selectionchange(self, i):
        for count in range(self.cb.count()):
            self.cb.itemText(count)

        self.courses = self.controller.getCoursePerFaculty(
            self.cb.currentText())
        self.cb_courses.clear()
        self.courseIDs = []
        for courseIds, coursenames in self.courses:
            self.cb_courses.addItem(coursenames)
            self.courseIDs.append(courseIds)

    def selectionchangeCourses(self, i):

        for count in range(self.cb_courses.count()):
            self.cb_courses.itemText(count)

    def enrollStudent(self):
        courseID = self.courseIDs[self.cb_courses.currentIndex()]
        result = self.controller.EnrollStudent(courseID, self.user.id,
                                               self.cb_courses.currentText())
        if (result == 0):
            self.error_message.setText("Database error Enrolling in course")
        elif (result == 1):

            self.refreshCourses_request.emit()
            self.loaddashlayout.emit(4)


#Student
#*******************************************************************************************************
#Professor

    def StartProf(self):

        self.layout = QFormLayout()

        self.le = QLineEdit()

        self.btn1 = QLabel("Course Name")

        self.le1 = QLineEdit()
        self.layout.addRow(self.btn1, self.le1)
        self.btn2 = QLabel("Description")

        self.le2 = QLineEdit()
        self.le2.setFixedHeight(150)

        self.done = QPushButton("Done")
        self.done.setObjectName("done")
        self.done.clicked.connect(lambda: self.SubmitCourse())

        self.cancel = QPushButton("Cancel")
        self.cancel.setObjectName("cancel")
        self.cancel.clicked.connect(lambda: self.goBack())

        self.layout.addRow(self.btn2, self.le2)

        self.facultyIndicator = QLabel("Faculty")
        self.faculty = QLineEdit()

        self.typeIndicator = QLabel("Type")
        self.typeOfCourse = QLineEdit()
        self.layout.addRow(self.facultyIndicator, self.faculty)
        self.layout.addRow(self.typeIndicator, self.typeOfCourse)
        self.layout.addRow(self.cancel, self.done)

        self.setLayout(self.layout)
        self.setWindowTitle("Add Course")

        self.errorText = QLabel("")
        self.layout.addRow(self.errorText)

    #Contacts controller with proper input to add course to database
    def SubmitCourse(self):
        result = self.controller.addCourse(self.le1.text(), self.le2.text(),
                                           self.user.id, self.faculty.text(),
                                           self.typeOfCourse.text())
        if (result == 1):
            #            self.errorText.setText("Course Added Successfully")

            self.refreshCourses_request.emit()
            self.loaddashlayout.emit(1)

        elif (result == 0):
            self.errorText.setText("Database Error")
        elif (result == 2):
            self.errorText.setText("Course Already Added Before")
        elif (result == 3):
            self.errorText.setText("Youtube Error")
        else:
            self.errorText.setText("Unknown Error")

    def goBack(self):
        self.loaddashlayout.emit(0)
Пример #57
0
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.row = -1

    def initUI(self):
        # self.setGeometry(300, 300, 300, 220)
        self.resize(1144, 400)
        self.setMinimumSize(624, 400)
        # self.setMinimumSize(1144, 400)
        self.center()
        self.setWindowTitle('Xmind转Excel')
        self.setWindowIcon(QIcon(':/contacts.png'))
        # self.setWindowIcon(QIcon("../Icon/window.ico"))
        layout = QVBoxLayout()

        self.column = 6

        # 使用水平布局
        self.tablewidget = QTableWidget()

        self.tablewidget.setColumnCount(self.column)
        self.tablewidget.setSelectionBehavior(
            QAbstractItemView.SelectRows)  # 设置表格的选取方式是行选取
        self.tablewidget.setSelectionMode(
            QAbstractItemView.SingleSelection)  # 设置选取方式为单个选取
        self.tablewidget.setHorizontalHeaderLabels(
            ['#ID', '用例名称', '预期结果', '用例等级', '需求ID', '用例类型'])
        self.tablewidget.setAlternatingRowColors(True)  # 行是否自动变色
        self.tablewidget.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)  # 设置列宽的适应方式
        # self.tablewidget.setColumnWidth(1, 350)

        self.qc = QComboBox(self)
        self.qc.addItems(['请选择用例类型', '功能测试', '冒烟测试', '回归测试'])

        self.qc.activated[str].connect(self.onActivated)

        # self.tablewidget.itemChanged.connect(QCoreApplication.instance().quit)
        self.tablewidget.itemChanged.connect(self.table_update)

        self.button1 = QPushButton("选择XMind文件", self)
        self.button1.clicked.connect(self.read_XMind)

        self.button2 = QPushButton("转成Excel", self)
        self.button2.clicked.connect(self.to_Excel)

        layout.addWidget(self.tablewidget)
        layout.addWidget(self.qc)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        self.setLayout(layout)

        self.show()

    def read_XMind(self):
        # self.tablewidget.clearContents()  # 清除所有数据--不包括标题头
        for i in range(1, self.row + 1):
            self.tablewidget.removeRow(0)
        self.tablewidget.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.qc.setCurrentIndex(0)

        fileName, _ = QFileDialog.getOpenFileName(self, "打开文件", ".",
                                                  "XMind(*.xmind)")

        if fileName == '':
            return
        ds = XMindData.read_XMind_to_list(fileName)[0]["topic"]
        # 获取头节点title,就是需求名
        self.title = ds["title"]
        # 获取头节点下的其余所有节点内容
        nodes_data = ds["topics"]
        # 创建XMData格式化xMind读取的数据
        md = XMindData()
        # 清空缓存数据
        md.clear_init_list_data()
        # 调用
        data = md.get_lists_data(data=nodes_data)
        # 动态设置行
        self.row = len(data)
        # 设置表格的行
        self.tablewidget.setRowCount(self.row)
        for case in enumerate(data):
            # id
            item1 = QTableWidgetItem(str(case[0] + 1))
            # 需求名
            # item2 = QTableWidgetItem("_".join(case[1][:3]))

            item_1 = "_".join(case[1][:-2])
            item_2 = item_1.replace('_', '', 1)

            # aaa=re.findall(r"\d+\.?\d*", item_2)
            # print(aaa[0])
            # item2 = QTableWidgetItem(item_2)
            # item2 = str(items).replace('_','',1)
            # 模块名
            item3 = QTableWidgetItem(case[1][-2])
            # 用例
            item4 = QTableWidgetItem(case[1][-1])
            item2 = None
            item5 = None

            # 需求ID
            bool1 = False
            try:
                # item2 = QTableWidgetItem(re.sub(re.findall(r"\d+\.?\d*", item_2)[0], '', item_2))
                item2 = QTableWidgetItem(
                    re.sub(re.findall(r"\d+\.?\d*", item_2)[0], '', item_2))
                item5 = QTableWidgetItem(
                    re.findall(r"\d+\.?\d*", case[1][0])[0])
                bool1 = True
            except:
                item2 = QTableWidgetItem(item_2)
                pass

            # print(re.sub(re.findall(r"\d+\.?\d*", item_2)[0],'',item_2))

            self.tablewidget.setItem(case[0], 0, item1)
            self.tablewidget.setItem(case[0], 1, item2)
            self.tablewidget.setItem(case[0], 2, item3)
            self.tablewidget.setItem(case[0], 3, item4)

            if bool1:
                self.tablewidget.setItem(case[0], 4, item5)

        for i in range(0, self.row + 1):
            item6 = QTableWidgetItem(None)
            self.tablewidget.setItem(i, 5, item6)
        self.qc.setCurrentIndex(0)  # 设置下拉框默认值
        self.tablewidget.horizontalHeader().setSectionResizeMode(
            QHeaderView.Fixed)
        self.tablewidget.setColumnWidth(1, 400)
        self.tablewidget.setColumnWidth(2, 400)

        for i in [0, 3, 4, 5]:
            self.tablewidget.setColumnWidth(i, 70)
        fileName = ''

    def table_update(self):
        """
        如果表格被编辑,则会保存编辑后的数据
        """
        self.tablewidget.selectedItems()

    def to_Excel(self):
        """
        保存到Excel中
        """

        if self.row == -1:
            QMessageBox.about(self, "请先选择", '请先选择Xmind文件...')
            self.qc.setCurrentIndex(0)
            return
        # 返回值是一个元祖,需要两个参数接收,第一个是文件名,第二个是文件类型
        fileName, fileType = QFileDialog.getSaveFileName(
            self, "保存Excel", self.title, "xlsx(*.xlsx)")

        if fileName == "":
            return
        else:
            try:
                if not fileName.endswith('.xlsx'):
                    # 如果后缀不是.xlsx,那么就加上后缀
                    fileName = fileName + '.xlsx'
                QMessageBox.about(self, "转换中...", '转换中,可能会有延迟,请不要关闭应用...')
                we = ExcelData(file_name=fileName)
                # 创建Excel
                we.creat_excel_and_set_title(titles=[
                    '#ID', '用例名称', '预期结果', '用例等级', '需求ID', '用例类型', '前置条件',
                    '操作步骤', '实际结果'
                ])

                # 保存并写入(表格中更新后的数据)写入从第二行开始写入(行需要+1,列需要+1)
                for r in range(self.row):
                    for c in range(self.column):
                        # print(self.tablewidget.item(r, c))
                        if self.tablewidget.item(r, c) is None:
                            # if self.tablewidget.item(r, c).text() is None:
                            we.write_excel_data(row=r + 2,
                                                column=c + 1,
                                                value='')
                            continue
                        we.write_excel_data(row=r + 2,
                                            column=c + 1,
                                            value=self.tablewidget.item(
                                                r, c).text())
                QMessageBox.about(self, "写入Excel",
                                  "写入Excel成功!\n路径:{}".format(fileName))
            except Exception as e:
                QMessageBox.critical(self, "写入Excel",
                                     "出错了,请重试!!!\n错误信息:{}".format(e),
                                     QMessageBox.Yes, QMessageBox.Yes)

    def onActivated(self, text):  # 把下拉列表框中选中的列表项的文本显示在标签组件上
        if self.row == -1:
            QMessageBox.about(self, "请先选择", '请先选择Xmind文件...')
            self.qc.setCurrentIndex(0)
        for i in range(0, self.row + 1):
            if self.qc.currentText() == '请选择用例类型':
                item6 = QTableWidgetItem(None)
            else:
                item6 = QTableWidgetItem(self.qc.currentText())
            self.tablewidget.setItem(i, 5, item6)

        # 退出提醒
    def closeEvent(self, event):
        reply = QMessageBox.question(self, '退出提醒', "确认退出吗?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    # 居中显示
    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
Пример #58
0
class Window(QDialog):
    def __init__(self):
        super().__init__()

        self.title = "PyQt5 Window"
        self.top = 100
        self.left = 100
        self.width = 400
        self.height = 150
        self.lang = "java19"

        self.setWindowTitle(self.title)
        self.setFixedSize(self.width, self.height)

        self.create_layout()

        vbox_layout = QVBoxLayout()
        vbox_layout.addWidget(self.group_box)
        self.setLayout(vbox_layout)

        self.show()

    def create_layout(self):
        vbox_layout = QVBoxLayout()

        hbox_layout = QHBoxLayout()

        btn_source = QPushButton("Choose Source", self)
        btn_source.setMinimumHeight(28)
        btn_source.clicked.connect(self.click_source_btn)
        hbox_layout.addWidget(btn_source)

        btn_destination = QPushButton("Choose Destination", self)
        btn_destination.setMinimumHeight(28)
        btn_destination.clicked.connect(self.click_destination_btn)
        hbox_layout.addWidget(btn_destination)

        btn_start = QPushButton("Start", self)
        btn_start.setMinimumHeight(28)
        btn_start.clicked.connect(self.click_start_btn)
        hbox_layout.addWidget(btn_start)

        vbox_layout.addLayout(hbox_layout)

        self.lang_cb = QComboBox()
        self.lang_cb.addItems(
            "java19,java17,java15,java15dm,java12,java11,python3,c/c++,c#-1.2,char,text,scheme"
            .split(","))
        self.lang_cb.currentIndexChanged.connect(
            self.selection_changed_lang_gb)
        vbox_layout.addWidget(self.lang_cb)

        self.group_box = QGroupBox("JPlag Wrapper")
        self.group_box.setLayout(vbox_layout)

    def click_source_btn(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)

        if dlg.exec_() == QFileDialog.Accepted:
            self.source_dir = dlg.selectedFiles()[0]
            logging.info("Source dir: '%s'", dlg.selectedFiles())
            print(dlg.selectedFiles())

    def click_destination_btn(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)

        if dlg.exec_() == QFileDialog.Accepted:
            self.destination_dir = dlg.selectedFiles()[0]
            logging.info("Destination dir: '%s'", dlg.selectedFiles())
            print(dlg.selectedFiles())

    def click_start_btn(self):
        logging.info("JPlag started with source: '%s' and destination: '%s'",
                     self.source_dir, self.destination_dir)
        print("Started with source: {} and destination: {}".format(
            self.source_dir, self.destination_dir))
        jplag_process = subprocess.run(
            f"java -jar ./jplag.jar -l {self.lang} -s '{self.source_dir}' -r '{self.destination_dir}'",
            shell=True,
            stdout=subprocess.PIPE)

        with open("jplag_output.txt", "w") as jplag_output_fd:
            jplag_output_fd.write(jplag_process.stdout.decode())

        logging.info("JPlag completed.")
        print("JPlag completed.")

    def selection_changed_lang_gb(self, i):
        logging.info("Selection changed to %s", self.lang_cb.currentText())
        print("Selection changed to", self.lang_cb.currentText())
        self.lang = self.lang_cb.currentText()
Пример #59
0
class search(QWidget):
    def __init__(self):
        super().__init__()
        self.combo_text = ''
        self.searchUI()

    def searchUI(self):
        self.combo = QComboBox()
        self.label = QLabel("검색:")
        self.lineEdit = QLineEdit()
        self.pushbtn = QPushButton("확인")
        self.table = QTableWidget()

        self.table.resize(700, 400)
        self.table.setAlternatingRowColors(True)

        self.pushbtn.clicked.connect(self.search)
        self.lineEdit.returnPressed.connect(self.search)
        self.combo.currentIndexChanged.connect(self.combo_act)

        # combobox
        self.combo.addItem('TYPE')
        self.combo.addItem('ITEM')
        self.combo.addItem('PU')
        # self.combo.addItem('LR')
        self.combo.addItem('LQ')
        # self.combo.addItem('PSN')
        # self.combo.addItem('STN')
        # self.combo.addItem('W')

        Hbox = QHBoxLayout()
        Hbox.addWidget(self.label)
        Hbox.addWidget(self.combo)
        Hbox.addWidget(self.lineEdit)
        Hbox.addWidget(self.pushbtn)

        Vbox = QVBoxLayout()
        Vbox.addLayout(Hbox)
        Vbox.addWidget(self.table)

        self.setLayout(Vbox)

        self.setWindowTitle('Ybio')
        self.setWindowIcon(QIcon('Ybio.png'))
        self.resize(750, 450)
        self.show()

    def search(self):
        search_text = self.lineEdit.text()
        search_text = search_text.upper()

        if self.combo_text == 'TYPE':
            reply = QMessageBox(self)
            reply.question(self, 'ERROR', 'TYPE을 입력하세요.', QMessageBox.Yes)
            DF = pd.DataFrame()

        if self.combo_text == 'ITEM':
            func = self.ITEM_f()
            df = self.ITEM
        elif self.combo_text == 'PU':
            df = self.PU_f()
        elif self.combo_text == 'LQ':
            df = self.LQ_f()

        if self.combo_text != 'TYPE':
            df_search = df['NAME'].str.contains(search_text)
            DF = df[df_search]

        if DF.empty:
            self.reply = QMessageBox(self)
            self.reply.question(self, 'Error', '검색되지 않습니다.', QMessageBox.Yes)
        else:
            self.numROW = len(DF)
            self.numCOL = len(DF.columns)

            self.table.setRowCount(self.numROW)
            self.table.setColumnCount(self.numCOL)

            self.table.setHorizontalHeaderLabels(DF.columns.tolist())
            self.v_list = DF.values.tolist()

            for m, n in zip(self.v_list, range(self.numROW)):
                for a, b in zip(range(self.numCOL), m):
                    b = str(b)
                    self.table.setItem(n, a, QTableWidgetItem(b))

    def ITEM_f(self):
        self.ITEM_3 = pd.read_excel("Z:/ANRT/물품구매/INVENTORY(2.0).xlsx",
                                    sheet_name='M')
        self.ITEM_2 = self.ITEM_3.drop(self.ITEM_3.index[0:6])
        self.ITEM_2.columns = [
            '1', '2', '3', 'PSNID', 'ITID', 'VENID', 'CATID', '판매자',
            'SUPPLYER', 'CAT', 'NAME', 'QUAN', '단가', '구매요청일', '담당자', '15',
            '16', '17', '18'
        ]
        self.ITEM = self.ITEM_2[[
            'PSNID', 'CAT', '구매요청일', 'NAME', 'SUPPLYER', 'CATID', '담당자', '판매자'
        ]]
        self.ITEM = self.ITEM.fillna('-')
        P = self.ITEM['NAME'] != 0
        self.ITEM = self.ITEM[P]
        self.ITEM = self.ITEM.sort_values(["PSNID"], ascending=[False])
        self.ITEM = self.ITEM.reset_index(drop=True)
        for i in range(len(self.ITEM)):
            X = self.ITEM['구매요청일'][i]
            x = str(X)[0:10]
            self.ITEM['구매요청일'][i] = x
        self.ITEM['NAME'] = self.ITEM['NAME'].str.upper()
        return self.ITEM

    def PU_f(self):
        self.PU_3 = pd.read_excel("Z:/REGI/REGI/REGI008PU(2.0).xlsx",
                                  sheet_name='M')
        self.PU_2 = self.PU_3.drop(self.PU_3.index[0:6])
        self.PU_2.columns = [
            '1', '2', '3', 'PUID', 'TRID', 'SID', 'NAME', 'VOL',
            'PRODUCTIVITY', 'DATE', 'CONC', 'AMOUNT', 'RESEARCHER', 'ELUTION',
            'DIALYSIS', 'METHOD', 'COMMENT', 'BATCH'
        ]
        self.PU = self.PU_2[['PUID', 'TRID', 'NAME', 'SID', 'DATE']]
        self.PU['DATE'] = self.PU.loc[:, 'DATE'].dt.strftime('%Y-%m-%d')
        self.PU = self.PU.sort_values(["PUID"], ascending=[False])
        self.PU = self.PU.reset_index(drop=True)
        self.PU = self.PU.fillna('-')
        self.PU['NAME'] = self.PU['NAME'].str.upper()
        return self.PU

    def LQ_f(self):
        self.LQ_3 = pd.read_excel("Z:/REGI/REGI/REGI008LQV2.xlsx",
                                  sheet_name='Main')
        self.LQ_2 = self.LQ_3.drop(self.LQ_3.index[0:6])
        self.LQ = self.LQ_2[[
            'Unnamed: 4', 'Unnamed: 5', 'Unnamed: 8', 'Unnamed: 6',
            'Unnamed: 7'
        ]]
        self.LQ.columns = ['LQID', 'TARGET', 'NAME', 'PUID', 'SID']
        self.LQ = self.LQ.sort_values(["LQID"], ascending=[False])
        self.LQ = self.LQ.reset_index(drop=True)
        self.LQ['NAME'] = self.LQ['NAME'].str.upper()
        return self.LQ

    def combo_act(self):
        self.combo_text = self.combo.currentText()
Пример #60
-1
class EditForm(QDialog):
    def __init__(self):
        super(EditForm, self).__init__()
        self.initUI(self)

    def initUI(self, EditForm):
        layout = QGridLayout(self)

        self.title_label = QLabel("Title:")
        self.title_line_edit = QLineEdit()
        self.rating_label = QLabel("Rating:")
        self.rating_slider = QSlider(Qt.Horizontal)
        self.rating_slider.setMinimum(0)
        self.rating_slider.setMaximum(5)
        self.rating_slider.setValue(0)
        self.rating_slider.setTickPosition(QSlider.TicksBelow)
        self.rating_slider.setTickInterval(5)

        self.review_label = QLabel("Review:")
        self.review_text_edit = QTextEdit()

        self.status_label = QLabel("Status:")
        self.status_combo_box = QComboBox()
        self.status_combo_box.addItems(["Read",
                                        "Currently Reading",
                                        "Want Тo Read"])
        self.edit_button = QPushButton("Edit book")

        layout.addWidget(self.title_label, 0, 0)
        layout.addWidget(self.title_line_edit, 0, 1)
        layout.addWidget(self.rating_label, 1, 0)
        layout.addWidget(self.rating_slider, 1, 1)
        layout.addWidget(self.review_label, 2, 0)
        layout.addWidget(self.review_text_edit, 2, 1)
        layout.addWidget(self.status_label, 3, 0)
        layout.addWidget(self.status_combo_box, 3, 1)
        layout.addWidget(self.edit_button, 4, 0, 1, 2, Qt.AlignCenter)

        self.setLayout(layout)
        self.edit_button.clicked.connect(self.edit_button_click)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle("Edit Book")
        self.setWindowIcon(QIcon(QPixmap('../images/edit.png')))

    def edit_button_click(self):
        title = self.title_line_edit.text()
        rating = self.rating_slider.value()
        review = self.review_text_edit.toPlainText()
        status = self.status_combo_box.currentText()

        if select_by_title(string.capwords(title)) == []:
            QMessageBox(QMessageBox.Critical, "Error",
                        "There is no such book in the library!").exec_()
        else:
            if update_entry(string.capwords(title), rating, review, status):
                QMessageBox(QMessageBox.Information, "Updated book info",
                            "You updated the info about this book!").exec_()
            else:
                QMessageBox(QMessageBox.Information, "Information",
                            "The book was NOT edited! Try again.").exec_()