示例#1
0
    def __init__(self):
        super().__init__(None, Qt.WindowFlags())

        self.window().setWindowTitle(APP_NAME)
        self.setMinimumWidth(APP_MIN_WIDTH)
        self.setMinimumHeight(APP_MIN_HEIGHT)

        self.thread_pool = QThreadPool()

        self._initial_point = None
        self._drown_points = None
        self._canvas = Canvas(
            initial_point_handler=self._initial_point_handler)

        self._btn_draw = QPushButton(self.tr('Draw'), 90, 30,
                                     self._draw_points)
        self._btn_draw.setEnabled(False)

        self._btn_reset = QPushButton(self.tr('Reset'), 90, 30,
                                      self._reset_canvas)
        self._btn_reset.setEnabled(False)

        self._btn_save = QPushButton(self.tr('Save'), 90, 30,
                                     self._save_canvas)
        self._btn_save.setEnabled(False)

        self._points_count_line_edit = QLineEdit()
        self._segment_div_line_edit = QLineEdit()

        main_widget = self.init_main_widget()
        self.setCentralWidget(main_widget)

        # self.setup_navigation_menu()
        self.setFont(QFont('SansSerif', APP_FONT))
示例#2
0
def test_set_color(canvas: Canvas):
    assert canvas.color == (255, 255, 255)

    canvas.set_brush(CircleShapeBrush())
    canvas.set_color((100, 200, 100))
    assert canvas.color == (100, 200, 100)
    assert canvas.brush.color == (100, 200, 100)
示例#3
0
def canvas(qtbot) -> Canvas:
    controller = ControllerMockup()

    gui = MainWindow(controller)
    gui.show()
    qtbot.addWidget(gui)

    canvas = Canvas(controller)
    assert canvas.hasMouseTracking() is True
    return canvas
示例#4
0
    def __init__(self, controller):
        super().__init__()
        self._controller = controller

        # Initializing the whole UI
        self._ui = Ui_MainWindow()
        self._ui.setupUi(self)
        self.set_status()

        self.canvas = Canvas(controller)

        # Menu buttons
        self._ui.actionNew.triggered.connect(lambda: self._handle_action_new())
        self._ui.actionSave.triggered.connect(lambda: self.save_dialog())
        self._ui.actionLoad.triggered.connect(lambda: self.load_dialog())
        self._ui.actionUndo.triggered.connect(lambda: self._controller.undo())
        self._ui.actionRedo.triggered.connect(lambda: self._controller.redo())
        self._ui.actionQuit.triggered.connect(
            lambda: self._handle_action_quit())
        self.disable_undo()
        self.disable_redo()

        # Setting specific brush for canvas after clicking on one of the tool buttons
        self._ui.dotButton.clicked.connect(
            lambda: self._toggle_brush(DotShapeBrush()))
        self._ui.lineButton.clicked.connect(
            lambda: self._toggle_brush(LineShapeBrush()))
        self._ui.polylineButton.clicked.connect(
            lambda: self._toggle_brush(PolylineShapeBrush()))
        self._ui.rectagleButton.clicked.connect(
            lambda: self._toggle_brush(RectShapeBrush()))
        self._ui.circleButton.clicked.connect(
            lambda: self._toggle_brush(CircleShapeBrush()))
        self._ui.removeButton.clicked.connect(
            lambda: self._toggle_brush(RemoveShapeBrush()))
        self._ui.colorButton.clicked.connect(lambda: self._handle_color_pick())
        self.brush_buttons = {
            DotShapeBrush(): self._ui.dotButton,
            LineShapeBrush(): self._ui.lineButton,
            PolylineShapeBrush(): self._ui.polylineButton,
            RectShapeBrush(): self._ui.rectagleButton,
            CircleShapeBrush(): self._ui.circleButton,
            RemoveShapeBrush(): self._ui.removeButton
        }

        self._ui.manualInput.returnPressed.connect(
            lambda: self._handle_user_input())

        self._ui.canvasHolder.setWidget(self.canvas)
        self._ui.canvasHolder.setStyleSheet('background-color: white')
