class VanillaWindow(QMainWindow): SHIFT = 100 MAX_BRUSH_SIZE = 500 TOOLBAR_HEIGHT = 791 TOOLBAR_WIDTH = 389 BUTTON_SIZE = 64 MENU_BAR_HEIGHT = 30 BUTTON_SHIFT = 20 MINIMUM_CANVAS_LEFT_SHIFT = 250 def __init__(self): super().__init__() self.to_draw_canvas = False self.to_draw_line = False self.to_draw_rectangle = False self.to_draw_triangle = False self.to_draw_ellipse = False self.to_draw_selection = False self.cursor_on_canvas = False self.shape_start = None self.selection_left = 0 self.selection_right = 0 self.selection_up = 0 self.selection_down = 0 self.selection_width = 0 self.selection_height = 0 self.mouse_pressed = False self.picture_name = None self.canvas = Canvas() self.button_images = {} self.buttons = {} self.layer_tables = [] self.init_ui() def init_ui(self): self.setWindowTitle('Vanilla') self.setWindowIcon(QIcon('images/icon.png')) self.showMaximized() self.setStyleSheet('QMainWindow{background: Gray;}' 'QMenuBar::item:selected{background: #202020;}' 'QMenu::item:disabled{color: #505050;}' 'QToolTip{background : black; font-size: 16px; color: white; ' 'border: black solid 1px}') self.setMouseTracking(True) self.create_menu_bar() self.color_picker = QPushButton('', self) color_picker_height = 100 self.color_picker.setGeometry(50, self.TOOLBAR_HEIGHT + self.MENU_BAR_HEIGHT - color_picker_height - 50, 100, color_picker_height) red = Canvas().current_color.r green = Canvas().current_color.g blue = Canvas().current_color.b self.color_picker.setStyleSheet(f'background: Color({red}, {green}, {blue})') self.color_picker.clicked.connect(self.pick_color) self.color_picker.show() self.size_slider = QSlider(Qt.Horizontal, self) slider_height = 20 self.size_slider.setGeometry(10, self.color_picker.y() - slider_height - 60, 145, slider_height) self.size_slider.setMinimum(1) self.size_slider.setMaximum(self.MAX_BRUSH_SIZE) self.size_slider.valueChanged[int].connect(self.size_changed) self.size_slider.show() validator = QIntValidator(1, self.MAX_BRUSH_SIZE) self.size_edit = QLineEdit('1', self) self.size_edit.setGeometry(self.size_slider.x() + self.size_slider.width() + 5, self.size_slider.y(), 35, 20) self.size_edit.setFont(QFont('Arial', 10)) self.size_edit.setAlignment(Qt.AlignCenter) self.size_edit.setValidator(validator) self.size_edit.textChanged[str].connect(self.size_edited) self.size_edit.show() self.size_label = QLabel('Brush Size:', self) self.size_label.setFont(QFont('Arial', 16)) self.size_label.setStyleSheet('color: lightGray;') self.size_label.setGeometry(self.size_slider.x(), self.size_slider.y() - self.size_slider.height() - 10, self.size_slider.width() + self.size_edit.width() + 5, 30) self.size_label.show() self.create_buttons() width = QDesktopWidget().width() height = QDesktopWidget().height() - 64 size = 20 self.layer_button_left = width - 220 self.add_layer_button = QPushButton('Add Layer', self) self.add_layer_button.setGeometry(self.layer_button_left + 24, self.TOOLBAR_HEIGHT - 15, 150, 30) self.add_layer_button.clicked.connect(self.add_layer) self.add_layer_button.setFont(QFont('Arial', 14)) self.add_layer_button.show() self.layers_label = QLabel('Layers', self) self.layers_label.setFont(QFont('Arial', 20)) self.layers_label.setStyleSheet('color: lightGray;') self.layers_label.setGeometry(self.layer_button_left, 25, 197, 60) self.layers_label.setAlignment(Qt.AlignCenter) self.layers_label.show() self.vertical_scrollbar = QScrollBar(self) self.vertical_scrollbar.setGeometry(width - size, 0, size, height - size) self.vertical_scrollbar.valueChanged[int].connect(self.vertical_scrollbar_value_changed) self.horizontal_scrollbar = QScrollBar(Qt.Horizontal, self) self.horizontal_scrollbar.setGeometry(0, height - size, width - size, size) self.horizontal_scrollbar.valueChanged[int].connect(self.horizontal_scrollbar_value_changed) self.show() def create_buttons(self): left = 25 brush_button = self.create_button(left, self.MENU_BAR_HEIGHT + 20, 'Brush', 'B', self.brush_button_clicked) self.buttons[Tools.BRUSH] = brush_button right = brush_button.x() + brush_button.width() + self.BUTTON_SHIFT eraser_button = self.create_button(right, brush_button.y(), 'Eraser', 'E', self.eraser_button_clicked) self.buttons[Tools.ERASER] = eraser_button fill_button = self.create_button(left, self.get_button_shift(brush_button), 'Fill', 'F', self.fill_button_pressed) self.buttons[Tools.FILL] = fill_button selection_button = self.create_button(right, fill_button.y(), 'Selection', 'S', self.selection_button_clicked) self.buttons[Tools.SELECTION] = selection_button line_button = self.create_button(left, self.get_button_shift(fill_button), 'Line', 'L', self.line_button_clicked) self.buttons[Tools.LINE] = line_button rectangle_button = self.create_button(right, line_button.y(), 'Rectangle', 'R', self.rectangle_button_clicked) self.buttons[Tools.SQUARE] = rectangle_button ellipse_button = self.create_button(left, self.get_button_shift(line_button), 'Ellipse', 'C', self.ellipse_button_clicked) self.buttons[Tools.CIRCLE] = ellipse_button triangle_button = self.create_button(right, ellipse_button.y(), 'Triangle', 'T', self.triangle_button_clicked) self.buttons[Tools.TRIANGLE] = triangle_button right_turn_button = self.create_button(left, self.get_button_shift(ellipse_button), 'Turn Right', 'Ctrl+R', self.turn_selection_right) left_turn_button = self.create_button(right, right_turn_button.y(), 'Turn Left', 'Ctrl+L', self.turn_selection_left) flip_horizontally_button = self.create_button(left, self.get_button_shift(right_turn_button), 'Flip Horizontally', 'Ctrl+H', self.flip_horizontally) flip_vertically_button = self.create_button(right, flip_horizontally_button.y(), 'Flip Vertically', 'Ctrl+F', self.flip_vertically) def create_menu_bar(self): self.menu_bar = self.menuBar() self.menu_bar.setStyleSheet('selection-background-color: #202020; background: #393939; color: lightGray;') file_menu = self.menu_bar.addMenu('&File') new_action = QAction('&New', self) new_action.setShortcut('Ctrl+N') new_action.triggered.connect(self.ask_size) file_menu.addAction(new_action) open_action = QAction('&Open', self) open_action.setShortcut('Ctrl+O') open_action.triggered.connect(self.open) file_menu.addAction(open_action) file_menu.addSeparator() self.save_action = QAction('&Save', self) self.save_action.setShortcut('Ctrl+S') self.save_action.triggered.connect(self.save) self.save_action.setDisabled(True) file_menu.addAction(self.save_action) self.save_as_action = QAction('Save as', self) self.save_as_action.setShortcut('Ctrl+Shift+S') self.save_as_action.triggered.connect(self.save_as) self.save_as_action.setDisabled(True) file_menu.addAction(self.save_as_action) image_menu = self.menu_bar.addMenu('&Image') self.greyscale_action = QAction('Greyscale', self) self.greyscale_action.setShortcut('Ctrl+G') self.greyscale_action.triggered.connect(self.change_greyscale) self.greyscale_action.setDisabled(True) image_menu.addAction(self.greyscale_action) self.brightness_action = QAction('Brightness', self) self.brightness_action.setShortcut('Ctrl+B') self.brightness_action.triggered.connect(self.brightness) self.brightness_action.setDisabled(True) image_menu.addAction(self.brightness_action) selection_menu = self.menu_bar.addMenu('&Selection') self.deselect_action = QAction('Deselect', self) self.deselect_action.setShortcut('Ctrl+D') self.deselect_action.triggered.connect(self.deselect) self.deselect_action.setDisabled(True) selection_menu.addAction(self.deselect_action) self.select_all_action = QAction('Select All', self) self.select_all_action.setShortcut('Ctrl+A') self.select_all_action.triggered.connect(self.select_all) self.select_all_action.setDisabled(True) selection_menu.addAction(self.select_all_action) selection_menu.addSeparator() self.delete_selection_action = QAction('Delete', self) self.delete_selection_action.setShortcut('Delete') self.delete_selection_action.triggered.connect(self.delete_in_selection) self.delete_selection_action.setDisabled(True) selection_menu.addAction(self.delete_selection_action) def create_button(self, x, y, image, shortcut='', action=lambda: None): button = QPushButton('', self) button.setGeometry(x, y, self.BUTTON_SIZE, self.BUTTON_SIZE) button.setStyleSheet('background: transparent;') button.setShortcut(shortcut) button.setToolTip(f'{image} ({shortcut})') button.clicked.connect(action) self.button_images[button] = QImage(f'images/{image}.png') button.show() return button def flip(self, flip_function): if not self.canvas.selection_is_on: return flip_function() self.to_draw_selection = False self.update_canvas() self.update() def flip_horizontally(self): self.flip(self.canvas.flip_horizontally) def flip_vertically(self): self.flip(self.canvas.flip_vertically) def get_button_shift(self, upper_button): return upper_button.y() + upper_button.height() + self.BUTTON_SHIFT def turn_selection_right(self): self.turn_selection(self.canvas.turn_selection_right) def turn_selection_left(self): self.turn_selection(self.canvas.turn_selection_left) def turn_selection(self, turn_function): if not self.canvas.selection_is_on: return turn_function() self.to_draw_selection = False self.update_canvas() self.update() def create_layer_button(self, x, y, layer_number): button = QPushButton('', self) button.setGeometry(x, y, 187, 100) button.setStyleSheet('background: transparent;') button.clicked.connect(lambda: self.change_layer(layer_number)) button.show() return button def change_layer(self, number): self.canvas.change_layer(number) self.update_color_button() self.update() def delete_layer(self, layer_table): self.canvas.delete_layer(layer_table.layer) self.layer_tables.remove(layer_table) self.update_canvas() self.update_layers_buttons() if len(self.canvas.layers) == 5: self.add_layer_button.setDisabled(False) self.update() def update_layers_buttons(self): for table in self.layer_tables: table.close() self.layer_tables = [] x = self.layer_button_left + 5 for i in range(len(self.canvas.layers)): layer = self.canvas.layers[i] btn = self.create_layer_button(x, 90 + i * 105, i) self.layer_tables.append(LayerTable(x, 90 + i * 105, layer, btn, self)) def add_layer(self): self.canvas.add_layer() if len(self.canvas.layers) == 6: self.add_layer_button.setDisabled(True) self.update_layers_buttons() self.update() def eraser_button_clicked(self): self.canvas.choose_eraser() self.update() def brush_button_clicked(self): self.canvas.choose_brush() self.update() def line_button_clicked(self): self.canvas.choose_line() self.update() def rectangle_button_clicked(self): self.canvas.choose_rectangle() self.update() def triangle_button_clicked(self): self.canvas.choose_triangle() self.update() def ellipse_button_clicked(self): self.canvas.choose_ellipse() self.update() def fill_button_pressed(self): self.canvas.choose_fill() self.update() def selection_button_clicked(self): self.canvas.choose_selection() self.update() def horizontal_scrollbar_value_changed(self, value): self.update() def vertical_scrollbar_value_changed(self, value): self.update() def change_greyscale(self): if self.canvas.active_layer.greyscale: self.canvas.turn_greyscale_off() else: self.canvas.turn_greyscale_on() self.update_canvas() self.update_color_button() self.update() def deselect(self): self.canvas.deselect() self.deselect_action.setDisabled(True) self.delete_selection_action.setDisabled(True) self.to_draw_selection = False self.update() def select_all(self): self.canvas.deselect() self.shape_start = 0, 0 self.cursor_position = self.canvas.width - 1, self.canvas.height - 1 self.update_selection_position() self.canvas.select(*self.shape_start, *self.cursor_position) self.to_draw_selection = True self.deselect_action.setDisabled(False) self.delete_selection_action.setDisabled(False) self.update() def change_brightness(self, brightness): self.canvas.change_brightness(brightness) self.update_canvas() self.update() def brightness(self): success, brightness = BrightnessDialog.get_brightness(self, self.canvas.active_layer.brightness) if success: self.change_brightness(brightness) def delete_in_selection(self): if not self.canvas.selection_is_on: return self.canvas.delete_selection() self.update_canvas() self.update() @property def canvas_left_side(self): return self.canvas_left_edge - self.horizontal_scrollbar.value() @property def canvas_upper_side(self): return self.canvas_upper_edge - self.vertical_scrollbar.value() def size_edited(self, size): if size == '': value = 1 else: value = int(size) if value == 0: self.size_edit.setText('1') else: self.size_slider.setValue(value) def size_changed(self, value): if value == 0: self.canvas.brush_size = 1 else: self.canvas.brush_size = value if self.to_draw_canvas: self.change_cursor() self.size_edit.setText(f'{self.canvas.brush_size}') def pick_color(self): color = QColorDialog.getColor() if color.isValid(): self.canvas.change_color(color.red(), color.green(), color.blue(), color.alpha()) self.update_color_button() def update_color_button(self): cur_color = self.canvas.current_color color = QColor(cur_color.r, cur_color.g, cur_color.b) self.color_picker.setStyleSheet(f'background: {color.name()}') def ask_size(self): success, width, height = SizeDialog.get_size(self) if success: self.create_canvas(width, height) def create_canvas(self, width, height): old_canvas = self.canvas self.canvas = Canvas(width, height) self.canvas.current_color_rgb = old_canvas.current_color_rgb self.canvas.brush_size = old_canvas.brush_size self.canvas.current_tool = old_canvas.current_tool max_size = self.height() - self.SHIFT * 2 proportion = width / height if proportion > 1: self.canvas_width = max_size self.canvas_height = max_size / proportion else: self.canvas_width = max_size * proportion self.canvas_height = max_size self.pixel_size = self.canvas_width / self.canvas.width self.canvas_left_edge = (self.width() - self.canvas_width) / 2 self.canvas_upper_edge = (self.height() - self.canvas_height) / 2 self.canvas_as_image = self.convert_to_image() self.to_draw_canvas = True self.enable_actions() self.update_layers_buttons() def enable_actions(self): self.save_action.setDisabled(False) self.save_as_action.setDisabled(False) self.greyscale_action.setDisabled(False) self.brightness_action.setDisabled(False) self.select_all_action.setDisabled(False) def convert_to_image(self): image = QImage(self.canvas.width, self.canvas.height, QImage.Format_ARGB32) x = 0 y = 0 for layer in self.canvas.layers: for column in layer.pixels: for pixel in column: image.setPixelColor(x, y, QColor(pixel.r, pixel.g, pixel.b, pixel.a)) y += 1 x += 1 y = 0 return image def open(self): load_file_name = QFileDialog.getOpenFileName(self, 'Chose Image File', '', 'PNG Files (*.png);;JPG Files (*.jpg);;BMP Files (*.bmp)')[0] if load_file_name == '': return False self.picture_name = load_file_name image = QImage(load_file_name) self.create_canvas(image.width(), image.height()) for x in range(self.canvas.width): for y in range(self.canvas.height): color = image.pixelColor(x, y) self.canvas.pixels[x][y] = Color(color.red(), color.green(), color.blue(), color.alpha()) self.update_canvas() self.to_draw_canvas = True self.update() def save(self): if self.picture_name is None: self.save_as() else: self.canvas_as_image.save(self.picture_name) def save_as(self): name = QFileDialog.getSaveFileName(self, 'Save', '', 'PNG Files (*.png);;JPG Files (*.jpg);;BMP Files (*.bmp)')[0] if name == '': return False self.picture_name = name self.save() def change_cursor(self): if self.canvas.current_tool == Tools.BRUSH: self.setCursor(self.get_brush_cursor()) elif self.canvas.current_tool == Tools.ERASER: self.setCursor(self.get_eraser_cursor()) elif self.canvas.current_tool == Tools.FILL: self.setCursor(self.get_fill_cursor()) def get_brush_cursor(self): size = (2 * self.canvas.brush_size - 1) * self.pixel_size cursor = QPixmap(size, size) cursor.fill(Qt.transparent) painter = QPainter() painter.begin(cursor) painter.setPen(QColor(self.canvas.current_color.r, self.canvas.current_color.g, self.canvas.current_color.b)) painter.drawEllipse(0, 0, size - 1, size - 1) painter.drawLine(size / 2, size / 4, size / 2, size / 4 * 3) painter.drawLine(size / 4, size / 2, size / 4 * 3, size / 2) painter.end() return QCursor(cursor) def get_eraser_cursor(self): size = (2 * self.canvas.brush_size - 1) * self.pixel_size cursor = QPixmap(size, size) cursor.fill(Qt.transparent) painter = QPainter() painter.begin(cursor) painter.setBrush(QBrush(QColor(255, 255, 255))) painter.drawEllipse(0, 0, size - 1, size - 1) painter.end() return QCursor(cursor) def get_fill_cursor(self): fill = QImage('images/FillCursor.png') cursor = QPixmap(fill.width(), fill.height()) cursor.fill(Qt.transparent) painter = QPainter() painter.begin(cursor) painter.setBrush(QColor(self.canvas.current_color.r, self.canvas.current_color.g, self.canvas.current_color.b)) painter.drawRect(10, 10, 10, 4) painter.drawImage(0, 0, fill) painter.end() return QCursor(cursor) def mouseMoveEvent(self, event): if not self.to_draw_canvas: return x = math.floor((event.pos().x() - self.canvas_left_side) / self.pixel_size) y = math.floor((event.pos().y() - self.canvas_upper_side) / self.pixel_size) if 0 <= x < self.canvas.width and 0 <= y < self.canvas.height: self.cursor_position = (x, y) self.change_cursor() self.cursor_on_canvas = True else: if not self.mouse_pressed: self.shape_start = None self.cursor_on_canvas = False self.setCursor(Qt.ArrowCursor) if self.mouse_pressed: self.move_tools() self.update_canvas() self.update() def move_tools(self): if self.canvas.current_tool in [Tools.BRUSH, Tools.ERASER]: self.canvas.paint(*self.cursor_position) if self.cursor_on_canvas and self.canvas.current_tool == Tools.SELECTION: self.update_selection_position() def update_canvas(self): if not self.to_draw_canvas: return while len(self.canvas.changed_pixels) > 0: x, y = self.canvas.changed_pixels.pop() layer = len(self.canvas.layers) - 1 pixel = self.canvas.get_pixel(x, y, layer) while layer > 0 and pixel.a == 0: layer -= 1 pixel = self.canvas.get_pixel(x, y, layer) self.canvas_as_image.setPixelColor(x, y, QColor(pixel.r, pixel.g, pixel.b, pixel.a)) def mousePressEvent(self, event): if self.cursor_on_canvas and event.button() == Qt.LeftButton: self.mouse_pressed = True self.press_tools() def press_tools(self): if self.canvas.current_tool in [Tools.LINE, Tools.SQUARE, Tools.TRIANGLE, Tools.CIRCLE, Tools.SELECTION]: self.shape_start = self.cursor_position if self.canvas.current_tool in [Tools.BRUSH, Tools.ERASER]: self.canvas.paint(*self.cursor_position) elif self.canvas.current_tool == Tools.LINE: self.to_draw_line = True elif self.canvas.current_tool == Tools.SQUARE: self.to_draw_rectangle = True elif self.canvas.current_tool == Tools.TRIANGLE: self.to_draw_triangle = True elif self.canvas.current_tool == Tools.CIRCLE: self.to_draw_ellipse = True elif self.canvas.current_tool == Tools.FILL: self.canvas.fill(*self.cursor_position) elif self.canvas.current_tool == Tools.SELECTION: self.deselect() self.deselect_action.setDisabled(False) self.delete_selection_action.setDisabled(False) self.to_draw_selection = True def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton and self.to_draw_canvas: self.release_tools() self.update_canvas() self.update() self.mouse_pressed = False def release_tools(self): if self.shape_start is None: return if self.canvas.current_tool == Tools.SELECTION: self.canvas.select(*self.shape_start, *self.cursor_position) if self.canvas.current_tool == Tools.LINE: self.to_draw_line = False self.canvas.draw_line(*self.shape_start, *self.cursor_position) elif self.canvas.current_tool == Tools.SQUARE: self.to_draw_rectangle = False self.canvas.draw_rectangle(*self.shape_start, *self.cursor_position) elif self.canvas.current_tool == Tools.TRIANGLE: self.to_draw_triangle = False self.canvas.draw_triangle(*self.shape_start, *self.cursor_position) elif self.canvas.current_tool == Tools.CIRCLE: self.to_draw_ellipse = False self.canvas.draw_ellipse(*self.shape_start, *self.cursor_position) def wheelEvent(self, event): if not self.to_draw_canvas: return delta = event.angleDelta().y() / 120 old_width = self.canvas_width old_height = self.canvas_height if self.canvas.width * (self.pixel_size + delta) > 0 and self.canvas.height * (self.pixel_size + delta) > 0: self.pixel_size += delta self.canvas_width = self.canvas.width * self.pixel_size self.canvas_height = self.canvas.height * self.pixel_size self.canvas_left_edge += (old_width - self.canvas_width) / 2 self.canvas_upper_edge += (old_height - self.canvas_height) / 2 self.change_cursor() self.update() if self.canvas_left_edge < self.MINIMUM_CANVAS_LEFT_SHIFT: max = self.MINIMUM_CANVAS_LEFT_SHIFT - self.canvas_left_edge self.horizontal_scrollbar.setMaximum(max) self.horizontal_scrollbar.setMinimum(-max) self.horizontal_scrollbar.show() else: self.horizontal_scrollbar.hide() if self.canvas_upper_edge < self.MENU_BAR_HEIGHT: max = self.MENU_BAR_HEIGHT - self.canvas_upper_edge self.vertical_scrollbar.setMinimum(-max) self.vertical_scrollbar.setMaximum(max) self.vertical_scrollbar.show() else: self.vertical_scrollbar.hide() def paintEvent(self, event): painter = QPainter() painter.begin(self) if self.to_draw_canvas: self.draw_pixels(painter) painter.setPen(QColor(self.canvas.current_color.r, self.canvas.current_color.g, self.canvas.current_color.b)) if self.to_draw_line: self.draw_line(painter) if self.to_draw_rectangle: self.draw_rectangle(painter) if self.to_draw_triangle: self.draw_triangle(painter) if self.to_draw_ellipse: self.draw_ellipse(painter) if self.to_draw_selection: self.draw_selection(painter) self.draw_edges(painter) self.draw_layers(painter) painter.drawImage(0, self.menu_bar.height(), QImage('images/ToolBar.png')) self.highlight_current_button(painter) self.draw_buttons(painter) painter.end() def draw_layers(self, painter): painter.drawImage(self.width() - self.TOOLBAR_WIDTH, self.menu_bar.height(), QImage('images/LayersBar.png')) self.draw_current_layer(painter) for table in self.layer_tables: table.draw(painter) def highlight_current_button(self, painter): painter.setBrush(QColor(255, 255, 255)) painter.setPen(Qt.transparent) button = self.buttons[self.canvas.current_tool] painter.drawRect(button.x(), button.y(), self.BUTTON_SIZE, self.BUTTON_SIZE) def get_start_end_position(self): start_x, start_y = self.shape_start end_x, end_y = self.cursor_position start_x = start_x * self.pixel_size + self.canvas_left_side + self.pixel_size / 2 start_y = start_y * self.pixel_size + self.canvas_upper_side + self.pixel_size / 2 end_x = end_x * self.pixel_size + self.canvas_left_side + self.pixel_size / 2 end_y = end_y * self.pixel_size + self.canvas_upper_side + self.pixel_size / 2 return start_x, start_y, end_x, end_y def draw_line(self, painter): start_x, start_y, end_x, end_y = self.get_start_end_position() painter.drawLine(start_x, start_y, end_x, end_y) def draw_rectangle(self, painter): start_x, start_y, end_x, end_y = self.get_start_end_position() left = min(start_x, end_x) up = min(start_y, end_y) painter.drawRect(left, up, abs(end_x - start_x), abs(end_y - start_y)) def draw_triangle(self, painter): start_x, start_y, end_x, end_y = self.get_start_end_position() left = min(start_x, end_x) right = max(start_x, end_x) up = min(start_y, end_y) down = max(start_y, end_y) width = right - left left_up = left + width // 2 right_up = left_up + (width % 2) painter.drawLine(left_up, up, left, down) painter.drawLine(right_up, up, right, down) painter.drawLine(left, down, right, down) def draw_ellipse(self, painter): start_x, start_y, end_x, end_y = self.get_start_end_position() left = min(start_x, end_x) up = min(start_y, end_y) painter.drawEllipse(left, up, abs(end_x - start_x), abs(end_y - start_y)) def update_selection_position(self): start_x = self.shape_start[0] * self.pixel_size + self.canvas_left_side start_y = self.shape_start[1] * self.pixel_size + self.canvas_upper_side end_x = self.cursor_position[0] * self.pixel_size + self.canvas_left_side end_y = self.cursor_position[1] * self.pixel_size + self.canvas_upper_side self.selection_left = min(start_x, end_x) self.selection_right = max(start_x, end_x) + self.pixel_size self.selection_up = min(start_y, end_y) self.selection_down = max(start_y, end_y) + self.pixel_size self.selection_width = abs(self.cursor_position[0] - self.shape_start[0]) + 1 self.selection_height = abs(self.cursor_position[1] - self.shape_start[1]) + 1 def draw_selection(self, painter): width = self.pixel_size / 4 black_pen = QPen(QColor(0, 0, 0)) black_pen.setWidth(3) white_pen = QPen(QColor(255, 255, 255)) white_pen.setWidth(3) painter.setPen(black_pen) for x in range(self.selection_width): painter.drawLine(self.selection_left + x * self.pixel_size, self.selection_up, self.selection_left + x * self.pixel_size + width, self.selection_up) painter.drawLine(self.selection_left + x * self.pixel_size, self.selection_down, self.selection_left + x * self.pixel_size + width, self.selection_down) painter.setPen(white_pen) painter.drawLine(self.selection_left + x * self.pixel_size + width, self.selection_up, self.selection_left + x * self.pixel_size + width * 3, self.selection_up) painter.drawLine(self.selection_left + x * self.pixel_size + width, self.selection_down, self.selection_left + x * self.pixel_size + width * 3, self.selection_down) painter.setPen(black_pen) painter.drawLine(self.selection_left + x * self.pixel_size + width * 3, self.selection_up, self.selection_left + x * self.pixel_size + width * 4, self.selection_up) painter.drawLine(self.selection_left + x * self.pixel_size + width * 3, self.selection_down, self.selection_left + x * self.pixel_size + width * 4, self.selection_down) for y in range(self.selection_height): painter.drawLine(self.selection_left, self.selection_up + y * self.pixel_size, self.selection_left, self.selection_up + y * self.pixel_size + width) painter.drawLine(self.selection_right, self.selection_up + y * self.pixel_size, self.selection_right, self.selection_up + y * self.pixel_size + width) painter.setPen(white_pen) painter.drawLine(self.selection_left, self.selection_up + y * self.pixel_size + width, self.selection_left, self.selection_up + y * self.pixel_size + width * 3) painter.drawLine(self.selection_right, self.selection_up + y * self.pixel_size + width, self.selection_right, self.selection_up + y * self.pixel_size + width * 3) painter.setPen(black_pen) painter.drawLine(self.selection_left, self.selection_up + y * self.pixel_size + width * 3, self.selection_left, self.selection_up + y * self.pixel_size + width * 4) painter.drawLine(self.selection_right, self.selection_up + y * self.pixel_size + width * 3, self.selection_right, self.selection_up + y * self.pixel_size + width * 4) def draw_pixels(self, painter): painter.drawImage(self.canvas_left_side, self.canvas_upper_side, self.canvas_as_image.scaled(self.canvas_width, self.canvas_height)) painter.setBrush(Qt.transparent) black_pen = QPen(QColor(0, 0, 0)) black_pen.setWidth(3) painter.setPen(black_pen) painter.drawRect(self.canvas_left_side, self.canvas_upper_side, self.canvas_width, self.canvas_height) painter.setPen(Qt.black) self.draw_grid(painter) def draw_grid(self, painter): if self.pixel_size > 10: for i in range(self.canvas.width + 1): x = self.canvas_left_side + i * self.pixel_size painter.drawLine(x, self.canvas_upper_side, x, self.canvas_upper_side + self.canvas_height) for i in range(self.canvas.height + 1): y = self.canvas_upper_side + i * self.pixel_size painter.drawLine(self.canvas_left_side, y, self.canvas_left_side + self.canvas_width, y) def draw_edges(self, painter): painter.setPen(Qt.transparent) painter.setBrush(QColor('#393939')) painter.drawRect(self.vertical_scrollbar.x(), self.vertical_scrollbar.y(), self.vertical_scrollbar.width(), self.vertical_scrollbar.height() + self.horizontal_scrollbar.height() + 1) painter.drawRect(self.horizontal_scrollbar.x(), self.horizontal_scrollbar.y(), self.horizontal_scrollbar.width(), self.horizontal_scrollbar.height() + 1) def draw_current_layer(self, painter): if not self.to_draw_canvas: return painter.setBrush(Qt.white) table = self.layer_tables[self.canvas.current_layer] painter.drawRect(table.x - 1, table.y - 1, LayerTable.WIDTH + 2, LayerTable.HEIGHT + 2) def draw_buttons(self, painter): painter.setPen(Qt.transparent) painter.setBrush(QColor(self.canvas.current_color.r, self.canvas.current_color.g, self.canvas.current_color.b)) for button, image in self.button_images.items(): painter.drawRect(button.x() + 3, button.y() + 3, self.BUTTON_SIZE - 6, self.BUTTON_SIZE - 6) painter.drawImage(button.x(), button.y(), image.scaled(self.BUTTON_SIZE, self.BUTTON_SIZE))
class dicomImage2DdisplayWidget(QWidget): addSeedsSignal = pyqtSignal(bool) def __init__(self, **kwargs): super(dicomImage2DdisplayWidget, self).__init__() self._face = kwargs.get('face', 0) self._datas = kwargs.get('datas', 0) self._Spacing = kwargs.get('spacing', None) self._low_hu = kwargs.get("low_hu", -1150) self._high_hu = kwargs.get("high_hu", 3250) self._axis = 0 #===============Seeds information============================ self.seedsColors = [] self.baseImageSize = 512 self.regionDrawMod = 0 self.drawLayer = [] #===============Regioin draw tool parmeter=================== self.drawPanterbegin = QPoint() self.drawPanterEnd = QPoint() self.posX = 0 self.posY = 0 #===============Init UI====================================== self.initUI() def initUI(self): self.setGeometry(0, 0, self.baseImageSize, self.baseImageSize) self.viewLayout = None self.imLable = QLabel(self) self.imLable.setScaledContents(True) self.imData = None self.topLable = QLabel(self) self.downLable = QLabel(self) self.imLable.resize(self.width(), self.height()) self.initDicomParameter() pass def initDicomParameter(self): #============================SetDataParameter=========================== self._color_table = [qRgb(i, i, i) for i in range(64)] self.datas = self._datas.copy() self.faceWindowV = self.faceWindowH = max(self.datas.shape) #============================ChangeFaceSize============================= self.xSpacing, self.ySpacing, self.zSpacing = self._Spacing #============================OperationMod=============================== self.OperationMod = 0 self.facePlane = ['mainFaceplane', 'leftFaceplane', 'frontFaceplane'] self.idxSlice = 100 self.currentFace = self.facePlane[self._face] #============================RegionGrowingParameter===================== self.PosXY = [150, 75] # self.seedList = [(self.PosXY[0], self.PosXY[1])] self.seedList = [] self.seedSelectNum = 0 self.LowAndUpper = [10, 3000] self.regionArea = [] self.regionDrawSize = 5 self.idxSlicelimt = self.datas.shape[0] # print(self.datas.shape[0]) #======================================================================= self.initOperationButton() self.initDisplayfacePlane() self.choiceOpreationMod() pass def initOperationButton(self): self.facePlanes = QComboBox(self) self.facePlanes.addItem(self.facePlane[0]) self.facePlanes.addItem(self.facePlane[1]) self.facePlanes.addItem(self.facePlane[2]) self.facePlanes.setCurrentIndex(self._face) # self.facePlanes.activated[str].connect(self.faceItem_Choice) self.facePlanes.currentTextChanged.connect(self.faceItem_Choice) self.facePlanes.keyPressEvent = self.customComboxKeyEvent self.facePlanes.move((self.width() - self.facePlanes.width()), 0) #==================================Active keyBoard event without combobox======================= # shorcut = QShortcut(QKeySequence(Qt.Key_F), self.facePlanes, activated=self.useforTestKeyEvent) #=============================================================================================== #================================== Contrul region seed up and low range ======================= regionWide = QRangeSlider(self) regionWide.setMax(255) regionWide.setMin(0) regionWide.setStart(150) regionWide.setEnd(255) regionWide.setRange(0, 255) regionWide.setDrawValues(True) regionWide.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);') regionWide.handle.setStyleSheet('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #8EE5EE, stop:1 #393);') regionWide.startValueChanged.connect(self.rangeSliderStartVolue) regionWide.endValueChanged.connect(self.rangeSliderEndVolue) #=============================================================================================== self.modCombox = QComboBox(self) self.modCombox.addItem('Normal') self.modCombox.addItem('Region') self.modCombox.setCurrentIndex(self.OperationMod) # self.modCombox.activated[str].connect(self.mod_Choice) self.modCombox.currentTextChanged.connect(self.mod_Choice) self.modCombox.keyPressEvent = self.customComboxKeyEvent self.modCombox.move((self.width() - self.facePlanes.width() - self.modCombox.width()), 0) self.layerScrollBar = QScrollBar(Qt.Horizontal, self) self.layerScrollBar.setGeometry(0, 0, 128, 5) self.layerScrollBar.setMinimum(0) self.layerScrollBar.setMaximum(min(self.datas.shape)) self.layerScrollBar.setValue(0) self.layerScrollBar.sliderMoved.connect(self.selectLayer) self.BaseBoxLayout = QBoxLayout(QBoxLayout.TopToBottom) self.BaseBoxLayout.addWidget(self.layerScrollBar, 0) self.BaseBoxLayout.addWidget(regionWide, 1) self.BaseBoxLayout.setAlignment(Qt.AlignTop) self.secondBoxLayout = QBoxLayout(QBoxLayout.LeftToRight) self.secondBoxLayout.addLayout(self.BaseBoxLayout) self.secondBoxLayout.addWidget(self.modCombox) self.secondBoxLayout.addWidget(self.facePlanes) self.secondBoxLayout.setAlignment(Qt.AlignTop) self.groupbox = QGroupBox(self) self.groupbox.setGeometry(28, -64, 512, 64) self.groupbox.setLayout(self.secondBoxLayout) self.showButton = QPushButton(self) self.showButton.setGeometry(0, 0, 16, 16) self.showButton.clicked.connect(self.playAnimation) self.initAnimation() pass def setGroup_pos(self, apos): self.groupbox.move(apos.x(), apos.y()) pass def setSeedsColor(self, lists): # self.seedList.clear() # self.seedsColors.clear() # for i in range(0, len(colorList)): # self.seedsColors.append(colorList[i][0]) # self.seedList.append(colorList[i][1]) self.seedsColors.append(lists[0]) self.seedList.append(lists[1]) print('seedList:', self.seedList) pass def selectSeedinList(self, num): # tmpS = self.seedList[num] # tmpC = self.seedsColors[num] self.seedSelectNum = num # print(self.seedsColors) # print(self.seedList) # print('number is :', num) # print(tmpC, tmpS) pass def removeSeedinList(self, num): self.seedList.remove(self.seedList[num]) self.choiceDisplayMod() pass def rangeSliderStartVolue(self, event): self.LowAndUpper[0] = event self.choiceDisplayMod() pass def rangeSliderEndVolue(self, event): self.LowAndUpper[1] = event self.choiceDisplayMod() pass def viewSeedinList(self, event): if event[0] == True: print('Open eye is:', event[1]) elif event[0] == False: print('Close eye is:', event[1]) else: print('viewSeedinList error.....') pass def initAnimation(self): self.isBoardshow = False xAxis = self.groupbox.pos().x() yAxis = self.groupbox.height() self.groupBoxAnim = QPropertyAnimation(self, b'pos') self.groupBoxAnim.setDuration(200) self.groupBoxAnim.setStartValue(QPointF(xAxis, -yAxis)) # self.anim.setKeyValueAt(0.5, QPointF(0, 10)) # self.anim.setKeyValueAt(0.8, QPointF(0, 80)) self.groupBoxAnim.setEndValue(QPointF(xAxis, 0)) self.reverGroupBoxAnim = QPropertyAnimation(self, b'pos') self.reverGroupBoxAnim.setDuration(200) self.reverGroupBoxAnim.setStartValue(QPointF(xAxis, 0)) self.reverGroupBoxAnim.setEndValue(QPointF(xAxis, -yAxis)) pass def playAnimation(self): print('-----PlayAnimation-----') if self.isBoardshow == False: self.reverGroupBoxAnim.stop() self.groupBoxAnim.start() self.isBoardshow = True elif self.isBoardshow == True: self.groupBoxAnim.stop() self.reverGroupBoxAnim.start() self.isBoardshow = False pass pos = pyqtProperty(QPointF, fset=setGroup_pos) def selectLayer(self, event): self.idxSlice = self.layerScrollBar.value() self.choiceDisplayMod() pass def sliderval(self): self._low_hu = self.lowHusBar.value() self._high_hu = self.heighHusBar.value() self.choiceDisplayMod() pass def mod_Choice(self, event): if event == 'Normal': self.OperationMod = 0 elif event == 'Region': self.OperationMod = 1 self.choiceOpreationMod() pass def initDisplayfacePlane(self): if self._face == 0: self.topfaceView() elif self._face == 1: self.leftfaceView() elif self._face == 2: self.frontfaceView() pass def faceItem_Choice(self, faceEvent): if faceEvent == self.facePlane[0]: self.topfaceView() self.currentFace = self.facePlane[0] print('main view') elif faceEvent == self.facePlane[1]: self.leftfaceView() self.currentFace = self.facePlane[1] print('left view') elif faceEvent == self.facePlane[2]: self.frontfaceView() self.currentFace = self.facePlane[2] print('front view') self.choiceOpreationMod() self.getResizeEvent(self.width(), self.height()) pass #==========================MakeSureDisplayMod============================= def choiceDisplayMod(self): if self.OperationMod == 0: self.drawNomralArea() elif self.OperationMod == 1: self.drawGrowingArea() pass #========================================================================= def choiceOpreationMod(self): if self.OperationMod == 0: self.imLable.mouseMoveEvent = self.normalModMouseMoveEvent elif self.OperationMod == 1: self.imLable.mouseMoveEvent = self.regionModMouseMoveEvent self.imLable.mousePressEvent = self.regionModMousePressEvent self.imLable.mouseReleaseEvent = self.regionModMouseReleasedEvent self.imLable.wheelEvent = self.regionGrowingWheelEvent self.choiceDisplayMod() pass def topfaceView(self): self.datas = self._datas.copy() self.idxSlicelimt = self.datas.shape[0] self.faceWindowH = self.faceWindowV = self.width() tmpPalete = QPalette() tmpPalete.setColor(QPalette.Background, QColor(0, 0, 0)) self.setPalette(tmpPalete) #=======================Init drawLayer=================== self.drawLayer = np.full(self.datas.shape, 0) print('topfaceView:', self.drawLayer.shape) pass def leftfaceView(self): self.datas = self._datas.copy() self.datas = np.rot90(self.datas, -1) self.datas = np.rot90(self.datas, axes=(0, 2)) self.idxSlicelimt = self.datas.shape[0] self.setScaleSize(max(self.datas.shape), min(self.datas.shape)) tmpPalete = QPalette() tmpPalete.setColor(QPalette.Background, QColor(0, 0, 0)) self.setPalette(tmpPalete) #=======================Init drawLayer=================== self.drawLayer = np.full(self.datas.shape, 0) print('leftfaceView:', self.drawLayer.shape) pass def frontfaceView(self): self.datas = self._datas.copy() self.datas = np.rot90(self.datas, -1) self.idxSlicelimt = self.datas.shape[0] width = self.datas.shape[0] height = self.datas.shape[1] depth = self.datas.shape[2] self.setScaleSize(max(width, height, depth), min(width, height, depth)) tmpPalete = QPalette() tmpPalete.setColor(QPalette.Background, QColor(0, 0, 0)) self.setPalette(tmpPalete) #=======================Init drawLayer=================== self.drawLayer = np.full(self.datas.shape, 0) print('frontfaceView:', self.drawLayer.shape) pass def drawNomralArea(self): self.idxSlice = np.clip(self.idxSlice, 0, self.idxSlicelimt -1) self.imData = self.datas[self.idxSlice] self.displayDicomImage() pass def drawGrowingArea(self): self.imgOriginal = SimpleITK.GetImageFromArray(self.datas[self.idxSlice]) self.imgWhiteMatter = SimpleITK.ConnectedThreshold(image1=self.imgOriginal, seedList=self.seedList, lower=self.LowAndUpper[0], upper=self.LowAndUpper[1], replaceValue=1, ) self.regionArea = SimpleITK.GetArrayFromImage(self.imgWhiteMatter) #================if use draw or eraser==================== if np.sum(self.drawLayer[self.idxSlice] != 0) != 0: self.regionDrawLayerCombinEvent() self.drawGrowingAreaContour() pass def drawGrowingAreaContour(self): foreColorvalue = 1 self.imgWhiteMatter = SimpleITK.GetImageFromArray(self.regionArea) self.imgWhiteMatterNoHoles = SimpleITK.VotingBinaryHoleFilling(image1=self.imgWhiteMatter, radius=[2] * 3, majorityThreshold=50, backgroundValue=0, foregroundValue=foreColorvalue) regionContour = SimpleITK.LabelContour(self.imgWhiteMatterNoHoles) # tmpWmatter = self.imgWhiteMatter # regionContour = tmpWmatter | regionContour tmpImage = SimpleITK.LabelOverlay(self.imgOriginal, regionContour) regionContourArray = SimpleITK.GetArrayFromImage(tmpImage) self.imData = regionContourArray self.displayDicomImage() pass #==============================Key board event ============================================ def customComboxKeyEvent(self, event): print('ComboxKeyEvent') pass def useforTestKeyEvent(self): print('just test combobox key event') # self.displayDicomImage() pass #==============================Use for display dicom image================================= def displayDicomImage(self): if self.imData is not None: raw_data = self.imData shape = self.imData.shape # maxNum = max(shape) # minNum = min(shape) raw_data[raw_data < 0] = 0 raw_data[raw_data > 255] = 255 if len(shape) >= 3: data = raw_data #=================用于调节对比度的方法======================= # data = (raw_data - self._low_hu) / self.window_width * 256 # print('---------Update3d--------') #=========================================================== data = data.astype(np.int8) tmpImage = QImage(data, shape[1], shape[0], shape[1] * shape[2], QImage.Format_RGB888) pixmap = QPixmap.fromImage(tmpImage) # pixmap = pixmap.scaled(self.faceWindowH , self.faceWindowV ) # pixmap = pixmap.scaled(self.xSpacing, self.zSpacing) # pixmap = pixmap.scaled(1024, 128) self.imLable.setPixmap(pixmap) elif len(shape) < 3: data = raw_data # data = (raw_data - self._low_hu) / self.window_width * 256 # print('---------Update2d---------') data = data.astype(np.int8) tmpImage = QImage(data, shape[1], shape[0], QImage.Format_Grayscale8) tmpImage.setColorTable(self._color_table) pixmap = QPixmap.fromImage(tmpImage) # pixmap = pixmap.scaled(self.faceWindowH, self.faceWindowV) # pixmap = pixmap.scaled(self.xSpacing, self.zSpacing) # pixmap = pixmap.scaled(1024, 128) self.imLable.setPixmap(pixmap) pass def normalModMouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: xAxis = event.pos().x() yAxis = event.pos().y() self.choiceDisplayMod() pass #=============================Region draw layer operation========================================== def regionDrawLayerEvent(self, x, y, value): self.regionArea[y - self.regionDrawSize:y + self.regionDrawSize, x - self.regionDrawSize:x + self.regionDrawSize] = value self.drawLayer[self.idxSlice] = self.regionArea pass def regionDrawLayerCombinEvent(self): self.regionArea = self.drawLayer[self.idxSlice].astype(np.uint8) pass #=============================Region mod mouse Press and released event============================ def regionModMousePressEvent(self, event): if event.buttons() == Qt.LeftButton and self.regionDrawMod != 0: xAxis = event.pos().x() yAxis = event.pos().y() if xAxis >= 0 and yAxis >= 0: tmpX = math.floor(xAxis * (self.baseImageSize / self.imLable.width())) tmpY = math.floor(yAxis * (self.baseImageSize / self.imLable.height())) if self.regionDrawMod == 1: self.regionDrawLayerEvent(tmpX, tmpY, 1) elif self.regionDrawMod == 2: self.regionDrawLayerEvent(tmpX, tmpY, 0) self.drawGrowingAreaContour() pass def regionModMouseReleasedEvent(self, Event): if Event.buttons() == Qt.RightButton: print('Right button released') pass #================================================================================================== #=====================================Region mod mouse move event================================== def regionModMouseMoveEvent(self, event): self.posX = event.pos().x() self.posY = event.pos().y() if event.buttons() == Qt.LeftButton and self.regionDrawMod == 0: if self.regionDrawMod == 0: xAxis = event.pos().x() yAxis = event.pos().y() if xAxis >= 0 and yAxis >= 0: self.PosXY[0] = math.floor(xAxis * (self.baseImageSize / self.imLable.width())) self.PosXY[1] = math.floor(yAxis * (self.baseImageSize / self.imLable.height())) self.seedList[self.seedSelectNum] = (self.PosXY[0], self.PosXY[1]) else: print('Region Mod has Nagtive number') elif event.buttons() == Qt.LeftButton and self.regionDrawMod != 0: xAxis = event.pos().x() yAxis = event.pos().y() if xAxis >= 0 and yAxis >= 0: tmpX = math.floor(xAxis * (self.baseImageSize / self.imLable.width())) tmpY = math.floor(yAxis * (self.baseImageSize / self.imLable.height())) if self.regionDrawMod == 1: self.regionDrawLayerEvent(tmpX, tmpY, 1) elif self.regionDrawMod == 2: self.regionDrawLayerEvent(tmpX, tmpY, 0) else: print('regionModMouseMoveEvent regionDrawMod error......') return self.drawGrowingAreaContour() return else: print('regionModMouseMoveEvent error......') self.choiceDisplayMod() pass #=================================SetWindowSizeEvent========================================== def setScaleSize(self, maxnum, minnum): self.faceWindowH = maxnum self.faceWindowV = minnum * (max(self.xSpacing, self.ySpacing, self.zSpacing) / min(self.xSpacing, self.ySpacing, self.zSpacing)) pass def getResizeEvent(self, sizeX, sizeY): if self.currentFace == self.facePlane[0]: tmpSize = min(sizeX, sizeY) self.imLable.resize(tmpSize, tmpSize) elif self.currentFace == self.facePlane[1]: #==================Resize Lable=================== self.setScaleSize(min(sizeX, sizeY), min(sizeX, sizeY) * (min(self.datas.shape)/max(self.datas.shape))) self.imLable.resize(self.faceWindowH, self.faceWindowV) elif self.currentFace == self.facePlane[2]: self.setScaleSize(min(sizeX, sizeY), min(sizeX, sizeY) * (min(self.datas.shape) / max(self.datas.shape))) self.imLable.resize(self.faceWindowH, self.faceWindowV) #==================Move Lable===================== maxPosY = max(sizeY, self.imLable.height()) minPoxY = min(sizeY, self.imLable.height()) tmpPosX = np.clip((sizeX - sizeY), 0, max(sizeX, sizeY)) / 2 tmpPosY = (maxPosY - minPoxY) / 2 self.imLable.move(tmpPosX, tmpPosY) pass #===========================mousewheelEvent================================== def regionGrowingWheelEvent(self, event): angle = event.angleDelta() / 8 angleX = angle.x() angleY = angle.y() if angleY > 0: self.regionDrawSize -= 1 elif angleY < 0: self.regionDrawSize += 1 pass #==========================RegionDrawMod===================== def setRegionDrawMod(self, event): if event == 0: self.regionDrawMod = 0 elif event == 1: self.regionDrawMod = 1 elif event == 2: self.regionDrawMod = 2 else: print('setRegionDrawMod error....') pass #====================Use for paint or eraser==================== def paintEvent(self, QPaintEvent): pen1 = QPen(Qt.blue, 1) q = QPainter(self) q.setPen(pen1) q.drawRect(self.posX - 25, self.posY - 25, 50, 50) # print('paintEvent') pass @property def window_width(self): return self._high_hu - self._low_hu #======================================================================================================================= # pathDicom = "D:/Dicomfile/MT_07/" # idxSlice = 50 # reader = SimpleITK.ImageSeriesReader() # filenamesDICOM = reader.GetGDCMSeriesFileNames(pathDicom) # # reader.SetFileNames(filenamesDICOM) # imgOriginals = reader.Execute() # datas = SimpleITK.GetArrayFromImage(imgOriginals) # Spacing = imgOriginals.GetSpacing() # # if __name__ == '__main__': # app = QApplication(sys.argv) # win = dicomImage2DdisplayWidget(face=0, datas= datas, spacing=Spacing) # win.show() # sys.exit(app.exec_())
class Example(QMainWindow): def __init__(self): super().__init__() self.background = QWidget(self) self.background.setGeometry(30, 20, 609, 321) self.background.setAutoFillBackground(True) p = self.background.palette() p.setColor(self.background.backgroundRole(), Qt.cyan) self.background.setPalette(p) loadUi("untitled.ui", self) self.initUI() def initUI(self): self.resize(1200, 650) self.move(300, 200) self.setWindowTitle('Map Editor v0.1') self.setWindowIcon(QIcon('web.png')) self.actualTexture = 0 self.mapInfo = numpy.zeros( 4, dtype=int ) # Wielkość X mapy, wielkość Y mapy, pozycja X portalu, pozycja Y portalu self.mtiles = {} self.mtilesHp = {} self.mpickups = {} self.mtraps = {} self.menemies = {} self.playerPos = {} # MENU self.flipButton.hide() self.hpLabel.hide() self.hpEditor.hide() self.armorLabel.hide() self.armorEditor.hide() self.mhpl.hide() # max hp label self.marl.hide() # max armor label self.mhpe.hide() # max hp editor self.mare.hide() # max armor editor self.hpEditor.valueChanged.connect(self.setMaxParameters) self.armorEditor.valueChanged.connect(self.setMaxParameters) self.playerInfo = numpy.zeros(6, dtype=int) # scrolle do przewijania mapy self.scrollX = QScrollBar(Qt.Horizontal, self) self.scrollX.setGeometry(30, 341, 609, 16) self.scrollY = QScrollBar(Qt.Vertical, self) self.scrollY.setGeometry(638, 20, 16, 320) self.scrollX.valueChanged.connect(self.prepareMap) self.scrollY.valueChanged.connect(self.prepareMap) self.checkButton.clicked.connect(self.checkInfo) self.button = 1 self.tiles = [ self.tile1, self.tile2, self.tile3, self.tile4, self.tile5, self.tile6, self.tile7, self.tile8, self.tile9, self.tile10, self.tile11, self.tile12, self.tile13, self.tile14, self.tile15, self.tile16, self.tile17, self.tile18, self.tile19, self.tile20, self.tile21, self.tile22, self.tile23, self.tile24, self.tile25, self.tile26, self.tile27, self.tile28, self.tile29, self.tile30, self.tile31, self.tile32, self.tile33, self.tile34, self.tile35, self.tile36, self.tile37, self.tile38, self.tile39, self.tile40, self.tile41, self.tile42, self.tile43, self.tile44, self.tile45, self.tile46, self.tile47, self.tile48, self.tile49, self.tile50, self.tile51, self.tile52, self.tile53, self.tile54, self.tile55, self.tile56, self.tile57, self.tile58, self.tile59, self.tile60, self.tile61, self.tile62, self.tile63, self.tile64, self.tile65, self.tile66, self.tile67, self.tile68, self.tile69, self.tile70, self.tile71, self.tile72, self.tile73, self.tile74, self.tile75, self.tile76, self.tile77, self.tile78, self.tile79, self.tile80, self.tile81, self.tile82, self.tile83, self.tile84, self.tile85, self.tile86, self.tile87, self.tile88, self.tile89, self.tile90, self.tile91, self.tile92, self.tile93, self.tile94, self.tile95, self.tile96, self.tile97, self.tile98, self.tile99, self.tile100, self.tile101, self.tile102, self.tile103, self.tile104, self.tile105, self.tile106, self.tile107, self.tile108, self.tile109, self.tile110, self.tile111, self.tile112, self.tile113, self.tile114, self.tile115, self.tile116, self.tile117, self.tile118, self.tile119, self.tile120, self.tile121, self.tile122, self.tile123, self.tile124, self.tile125, self.tile126, self.tile127, self.tile128, self.tile129, self.tile130, self.tile131, self.tile132, self.tile133, self.tile134, self.tile135, self.tile136, self.tile137, self.tile138, self.tile139, self.tile140, self.tile141, self.tile142, self.tile143, self.tile144, self.tile145, self.tile146, self.tile147, self.tile148, self.tile149, self.tile150, self.tile151, self.tile152, self.tile153, self.tile154, self.tile155, self.tile156, self.tile157, self.tile158, self.tile159, self.tile160, self.tile161, self.tile162, self.tile163, self.tile164, self.tile165, self.tile166, self.tile167, self.tile168, self.tile169, self.tile170, self.tile171, self.tile172, self.tile173, self.tile174, self.tile175, self.tile176, self.tile177, self.tile178, self.tile179, self.tile180, self.tile181, self.tile182, self.tile183, self.tile184, self.tile185, self.tile186, self.tile187, self.tile188, self.tile189, self.tile190 ] self.enemies = [ self.enemy1, self.enemy2, self.enemy3, self.enemy4, self.enemy5, self.enemy6, self.enemy7, self.enemy8, self.enemy9, self.enemy10, self.enemy11, self.enemy12, self.enemy13, self.enemy14, self.enemy15, self.enemy16, self.enemy17, self.enemy18, self.enemy19, self.enemy20, self.enemy21, self.enemy22, self.enemy23, self.enemy24, self.enemy25, self.enemy26, self.enemy27, self.enemy28, self.enemy29, self.enemy30, self.enemy31, self.enemy32, self.enemy33, self.enemy34, self.enemy35, self.enemy36, self.enemy37, self.enemy38, self.enemy39, self.enemy40, self.enemy41, self.enemy42, self.enemy43, self.enemy44, self.enemy45, self.enemy46, self.enemy47, self.enemy48, self.enemy49, self.enemy50, self.enemy51, self.enemy52, self.enemy53, self.enemy54, self.enemy55, self.enemy56, self.enemy57, self.enemy58, self.enemy59, self.enemy60, self.enemy61, self.enemy62, self.enemy63, self.enemy64, self.enemy65, self.enemy66, self.enemy67, self.enemy68, self.enemy69, self.enemy70, self.enemy71, self.enemy72, self.enemy73, self.enemy74, self.enemy75, self.enemy76, self.enemy77, self.enemy78, self.enemy79, self.enemy80, self.enemy81, self.enemy82, self.enemy83, self.enemy84, self.enemy85, self.enemy86, self.enemy87, self.enemy88, self.enemy89, self.enemy90, self.enemy91, self.enemy92, self.enemy93, self.enemy94, self.enemy95, self.enemy96, self.enemy97, self.enemy98, self.enemy99, self.enemy100, self.enemy101, self.enemy102, self.enemy103, self.enemy104, self.enemy105, self.enemy106, self.enemy107, self.enemy108, self.enemy109, self.enemy110, self.enemy111, self.enemy112, self.enemy113, self.enemy114, self.enemy115, self.enemy116, self.enemy117, self.enemy118, self.enemy119, self.enemy120, self.enemy121, self.enemy122, self.enemy123, self.enemy124, self.enemy125, self.enemy126, self.enemy127, self.enemy128, self.enemy129, self.enemy130, self.enemy131, self.enemy132, self.enemy133, self.enemy134, self.enemy135, self.enemy136, self.enemy137, self.enemy138, self.enemy139, self.enemy140, self.enemy141, self.enemy142, self.enemy143, self.enemy144, self.enemy145, self.enemy146, self.enemy147, self.enemy148, self.enemy149, self.enemy150, self.enemy151, self.enemy152, self.enemy153, self.enemy154, self.enemy155, self.enemy156, self.enemy157, self.enemy158, self.enemy159, self.enemy160, self.enemy161, self.enemy162, self.enemy163, self.enemy164, self.enemy165, self.enemy166, self.enemy167, self.enemy168, self.enemy169, self.enemy170, self.enemy171, self.enemy172, self.enemy173, self.enemy174, self.enemy175, self.enemy176, self.enemy177, self.enemy178, self.enemy179, self.enemy180, self.enemy181, self.enemy182, self.enemy183, self.enemy184, self.enemy185, self.enemy186, self.enemy187, self.enemy188, self.enemy189, self.enemy190 ] self.pickups = [ self.pickup1, self.pickup2, self.pickup3, self.pickup4, self.pickup5, self.pickup6, self.pickup7, self.pickup8, self.pickup9, self.pickup10, self.pickup11, self.pickup12, self.pickup13, self.pickup14, self.pickup15, self.pickup16, self.pickup17, self.pickup18, self.pickup19, self.pickup20, self.pickup21, self.pickup22, self.pickup23, self.pickup24, self.pickup25, self.pickup26, self.pickup27, self.pickup28, self.pickup29, self.pickup30, self.pickup31, self.pickup32, self.pickup33, self.pickup34, self.pickup35, self.pickup36, self.pickup37, self.pickup38, self.pickup39, self.pickup40, self.pickup41, self.pickup42, self.pickup43, self.pickup44, self.pickup45, self.pickup46, self.pickup47, self.pickup48, self.pickup49, self.pickup50, self.pickup51, self.pickup52, self.pickup53, self.pickup54, self.pickup55, self.pickup56, self.pickup57, self.pickup58, self.pickup59, self.pickup60, self.pickup61, self.pickup62, self.pickup63, self.pickup64, self.pickup65, self.pickup66, self.pickup67, self.pickup68, self.pickup69, self.pickup70, self.pickup71, self.pickup72, self.pickup73, self.pickup74, self.pickup75, self.pickup76, self.pickup77, self.pickup78, self.pickup79, self.pickup80, self.pickup81, self.pickup82, self.pickup83, self.pickup84, self.pickup85, self.pickup86, self.pickup87, self.pickup88, self.pickup89, self.pickup90, self.pickup91, self.pickup92, self.pickup93, self.pickup94, self.pickup95, self.pickup96, self.pickup97, self.pickup98, self.pickup99, self.pickup100, self.pickup101, self.pickup102, self.pickup103, self.pickup104, self.pickup105, self.pickup106, self.pickup107, self.pickup108, self.pickup109, self.pickup110, self.pickup111, self.pickup112, self.pickup113, self.pickup114, self.pickup115, self.pickup116, self.pickup117, self.pickup118, self.pickup119, self.pickup120, self.pickup121, self.pickup122, self.pickup123, self.pickup124, self.pickup125, self.pickup126, self.pickup127, self.pickup128, self.pickup129, self.pickup130, self.pickup131, self.pickup132, self.pickup133, self.pickup134, self.pickup135, self.pickup136, self.pickup137, self.pickup138, self.pickup139, self.pickup140, self.pickup141, self.pickup142, self.pickup143, self.pickup144, self.pickup145, self.pickup146, self.pickup147, self.pickup148, self.pickup149, self.pickup150, self.pickup151, self.pickup152, self.pickup153, self.pickup154, self.pickup155, self.pickup156, self.pickup157, self.pickup158, self.pickup159, self.pickup160, self.pickup161, self.pickup162, self.pickup163, self.pickup164, self.pickup165, self.pickup166, self.pickup167, self.pickup168, self.pickup169, self.pickup170, self.pickup171, self.pickup172, self.pickup173, self.pickup174, self.pickup175, self.pickup176, self.pickup177, self.pickup178, self.pickup179, self.pickup180, self.pickup181, self.pickup182, self.pickup183, self.pickup184, self.pickup185, self.pickup186, self.pickup187, self.pickup188, self.pickup189, self.pickup190 ] self.traps = [ self.trap1, self.trap2, self.trap3, self.trap4, self.trap5, self.trap6, self.trap7, self.trap8, self.trap9, self.trap10, self.trap11, self.trap12, self.trap13, self.trap14, self.trap15, self.trap16, self.trap17, self.trap18, self.trap19, self.trap20, self.trap21, self.trap22, self.trap23, self.trap24, self.trap25, self.trap26, self.trap27, self.trap28, self.trap29, self.trap30, self.trap31, self.trap32, self.trap33, self.trap34, self.trap35, self.trap36, self.trap37, self.trap38, self.trap39, self.trap40, self.trap41, self.trap42, self.trap43, self.trap44, self.trap45, self.trap46, self.trap47, self.trap48, self.trap49, self.trap50, self.trap51, self.trap52, self.trap53, self.trap54, self.trap55, self.trap56, self.trap57, self.trap58, self.trap59, self.trap60, self.trap61, self.trap62, self.trap63, self.trap64, self.trap65, self.trap66, self.trap67, self.trap68, self.trap69, self.trap70, self.trap71, self.trap72, self.trap73, self.trap74, self.trap75, self.trap76, self.trap77, self.trap78, self.trap79, self.trap80, self.trap81, self.trap82, self.trap83, self.trap84, self.trap85, self.trap86, self.trap87, self.trap88, self.trap89, self.trap90, self.trap91, self.trap92, self.trap93, self.trap94, self.trap95, self.trap96, self.trap97, self.trap98, self.trap99, self.trap100, self.trap101, self.trap102, self.trap103, self.trap104, self.trap105, self.trap106, self.trap107, self.trap108, self.trap109, self.trap110, self.trap111, self.trap112, self.trap113, self.trap114, self.trap115, self.trap116, self.trap117, self.trap118, self.trap119, self.trap120, self.trap121, self.trap122, self.trap123, self.trap124, self.trap125, self.trap126, self.trap127, self.trap128, self.trap129, self.trap130, self.trap131, self.trap132, self.trap133, self.trap134, self.trap135, self.trap136, self.trap137, self.trap138, self.trap139, self.trap140, self.trap141, self.trap142, self.trap143, self.trap144, self.trap145, self.trap146, self.trap147, self.trap148, self.trap149, self.trap150, self.trap151, self.trap152, self.trap153, self.trap154, self.trap155, self.trap156, self.trap157, self.trap158, self.trap159, self.trap160, self.trap161, self.trap162, self.trap163, self.trap164, self.trap165, self.trap166, self.trap167, self.trap168, self.trap169, self.trap170, self.trap171, self.trap172, self.trap173, self.trap174, self.trap175, self.trap176, self.trap177, self.trap178, self.trap179, self.trap180, self.trap181, self.trap182, self.trap183, self.trap184, self.trap185, self.trap186, self.trap187, self.trap188, self.trap189, self.trap190 ] self.names = [ "Brick", "Box", "AK", "Pistol", "Rock", "Shield", "Heart", "Dog", "Soldier", "Spikes", "Shooter", "Shooter", "Shooter", "Shooter", "Player", "Portal" ] self.pixmaps = [ "./textures/blank.png", "./textures/brick.png", "./textures/box.png", "./textures/ak.png", "./textures/pistol.png", "./textures/rock.png", "./textures/armor.png", "./textures/heart.png", "./textures/dog.png", "./textures/enemy.png", "./textures/spikes.png", "./textures/shooter1.png", "./textures/shooter2.png", "./textures/shooter3.png", "./textures/shooter4.png", "./textures/spawn.png", "./textures/portal.png" ] self.bpixmaps = [ "./textures/brick.png", "./textures/box.png", "./textures/ak.png", "./textures/pistol.png", "./textures/rock.png", "./textures/armor.png", "./textures/heart.png", "./textures/dog.png", "./textures/enemy.png", "./textures/spikes.png", "./textures/shooter1.png", "./textures/shooter2.png", "./textures/shooter3.png", "./textures/shooter4.png", "./textures/player.png", "./textures/portal.png" ] # obrót shootera self.flip = 0 self.shooterFlip = [ "./textures/shooter1.png", "./textures/shooter2.png", "./textures/shooter3.png", "./textures/shooter4.png" ] self.flipButton.clicked.connect(self.changeShooterFlip) self.buttons = [ self.l1, self.l2, self.l3, self.l4, self.l5, self.l6, self.l7, self.l8, self.l9, self.l10, self.l11, self.spawnpointButton, self.endMapButton ] self.l8.setIconSize(QSize(64, 64)) self.l9.setIconSize(QSize(64, 64)) self.confirmSizeButton.clicked.connect(self.makeArray) self.saveButton.clicked.connect(self.save) for button, pixmap, i in zip(self.buttons, self.bpixmaps, range(1, len(self.buttons) + 1)): if i < 12: button.setIcon(QIcon(QPixmap(pixmap))) button.setIconSize(QSize(32, 32)) if i > 8: button.setIconSize(QSize(64, 64)) button.clicked.connect(partial(self.makeMenu, i)) else: button.clicked.connect(partial(self.makeMenu, i + 3)) self.makeArray() self.show() def changeShooterFlip(self): self.flip = (self.flip + 1) % 4 self.makeMenu(11 + self.flip) def makeMenu(self, i): print(i) self.infoLabel.setText('') self.actualTexture = i self.nameLabel.setText(self.names[i - 1]) self.podglad.setPixmap(QPixmap(self.pixmaps[i])) self.hpLabel.hide() self.hpEditor.hide() self.flipButton.hide() self.armorLabel.hide() self.armorEditor.hide() self.mhpl.hide() self.marl.hide() self.mhpe.hide() self.mare.hide() if i == 2: self.hpLabel.show() self.hpEditor.show() if i == 11: self.flip = 0 if 11 <= i < 15: self.flipButton.show() if i == 8 or i == 9: self.hpLabel.show() self.hpEditor.show() self.armorLabel.show() self.armorEditor.show() if i == 15: self.hpLabel.show() self.hpEditor.show() self.armorLabel.show() self.armorEditor.show() self.mhpl.show() self.marl.show() self.mhpe.show() self.mare.show() def setMaxParameters(self): self.mare.setMinimum(self.armorEditor.value()) self.mhpe.setMinimum(self.hpEditor.value()) def makeArray(self): allOk = 0 sizeX = self.sizeX.toPlainText() sizeY = self.sizeY.toPlainText() try: self.mapInfo[0] = (int)(sizeX) self.mapInfo[1] = (int)(sizeY) allOk = 1 except ValueError: msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Information") msg.setText("Entered data must be numbers!") msg.show() if allOk: if self.mapInfo[0] >= 19 and self.mapInfo[1] >= 10: self.mtiles = numpy.zeros((self.mapInfo[0], self.mapInfo[1]), dtype=int) self.mtilesHp = numpy.zeros((self.mapInfo[0], self.mapInfo[1]), dtype=int) self.mpickups = numpy.zeros((self.mapInfo[0], self.mapInfo[1]), dtype=int) self.mtraps = numpy.zeros((self.mapInfo[0], self.mapInfo[1]), dtype=int) self.menemies = numpy.zeros((self.mapInfo[0], self.mapInfo[1]), dtype=int) self.playerPos = numpy.zeros( (self.mapInfo[0], self.mapInfo[1]), dtype=int) self.scrollX.setMaximum(self.mapInfo[0] - 19) self.scrollY.setMaximum(self.mapInfo[1] - 10) msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Information") msg.setText("Current dimensions: " + sizeX + "x" + sizeY) msg.show() self.prepareMap() else: msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Information") msg.setText("Dimensions must be >= 19x10") msg.show() def prepareMap(self): for i in range(19): for j in range(10): self.tiles[19 * j + i].setPixmap( QPixmap(self.pixmaps[self.mtiles[i + self.scrollX.value()][ j + self.scrollY.value()]])) self.pickups[19 * j + i].setPixmap( QPixmap(self.pixmaps[self.mpickups[ i + self.scrollX.value()][j + self.scrollY.value()]])) self.traps[19 * j + i].setPixmap( QPixmap(self.pixmaps[self.mtraps[i + self.scrollX.value()][ j + self.scrollY.value()]])) pom = self.menemies[i + self.scrollX.value()][ j + self.scrollY.value()] / 100 self.enemies[19 * j + i].setPixmap( QPixmap(self.pixmaps[int(pom)]).scaled( 32, 32, Qt.KeepAspectRatio)) if self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()] > 0: self.enemies[19 * j + i].setPixmap( QPixmap(self.pixmaps[self.playerPos[ i + self.scrollX.value()][j + self.scrollY.value()]])) def mouseMoveEvent(self, event): self.addItem(event) def save(self): if self.mapInfo[2] == 0 and self.mapInfo[3] == 0: msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Information") msg.setText("Set portal(end of the map)!") msg.show() elif self.playerInfo[3] == 0: msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Information") msg.setText("Set spawnpoint!") msg.show() else: path = QInputDialog.getText(self, "Save map", "Please input map name:") if path[1]: if not os.path.exists("./levels/" + path[0]): os.makedirs("./levels/" + path[0]) text = " ".join(str(x) for x in self.mtiles) text = text.translate({ord('['): ''}) text = text.translate({ord(']'): ''}) text = re.sub('0', '00', text).strip() text = re.sub('1', '01', text).strip() text = re.sub('2', '02', text).strip() text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace("\n", "") self.saveFile("./levels/" + path[0] + "/map.map", text) text = " ".join(str(x) for x in self.mtilesHp) text = text.translate({ord('['): ''}) text = text.translate({ord(']'): ''}) text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace("\n", "") self.saveFile("./levels/" + path[0] + "/map.hp", text) text = " ".join(str(x) for x in self.mtraps) text = text.translate({ord('['): ''}) text = text.translate({ord(']'): ''}) text = re.sub('10', '1', text).strip() text = re.sub('11', '2', text).strip() text = re.sub('12', '3', text).strip() text = re.sub('13', '4', text).strip() text = re.sub('14', '5', text).strip() text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace("\n", "") self.saveFile("./levels/" + path[0] + "/map.trap", text) text = " ".join(str(x) for x in self.mpickups) text = text.translate({ord('['): ''}) text = text.translate({ord(']'): ''}) text = re.sub('7', '1', text).strip() text = re.sub('6', '2', text).strip() text = re.sub('3', '7', text).strip() text = re.sub('5', '3', text).strip() text = re.sub('7', '5', text).strip() text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace("\n", "") self.saveFile("./levels/" + path[0] + "/map.pck", text) text = " ".join(str(x) for x in self.menemies) #text = re.sub('0', '000', text).strip() text = re.sub(' ', ' ', text).strip() text = re.sub(' ', ' ', text).strip() text = text.translate({ord('['): ''}) text = text.translate({ord(']'): ''}) text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace("\n", "") self.saveFile("./levels/" + path[0] + "/map.enm", text) text = " ".join(str(x) for x in self.playerInfo) text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace("\n", "") self.saveFile("./levels/" + path[0] + "/player.info", text) text = " ".join(str(x) for x in self.mapInfo) text = text.translate({ord('['): ''}) text = text.translate({ord(']'): ''}) text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace(" ", " ") text = text.replace("\n", "") self.saveFile("./levels/" + path[0] + "/map.info", text) msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Information") msg.setText("Map created successfully!") msg.show() else: msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Information") msg.setText("A map with this name exists!") msg.show() def saveFile(self, fileName, text): f = open(fileName, "a") f.write(text) def mousePressEvent(self, event): if event.button() == 1: self.button = 1 else: self.button = 0 self.addItem(event) def addItem(self, event): for i in range(19): for j in range(10): if (i + 1) * 32 + 30 >= event.x() >= i * 32 + 30 and ( j + 1) * 32 + 20 >= event.y() >= j * 32 + 20: if (self.button): if 3 > self.actualTexture > 0: self.mtiles[i + self.scrollX.value()][ j + self.scrollY.value()] = self.actualTexture if self.actualTexture == 2: pom = self.hpEditor.value() / 100.0 self.mtilesHp[i + self.scrollX.value()][ j + self.scrollY.value()] = int(pom) if 8 > self.actualTexture > 2: self.mpickups[i + self.scrollX.value()][ j + self.scrollY.value()] = self.actualTexture if 10 > self.actualTexture > 7: self.menemies[i + self.scrollX.value( )][j + self.scrollY.value( )] = 100 * self.actualTexture + self.hpEditor.value( ) / 10 + self.armorEditor.value() / 100 if self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()] != 0: self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 self.playerInfo = numpy.zeros(6, dtype=int) if 15 > self.actualTexture > 9: self.mtraps[i + self.scrollX.value()][ j + self.scrollY.value()] = self.actualTexture if self.actualTexture == 15: self.playerPos[self.playerInfo[0]][ self.playerInfo[1]] = 0 self.playerInfo[0] = i + self.scrollX.value() self.playerInfo[1] = j + self.scrollY.value() self.playerInfo[2] = self.hpEditor.value() / 100 self.playerInfo[3] = self.mhpe.value() / 100 self.playerInfo[4] = self.armorEditor.value() / 100 self.playerInfo[5] = self.mare.value() / 100 self.playerPos[self.playerInfo[0]][ self.playerInfo[1]] = 0 self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()] = self.actualTexture self.menemies[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 self.prepareMap() if self.actualTexture == 16: self.playerPos[self.mapInfo[2]][ self.mapInfo[3]] = 0 self.mapInfo[2] = i + self.scrollX.value() self.mapInfo[3] = j + self.scrollY.value() self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()] = self.actualTexture self.menemies[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 self.prepareMap() if self.actualTexture == 0: if (self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()]) != 0: text = "HP: " + str( self.playerInfo[2] * 100) + " Max HP: " + str( self.playerInfo[3] * 100) + "\nArmor: " + str( self.playerInfo[4] * 100) + " Max Armor: " + str( self.playerInfo[5] * 100) self.infoLabel.setText(text) if (self.mtilesHp[i + self.scrollX.value()][ j + self.scrollY.value()]) != 0: text = "HP: " + str( self.mtilesHp[i + self.scrollX.value()][ j + self.scrollY.value()] * 100) self.infoLabel.setText(text) if (self.menemies[i + self.scrollX.value()][ j + self.scrollY.value()]) != 0: pom = str( self.menemies[i + self.scrollX.value()][ j + self.scrollY.value()]) text = "HP: " + str( int(pom[1]) * 100) + "\nArmor: " + str( int(pom[2]) * 100) self.infoLabel.setText(text) else: self.mtiles[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 self.mpickups[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 self.mtraps[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 self.menemies[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 if self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()] != 0: self.playerPos[i + self.scrollX.value()][ j + self.scrollY.value()] = 0 self.playerInfo = numpy.zeros(6, dtype=int) self.prepareMap() self.update() def checkInfo(self): self.makeMenu(0)
class GraphViewer(QWidget): def __init__(self, parent): super().__init__(parent) self._y = 0 self._width = 1 self._height = 1 self.dot = Digraph(format='svg', strict=True) self._declared_count = 1 self._declared = dict() self._renderer = QSvgRenderer(self.dot.pipe(), self) self.scrollbar = QScrollBar(self.parent()) self.scrollbar.setRange(0, 0) self.parent().wheelEvent = self.wheelEvent def wheelEvent(self, event): if event.x() > self.getScrollWidth(): return if event.y() > self._height: return self.scrollbar.wheelEvent(event) def add(self, data): # is variable if data in self._declared.keys(): return self._declared[data] if data.is_variable: name = data.name self._declared[data] = name self.dot.node(name) if data.toward is not None: toward = self.add(data.toward) self.dot.edge(toward, name) return name # is constant if data.is_constant: name = data.symbol self._declared[data] = name self.dot.node(name) return name # is operator if data.is_operator: name = '[%d] %s' % (self._declared_count, data.name) self._declared_count += 1 self._declared[data] = name self.dot.node(name) args = [data.sub, data.obj, data.step] if data.args is not None: args += data.args args = [arg for arg in args if arg is not None] for arg in args: arg = self.add(arg) self.dot.edge(arg, name) return name def paintEvent(self, event): self._width = self.width() self._height = self.height() self.scrollbar.setGeometry(self.getScrollWidth(), 0, 20, self._height) self.resize(self._renderer.defaultSize()) painter = QPainter(self) painter.restore() drawRect = QRectF(self.rect()) if self.scrollbar.maximum() == 0: draw_y = 0 else: draw_y = drawRect.height() - self._height draw_y *= self.scrollbar.value() / self.scrollbar.maximum() drawRect.setY(-draw_y) drawRect.setHeight(drawRect.y() + drawRect.height()) self._renderer.render(painter, drawRect) def flush(self): self._renderer = QSvgRenderer(self.dot.pipe()) max_h = self._renderer.defaultSize().height() / self._height if max_h <= 1: max_h = 0 max_h = int(self.delta() * max_h) self.scrollbar.setMaximum(max_h) def clear(self): self._declared_count = 1 self._declared = dict() self.dot.clear() def getScrollWidth(self): return self._width - 20 def delta(self): return 3.14
class MyCodeEditor(QWidget): def __init__(self,parent=None): QWidget.__init__(self,parent) self.__editorSettings = EditorSettings() self.__textDocument = PythonTextDocument() self.__splitter = QSplitter(self) # 横纵滚动条 self.__verticalScrollBar = QScrollBar(self) self.__verticalScrollBar.adjustSize() self.__verticalScrollBar.setMinimumWidth(self.__verticalScrollBar.width()) self.__verticalScrollBar.setMaximumWidth(self.__verticalScrollBar.width()) self.__verticalScrollBar.valueChanged.connect(self.__onVScrollValueChanged) self.__editorSettings.startDisLineNumberChangedSignal.connect(self.__verticalScrollBar.setValue) self.__horizontalScrollBar = QScrollBar(QtCore.Qt.Horizontal,self) self.__horizontalScrollBar.adjustSize() self.__horizontalScrollBar.setMinimumHeight(self.__horizontalScrollBar.height()) self.__horizontalScrollBar.setMaximumHeight(self.__horizontalScrollBar.height()) self.__horizontalScrollBar.valueChanged.connect(self.__onHScrollValueChanged) self.__editorSettings.startDisLetterXOffChangedSignal.connect(self.__horizontalScrollBar.setValue) self.__lineNumberWidget = LineNumberWidget(self.__editorSettings,self.__splitter) setattr(self.__lineNumberWidget,'resizeEvent',self.__onLineNumberWidgetSizeChanged) self.__codeTextWidget = CodeTextWidget(self.__textDocument,self.__editorSettings,self.__splitter) self.__codeTextWidget.document().totalLevelTextChangedSignal.connect(self.__onCodeTextChanged) self.__codeTextWidget.settings().lineTextMaxPixelChangedSignal.connect(self.__onLineStrLengthChanged) self.__codeTextWidget.visibleLineYOffInfoChangedSignal.connect( self.__lineNumberWidget.setVisibleLineYOffInfoArray ) self.__splitter.addWidget( self.__lineNumberWidget ) self.__splitter.addWidget( self.__codeTextWidget ) self.__splitter.setCollapsible( 0,False ) self.__splitter.setCollapsible( 1,False ) self.setText = self.__codeTextWidget.setText self.getText = self.__codeTextWidget.getText def __onLineStrLengthChanged(self,newMaxLength): hMax = newMaxLength-1 self.__horizontalScrollBar.setRange(0,hMax) if self.__horizontalScrollBar.value() > hMax: self.__horizontalScrollBar.setValue(hMax) def __onCodeTextChanged(self,*arg1,**arg2): vMax = self.__codeTextWidget.document().getLineCount()-1 self.__verticalScrollBar.setRange(0,vMax) if self.__verticalScrollBar.value() > vMax: self.__verticalScrollBar.setValue(vMax) def __onVScrollValueChanged(self): self.__codeTextWidget.showLineNumberAsTop(self.__verticalScrollBar.value()) def __onHScrollValueChanged(self): self.__codeTextWidget.showLeftXOffAsLeft(self.__horizontalScrollBar.value()) def __onLineNumberWidgetSizeChanged(self,*arg1,**arg2): lineNumberWidgetWidth = self.__lineNumberWidget.width() vScrollBarWidth = self.__verticalScrollBar.width() hScrollBarHeight = self.__horizontalScrollBar.height() self.__horizontalScrollBar.setGeometry(lineNumberWidgetWidth,self.height()-hScrollBarHeight, \ self.width()-vScrollBarWidth-lineNumberWidgetWidth,hScrollBarHeight) def resizeEvent(self, event): vScrollBarWidth = self.__verticalScrollBar.width() hScrollBarHeight = self.__horizontalScrollBar.height() self.__splitter.setGeometry( 0,0,self.width()-vScrollBarWidth,self.height()-hScrollBarHeight ) self.__verticalScrollBar.setGeometry(self.width()-vScrollBarWidth,0,vScrollBarWidth,self.height()-hScrollBarHeight) self.__onLineNumberWidgetSizeChanged() def wheelEvent(self, event): changedV = 3 if event.angleDelta().y() < 0 else -3 self.__verticalScrollBar.setValue( self.__verticalScrollBar.value() + changedV )