示例#1
0
class ReactionBox(QGraphicsItem):
    """Handle to the line edits on the map"""
    def __init__(self, parent: MapView, r_id: str, name):
        QGraphicsItem.__init__(self)

        self.map = parent
        self.id = r_id
        self.name = name

        self.item = QLineEdit()
        self.item.setMaximumWidth(80)
        r = self.map.appdata.project.cobra_py_model.reactions.get_by_id(r_id)
        text = "Id: " + r.id + "\nName: " + r.name \
            + "\nEquation: " + r.build_reaction_string()\
            + "\nLowerbound: " + str(r.lower_bound) \
            + "\nUpper bound: " + str(r.upper_bound) \
            + "\nObjective coefficient: " + str(r.objective_coefficient)

        self.item.setToolTip(text)
        self.proxy = self.map.scene.addWidget(self.item)
        self.proxy.show()

        palette = self.item.palette()
        palette.setColor(QPalette.Base, self.map.appdata.default_color)
        role = self.item.foregroundRole()
        palette.setColor(role, Qt.black)
        self.item.setPalette(palette)

        self.setCursor(Qt.OpenHandCursor)
        self.setAcceptedMouseButtons(Qt.LeftButton)
        self.item.textEdited.connect(self.value_changed)
        self.item.returnPressed.connect(self.returnPressed)

        self.item.setContextMenuPolicy(Qt.CustomContextMenu)
        self.item.customContextMenuRequested.connect(self.on_context_menu)

        # create context menu
        self.pop_menu = QMenu(parent)
        maximize_action = QAction('maximize flux for this reaction', parent)
        self.pop_menu.addAction(maximize_action)
        maximize_action.triggered.connect(self.emit_maximize_action)
        minimize_action = QAction('minimize flux for this reaction', parent)
        self.pop_menu.addAction(minimize_action)
        minimize_action.triggered.connect(self.emit_minimize_action)
        switch_action = QAction('switch to reaction mask', parent)
        self.pop_menu.addAction(switch_action)
        switch_action.triggered.connect(self.switch_to_reaction_mask)
        remove_action = QAction('remove from map', parent)
        self.pop_menu.addAction(remove_action)
        remove_action.triggered.connect(self.remove)

        self.pop_menu.addSeparator()

    def returnPressed(self):
        if validate_value(self.item.text()):
            self.map.value_changed(self.id, self.item.text())

        # TODO: actually I want to repaint
        # self.map.update()

    def value_changed(self):
        test = self.item.text().replace(" ", "")
        if test == "":
            self.map.value_changed(self.id, test)
            self.set_color(self.map.appdata.default_color)
        elif validate_value(self.item.text()):
            self.map.value_changed(self.id, self.item.text())
            if self.id in self.map.appdata.project.scen_values.keys():
                self.set_color(self.map.appdata.scen_color)
            else:
                self.set_color(self.map.appdata.comp_color)
        else:
            self.set_color(Qt.magenta)

        # TODO: actually I want to repaint
        # self.map.update()

    def set_val_and_color(self, value: Tuple[float, float]):
        self.set_value(value)
        self.recolor()

    def set_value(self, value: Tuple[float, float]):
        (vl, vu) = value
        if isclose(vl, vu, abs_tol=self.map.appdata.abs_tol):
            self.item.setText(str(round(vl, self.map.appdata.rounding)))
        else:
            self.item.setText(
                str((round(vl, self.map.appdata.rounding),
                     round(vu, self.map.appdata.rounding))))
        self.item.setCursorPosition(0)

    def recolor(self):
        value = self.item.text()
        test = value.replace(" ", "")
        if test == "":
            self.set_color(self.map.appdata.default_color)
        elif validate_value(value):
            if self.id in self.map.appdata.project.scen_values.keys():
                value = self.map.appdata.project.scen_values[self.id]
                self.set_color(self.map.appdata.scen_color)
            else:
                value = self.map.appdata.project.comp_values[self.id]
                (vl, vu) = value
                if math.isclose(vl, vu, abs_tol=self.map.appdata.abs_tol):
                    if self.map.appdata.modes_coloring:
                        if vl == 0:
                            self.set_color(Qt.red)
                        else:
                            self.set_color(Qt.green)
                    else:
                        self.set_color(self.map.appdata.comp_color)
                else:
                    if math.isclose(vl, 0.0, abs_tol=self.map.appdata.abs_tol):
                        self.set_color(self.map.appdata.special_color_1)
                    elif math.isclose(vu,
                                      0.0,
                                      abs_tol=self.map.appdata.abs_tol):
                        self.set_color(self.map.appdata.special_color_1)
                    elif vl <= 0 and vu >= 0:
                        self.set_color(self.map.appdata.special_color_1)
                    else:
                        self.set_color(self.map.appdata.special_color_2)
        else:
            self.set_color(Qt.magenta)

    def set_color(self, color: QColor):
        palette = self.item.palette()
        palette.setColor(QPalette.Base, color)
        role = self.item.foregroundRole()
        palette.setColor(role, Qt.black)
        self.item.setPalette(palette)

    def boundingRect(self):
        return QRectF(-15, -15, 20, 20)

    def paint(self, painter: QPainter, _option, _widget: QWidget):
        # set color depending on wether the value belongs to the scenario
        if self.id in self.map.appdata.project.scen_values.keys():
            painter.setPen(Qt.magenta)
            painter.setBrush(Qt.magenta)
        else:
            painter.setPen(Qt.darkGray)

        painter.drawRect(-15, -15, 20, 20)
        painter.setPen(Qt.darkGray)
        painter.drawLine(-5, 0, -5, -10)
        painter.drawLine(0, -5, -10, -5)

    def mousePressEvent(self, _event: QGraphicsSceneMouseEvent):
        pass

    def mouseReleaseEvent(self, _event: QGraphicsSceneMouseEvent):
        pass

    def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent):
        drag = QDrag(event.widget())
        mime = QMimeData()
        mime.setText(str(self.id))
        drag.setMimeData(mime)
        # self.setCursor(Qt.ClosedHandCursor)
        drag.exec_()
        # self.setCursor(Qt.OpenHandCursor)

    def setPos(self, x, y):
        self.proxy.setPos(x, y)
        super().setPos(x, y)

    def on_context_menu(self, point):
        # show context menu
        self.pop_menu.exec_(self.item.mapToGlobal(point))

    def remove(self):
        self.map.remove_box(self.id)
        self.map.drag = False

    def switch_to_reaction_mask(self):
        self.map.switchToReactionMask.emit(self.id)
        self.map.drag = False

    def emit_maximize_action(self):
        self.map.maximizeReaction.emit(self.id)
        self.map.drag = False

    def emit_minimize_action(self):
        self.map.minimizeReaction.emit(self.id)
        self.map.drag = False