示例#5
0
def test_mouse_move_event(canvas: Canvas):
    assert canvas.brush == MoveShapeBrush()
    assert canvas.cursor() == Qt.ArrowCursor

    canvas.mouseMoveEvent(EventMockup)
    assert (canvas._controller.command is None)

    canvas.set_brush(DotShapeBrush())
    canvas.mouseMoveEvent(EventMockup)
    assert (canvas._controller.command == PrintDotCommand(
        canvas._controller, EventMockup.x(), EventMockup.y(), (255, 255, 255)))
    assert canvas.cursor() == Qt.CrossCursor
示例#6
0
def test_mouse_press_event(canvas: Canvas):
    assert canvas.brush == MoveShapeBrush()
    assert canvas.cursor() == Qt.ArrowCursor

    canvas.mousePressEvent(EventMockup)
    assert canvas._controller.command is None

    canvas.set_brush(RectShapeBrush())
    canvas.mousePressEvent(EventMockup)
    canvas.mousePressEvent(EventMockup)
    assert (canvas._controller.command == PrintRectCommand(
        receiver=canvas._controller,
        start_x=EventMockup.x(),
        start_y=EventMockup.y(),
        color=(255, 255, 255),
        rect_factory=PointsRectFactory,
        end_x=EventMockup.x(),
        end_y=EventMockup.y()))
示例#7
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__(None, Qt.WindowFlags())

        self.window().setWindowTitle(APP_NAME)
        self.setMinimumWidth(APP_MIN_WIDTH)
        self.setMinimumHeight(APP_MIN_HEIGHT)

        self.thread_pool = QThreadPool()

        self._initial_point = None
        self._drown_points = None
        self._canvas = Canvas(
            initial_point_handler=self._initial_point_handler)

        self._btn_draw = QPushButton(self.tr('Draw'), 90, 30,
                                     self._draw_points)
        self._btn_draw.setEnabled(False)

        self._btn_reset = QPushButton(self.tr('Reset'), 90, 30,
                                      self._reset_canvas)
        self._btn_reset.setEnabled(False)

        self._btn_save = QPushButton(self.tr('Save'), 90, 30,
                                     self._save_canvas)
        self._btn_save.setEnabled(False)

        self._points_count_line_edit = QLineEdit()
        self._segment_div_line_edit = QLineEdit()

        main_widget = self.init_main_widget()
        self.setCentralWidget(main_widget)

        # self.setup_navigation_menu()
        self.setFont(QFont('SansSerif', APP_FONT))

    def _reset_canvas(self):
        self._initial_point = None
        self._drown_points = None
        self._canvas.clean()
        self._btn_draw.setEnabled(False)
        self._btn_reset.setEnabled(False)
        self._btn_save.setEnabled(False)

    def _save_canvas(self):
        # TODO:
        print('Canvas is saved')

    def _draw_points(self):
        worker = Worker(self._draw_points_fn)
        worker.signals.error.connect(self._popup_err)
        worker.signals.param_success.connect(self._draw_points_finished)
        self.thread_pool.start(worker)

    def _draw_points_finished(self, points):
        self._drown_points = points
        self._canvas.set_points(points)
        self._btn_save.setEnabled(True)

    def _draw_points_fn(self):
        triangle = Triangle(self._canvas.width(), self._canvas.height(),
                            int(self._segment_div_line_edit.text()))
        return triangle.calc_points(
            (self._initial_point.x(), self._initial_point.y()),
            int(self._points_count_line_edit.text()))

    def _initial_point_handler(self, point):
        if self._initial_point is None:
            self._initial_point = point
            self._btn_draw.setEnabled(True)
            self._btn_reset.setEnabled(True)
            return point
        return None

    def _add_input_field(self, parent, title, default=None, regex=None):
        widget = QWidget(self, flags=self.windowFlags())
        layout = QVBoxLayout(widget)
        layout.addWidget(QLabel(title), 0, Qt.AlignLeft)
        line_edit = QLineEdit()
        if default is not None:
            line_edit.setText(str(default))
        line_edit.setAlignment(Qt.AlignHCenter)
        if regex is not None:
            line_edit.setValidator(QRegExpValidator(QRegExp(regex), line_edit))
            line_edit.textChanged.connect(self._inputs_changed)
        layout.addWidget(line_edit, 0, Qt.AlignLeft)
        parent.addWidget(widget, 0, Qt.AlignHCenter)
        return line_edit

    def init_main_widget(self):
        layout = QVBoxLayout()

        # noinspection PyArgumentList
        layout.addWidget(self._canvas)

        container = QWidget(self, flags=self.windowFlags())
        container.setStyleSheet('background-color: lightgray;')
        container.setFixedHeight(100)

        tools = QHBoxLayout(container)

        self._points_count_line_edit = self._add_input_field(
            tools, 'Points count:', 100000, '[1-9]+[0-9]*')
        self._segment_div_line_edit = self._add_input_field(
            tools, 'Segment divisor:', 2, '[1-9]+[0-9]*')

        tools.addWidget(self._btn_draw, 0, Qt.AlignHCenter)
        tools.addWidget(self._btn_reset, 0, Qt.AlignHCenter)
        tools.addWidget(self._btn_save, 0, Qt.AlignHCenter)

        # noinspection PyArgumentList
        layout.addWidget(container)

        widget = QWidget(flags=self.windowFlags())
        widget.setLayout(layout)
        return widget

    @staticmethod
    def _empty(inp):
        return len(inp.text()) == 0

    def _inputs_changed(self):
        if self._empty(self._segment_div_line_edit) or self._empty(
                self._points_count_line_edit) or self._initial_point is None:
            self._btn_draw.setEnabled(False)
        else:
            self._btn_draw.setEnabled(True)

    def _popup_err(self, err):
        err_msg = 'Input data error\nCheck inputs'
        if err is not None:
            err_msg = err[1]
        msg_box = QMessageBox()
        msg_box.warning(self, 'Input data error', err_msg, QMessageBox.Ok)
        self._btn_draw.setEnabled(True)
