I am trying to write a simple graphical editor using PyGObject and python 3. I need to draw lines with different colors and widths using the mouse. I found many examples, such as this one , but nothing more complicated.
How to save a sketched image between 'draw' events? Is there an incremental way to draw, or do I need to redraw the panel on each 'draw' event? I found out that I can save the path, but how can I keep the width and color of the drawn lines? Is there a way to create βcallbackβ feedback and apply (invert) it inside the callback?
Here is what I have now.
#!/usr/bin/env python # -*- coding: utf-8 -*- from gi.repository import Gtk, Gdk import os class App(object): main_ui = os.path.join(os.path.dirname(__file__), 'gui.glade') def __init__(self): self.builder = Gtk.Builder() self.builder.add_from_file(self.main_ui) self.main_window.connect('destroy', self.quit) self.mw_quit_button.connect('clicked', self.quit) self.mw_graph_editor_button.connect('clicked', self.show_window, self.graph_editor_window) self.graph_editor_window.connect('delete-event', self.hide_window_delete) self.ge_menubar_file_quit.connect('activate', self.hide_window, self.graph_editor_window) self.ge_toolbar_quit.connect('clicked', self.hide_window, self.graph_editor_window) self.ge_drawingarea.connect('motion-notify-event', self.pointer_motion) self.ge_drawingarea.connect('motion-notify-event', self.show_coordinates) self.ge_drawingarea.connect('draw', self.draw_callback) self.path = None self.coord = (0, 0) self.rgb = (0, 0, 0) def __getattr__(self, name): obj = self.builder.get_object(name) if not obj: raise AttributeError("Object {0} has no attribute {1}".format(self, name)) setattr(self, name, obj) return obj def draw_callback(self, drawingarea, cr): if self.path: cr.append_path(self.path) cr.line_to(self.coord[0], self.coord[1]) cr.set_source_rgba(*self.rgb) self.path = cr.copy_path_flat() cr.stroke() def show_coordinates(self, window, event): self.ge_mouse_coordinates.set_label('X: {0:.0f} Y: {1:.0f}'.format(event.x, event.y)) def pointer_motion(self, widget, event): if event.state & Gdk.ModifierType.BUTTON1_MASK: self.draw(widget, event.x, event.y) elif event.state & Gdk.ModifierType.BUTTON3_MASK: self.draw(widget, event.x, event.y, True) def draw(self, widget, x, y, erase=False): self.coord = (x,y) if erase: self.rgb = (256, 256, 256) else: self.rgb = (0, 0, 0) widget.queue_draw() def show_window(self, widget, data): data.show_all() def hide_window_delete(self, widget, event): widget.hide() return True def hide_window(self, widget, window): window.hide() def run(self): self.main_window.show_all() Gtk.main() def quit(self, widget=None, data=None): self.main_window.destroy() Gtk.main_quit() if __name__ == "__main__": app = App() app.run()
Sorry for my English, this is not my native language.