class MainWindowTyping(QMainWindow):
    """Main Window."""
    def __init__(self):
        """Main Window UI를 설정한다."""
        super().__init__()
        self.setWindowTitle(f"Typing Number - {VER}")

        icon = QIcon()
        icon.addPixmap(QPixmap(r'ok_64x64.ico'), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.setMinimumSize(800, 100)

        # Typing Info
        self.typing = ManageTyping()

        # Setup StatusBar
        self.statusBar().showMessage("")
        self.statusBar().addPermanentWidget(VLine())
        self.label_typing_avg = QLabel("평균타수 : 0.0타/초", self)
        self.statusBar().addPermanentWidget(self.label_typing_avg)

        self.statusBar().addPermanentWidget(VLine())
        self.label_total_time = QLabel("총 연습시간", self)
        self.statusBar().addPermanentWidget(self.label_total_time)

        # Setup LineEdit
        self.line_for_number = QLineEdit(self)
        self.line_for_typing = QLineEdit(self)
        self.line_for_error = QLineEdit(self)
        self.setup_lineedit()
        vbox = QVBoxLayout()
        vbox.addWidget(self.line_for_number)
        vbox.addWidget(self.line_for_typing)
        vbox.addWidget(self.line_for_error)

        central_widget = QWidget(self)
        central_widget.setLayout(vbox)
        self.setCentralWidget(central_widget)

        self.new_game()

    def setup_lineedit(self):
        """LineEdit를 설정한다."""
        mask = (("X" + " " * self.typing.n_space_between_chars) *
                self.typing.n_char_in_game)
        self.line_for_number.setInputMask(mask)
        self.line_for_typing.setInputMask(mask)
        self.line_for_error.setInputMask(mask)

        self.line_for_number.setReadOnly(True)
        self.line_for_error.setReadOnly(True)

        self.line_for_error.setStyleSheet(
            "QLineEdit { border:none; color: red; }")

        self.line_for_typing.textChanged.connect(self.update_typing)

    def display_result(self):
        """연습결과를 보여준다."""
        typing_per_sec = self.typing.typing_per_sec_prev()
        typing_per_sec_avg = self.typing.typing_per_sec_avg()

        self.statusBar().showMessage(f'현재타수 : {typing_per_sec:.1f}타/초')

        self.label_typing_avg.setText(f'평균타수 : {typing_per_sec_avg:.1f}타/초')

        self.label_total_time.setText("총 연습시간 : " +
                                      self.typing.str_of_total_time())

    def new_game(self):
        """연습에 필요한 문자열 만든다."""
        self.line_for_typing.setText("")
        self.line_for_typing.setCursorPosition(0)

        self.typing.new_game()
        self.line_for_number.setText(self.typing.chars_answer)

        self.line_for_typing.setFocus()
        self.display_result()

    def update_typing(self):
        """Typing 정보를 갱신한다."""
        typing = self.typing
        typing.update_time()
        is_correct, err_str = typing.check_result(self.line_for_typing.text())

        if is_correct:
            self.new_game()
            self.line_for_error.setText("")

        self.line_for_error.setText(err_str)
示例#3
0
class InteractionVolumeView(VolumeView):

    signalAxisChanged = Signal(int)

    def __init__(self, label=None, **kwargs):

        super(InteractionVolumeView, self).__init__(**kwargs)

        self.interactionFrame = QFrame(self)
        self.interactionFrame.setSizePolicy(
            QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed))
        self.interactionFrame.setFixedHeight(30)
        self.interactionLayout = QHBoxLayout(self.interactionFrame)
        self.interactionLayout.setContentsMargins(5, 5, 5, 5)

        self.sliceLabel = QLabel(self.interactionFrame)
        self.sliceLabel.setSizePolicy(
            QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum))
        self.updateSliceLabel()

        self.textLabel = QLineEdit(self.interactionFrame)
        self.textLabel.setReadOnly(True)
        self.textLabel.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.textLabel.setAlignment(Qt.AlignCenter)
        stylesheet = \
            "QLineEdit {\n" \
            + "border: none;\n" \
            + "background-color: rgba(255, 255, 255, 0);\n" \
            + "}"
        self.textLabel.setStyleSheet(stylesheet)
        if label is not None:
            self.updateTextLabel(label)

        self.interactionLayout.addWidget(self.sliceLabel)
        self.interactionLayout.addWidget(self.textLabel)

        self.axisSelector = QComboBox(self.interactionFrame)
        self.axisSelector.setFixedWidth(40)
        self.axisSelector.insertItems(0, ["0", "1", "2"])
        self.interactionLayout.addWidget(self.axisSelector)

        self.layout.addWidget(self.interactionFrame)

        self.signalSliceChanged.connect(self.updateSliceLabel)
        self.axisSelector.currentIndexChanged.connect(self.setAxisAndEmit)

    def setAxisAndEmit(self, axis):
        self.setAxis(axis)
        self.signalAxisChanged.emit(axis)

    def setAxis(self, axis):
        super(InteractionVolumeView, self).setAxis(axis)
        self.axisSelector.setCurrentIndex(axis)
        self.updateSliceLabel()

    def setSlice(self, slice_):
        super(InteractionVolumeView, self).setSlice(slice_)
        self.updateSliceLabel()

    def updateSliceLabel(self):
        try:
            length = str(len(str(self.numberOfSlices)))
            self.sliceLabel.setText(
                ("{:0" + length + "d}/{:0" + length + "}").format(
                    self.currentSlice, self.numberOfSlices))
        except AttributeError:
            pass

    def updateTextLabel(self, text):
        try:
            self.textLabel.setText(text)
            self.textLabel.setCursorPosition(0)
        except AttributeError:
            pass