示例#8
0
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, controller):
        super().__init__()
        self._controller = controller

        # Initializing the whole UI
        self._ui = Ui_MainWindow()
        self._ui.setupUi(self)
        self.set_status()

        self.canvas = Canvas(controller)

        # Menu buttons
        self._ui.actionNew.triggered.connect(lambda: self._handle_action_new())
        self._ui.actionSave.triggered.connect(lambda: self.save_dialog())
        self._ui.actionLoad.triggered.connect(lambda: self.load_dialog())
        self._ui.actionUndo.triggered.connect(lambda: self._controller.undo())
        self._ui.actionRedo.triggered.connect(lambda: self._controller.redo())
        self._ui.actionQuit.triggered.connect(
            lambda: self._handle_action_quit())
        self.disable_undo()
        self.disable_redo()

        # Setting specific brush for canvas after clicking on one of the tool buttons
        self._ui.dotButton.clicked.connect(
            lambda: self._toggle_brush(DotShapeBrush()))
        self._ui.lineButton.clicked.connect(
            lambda: self._toggle_brush(LineShapeBrush()))
        self._ui.polylineButton.clicked.connect(
            lambda: self._toggle_brush(PolylineShapeBrush()))
        self._ui.rectagleButton.clicked.connect(
            lambda: self._toggle_brush(RectShapeBrush()))
        self._ui.circleButton.clicked.connect(
            lambda: self._toggle_brush(CircleShapeBrush()))
        self._ui.removeButton.clicked.connect(
            lambda: self._toggle_brush(RemoveShapeBrush()))
        self._ui.colorButton.clicked.connect(lambda: self._handle_color_pick())
        self.brush_buttons = {
            DotShapeBrush(): self._ui.dotButton,
            LineShapeBrush(): self._ui.lineButton,
            PolylineShapeBrush(): self._ui.polylineButton,
            RectShapeBrush(): self._ui.rectagleButton,
            CircleShapeBrush(): self._ui.circleButton,
            RemoveShapeBrush(): self._ui.removeButton
        }

        self._ui.manualInput.returnPressed.connect(
            lambda: self._handle_user_input())

        self._ui.canvasHolder.setWidget(self.canvas)
        self._ui.canvasHolder.setStyleSheet('background-color: white')

    # ------------------------------------------------ Handlers -------------------------------------------------------

    def _handle_action_new(self):
        command = ClearCommand(self._controller)
        self._controller.execute_command(command)

    def _handle_save_file(self):
        command = SaveCommand(self._controller)
        self._controller.execute_command(command)

    def _handle_load_file(self):
        command = LoadCommand(self._controller)
        self._controller.execute_command(command)

    def _toggle_brush(self, brush: Brush):
        if self.canvas.brush != MoveShapeBrush():
            # Un-checking the previous brush button
            previous_brush_button = self.brush_buttons[self.canvas.brush]
            previous_brush_button.setChecked(False)

        if self.canvas.brush != brush:
            self.canvas.set_brush(brush)
            self.set_status(str(brush))
        else:
            self.canvas.set_brush()
            self.set_status()

    def _handle_color_pick(self):
        # Color picker will popup and returns chosen color
        color = QColorDialog().getColor(QColor(*self.canvas.color))
        if color.isValid():
            self._ui.colorButton.setStyleSheet(
                f'background-color: {color.name()}')
            r, g, b, alpha = color.getRgb()
            self.canvas.set_color((r, g, b))

    def _handle_user_input(self):
        command_text = self._ui.manualInput.text()
        self._ui.manualInput.setText('')
        if command_text != '' and not command_text.isspace():
            self._controller.parse_command(command_text)

    def _handle_action_quit(self):
        command = QuitCommand(self._controller)
        self._controller.execute_command(command)

    # --------------------------------------------- Main window methods -----------------------------------------------

    @staticmethod
    def clear_dialog() -> bool:
        res = ClearDialog()
        return res.accepted

    def set_status(self, message: str = str(MoveShapeBrush())):
        self.statusBar().showMessage(message)

    def save_dialog(self, path_to_file: str = None):
        # Save file dialog will open and returns tuple (name of the saved file, type)
        user = getpass.getuser()
        path = path_to_file or f'/home/{user}/untitled.txt'
        name, _ = QFileDialog().getSaveFileName(self, 'Save File', path)
        if name:
            self._controller.save(name)

    def load_dialog(self, path_to_file: str = None):
        # Load file dialog will open and returns tuple (name of the loaded file, type)
        user = getpass.getuser()
        path = path_to_file or f'/home/{user}/untitled.txt'
        name, _ = QFileDialog().getOpenFileName(self, 'Load File', path)
        if name:
            self._controller.load(name)

    def enable_undo(self):
        self._ui.actionUndo.setEnabled(True)

    def disable_undo(self):
        self._ui.actionUndo.setEnabled(False)

    def enable_redo(self):
        self._ui.actionRedo.setEnabled(True)

    def disable_redo(self):
        self._ui.actionRedo.setEnabled(False)

    def print_lines_to_history(self, lines: str):
        self._ui.history.append(lines)

    def delete_from_history(self, number_of_lines: int = 1):
        history = self._ui.history.toPlainText()
        history = history.split('\n')

        if number_of_lines > len(history):
            raise ValueError

        history = history[:(-number_of_lines)]
        history = '\n'.join(history)
        self._ui.history.setText(history)
        self._ui.history.moveCursor(QTextCursor.End)
        self._ui.history.ensureCursorVisible()

    def clear_history(self):
        self._ui.history.setText('')
示例#9
0
def test_pain_event(canvas: Canvas):
    canvas.paintEvent(EventMockup)
    assert canvas._controller.all_shapes == 'printed all shapes'
示例#10
0
def test_set_brush(canvas: Canvas):
    assert canvas.brush == MoveShapeBrush()
    assert canvas.cursor() == Qt.ArrowCursor

    canvas.set_brush(LineShapeBrush())
    assert canvas.brush.color == (255, 255, 255)
    assert canvas.brush == LineShapeBrush()
    assert canvas.cursor() == Qt.CrossCursor

    canvas.set_color((10, 20, 30))
    canvas.set_brush(RectShapeBrush())
    assert canvas.brush.color == (10, 20, 30)
    assert canvas.brush == RectShapeBrush()
    assert canvas.cursor() == Qt.CrossCursor

    canvas.set_brush()
    assert canvas.brush == MoveShapeBrush()
    assert canvas.cursor() == Qt.ArrowCursor