示例#4
0
class EditableLineEdit(QWidget):
    """
    """
    sig_text_changed = Signal(object, object)  # old_text, new_text

    def __init__(self, title, text, regex=None, allow_empty=False):
        super(EditableLineEdit, self).__init__()
        self._label = QLabel(title)
        self._text = QLineEdit()
        self.button_edit = QPushButton()
        self.allow_empty = allow_empty
        self.regex = regex
        self.qregex = None

        self.button_edit.setIcon(qta.icon('fa.edit'))
        self._text.setText(text)

        layout = QVBoxLayout()
        layout.addWidget(self._label)

        layout_h = QHBoxLayout()
        layout_h.addWidget(self._text)
        layout_h.addWidget(self.button_edit)
        layout.addLayout(layout_h)

        self.setLayout(layout)
        self._text.setDisabled(True)

        self.button_edit.clicked.connect(self.edit)

        self.last_text = self._text.text()
        self.set_regex(regex)

#    def focusOutEvent(self, event):
#        """
#        Qt override.
#        FIXME:
#        """
#        super(EditableLineEdit, self).focusOutEvent(event)
#        event = QKeyEvent(QKeyEvent.KeyPress, Qt.Key_Escape)
#        self.keyPressEvent(event)

    def keyPressEvent(self, event):
        """
        Qt override.
        """
        super(EditableLineEdit, self).keyPressEvent(event)
        key = event.key()
        if key in [Qt.Key_Enter, Qt.Key_Return]:
            self.check_text()
        elif key in [Qt.Key_Escape]:
            self._text.setText(self.last_text)
            self.check_text(escaped=True)

    # --- Public API
    # -------------------------------------------------------------------------
    def text(self):
        return self._text.text()

    def setText(self, text):
        self.set_text(text)

    def set_text(self, text):
        """
        """
        self._text.setText(text)

    def set_label_text(self, text):
        """
        """
        self.label.setText(text)

    def set_regex(self, regex):
        """
        """
        if regex:
            self.regex = regex
            self.qregex = QRegExp(regex)
            validator = QRegExpValidator(self.qregex)
            self._text.setValidator(validator)

    def check_text(self, escaped=False):
        """
        """
        self._text.setDisabled(True)
        self.button_edit.setDisabled(False)
        new_text = self._text.text()

        if not self.allow_empty and len(new_text) == 0:
            self.edit()

        if self.last_text != new_text and not escaped:
            self.sig_text_changed.emit(self.last_text, new_text)
            self.last_text = new_text

    def edit(self):
        """
        """
        self._text.setDisabled(False)
        self.button_edit.setDisabled(True)
        self._text.setFocus()
        self._text.setCursorPosition(len(self._text.text()))
        self.last_text = self._text.text()