Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PyGobject中的绘图(python3)_Python_Python 3.x_Gtk_Cairo_Pygobject - Fatal编程技术网

PyGobject中的绘图(python3)

PyGobject中的绘图(python3),python,python-3.x,gtk,cairo,pygobject,Python,Python 3.x,Gtk,Cairo,Pygobject,我正在尝试使用PyGObject和Python3编写简单的图形编辑器。 我需要用鼠标画不同颜色和宽度的线。我发现了很多类似的例子,但没有比这更复杂的了 如何在“绘制”事件之间保存绘制的图像?是否有增量绘制方式,或者我必须在每个“绘制”事件上重新绘制窗格?我发现我可以保存路径,但如何保存绘制线的宽度和颜色?有没有办法在“draw”回调外部创建图像,而只在回调内部应用(draw)它 这就是我现在所拥有的 #!/usr/bin/env python # -*- coding: utf-8 -*- f

我正在尝试使用PyGObject和Python3编写简单的图形编辑器。 我需要用鼠标画不同颜色和宽度的线。我发现了很多类似的例子,但没有比这更复杂的了

如何在“绘制”事件之间保存绘制的图像?是否有增量绘制方式,或者我必须在每个“绘制”事件上重新绘制窗格?我发现我可以保存路径,但如何保存绘制线的宽度和颜色?有没有办法在“draw”回调外部创建图像,而只在回调内部应用(draw)它

这就是我现在所拥有的

#!/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()

对不起,我的英语不是我的母语。

您需要使用双缓冲区技术:

这就是你有一个图像,你画在这个图像上:这个图像是“幕后”缓冲区。你可以用很多方法把一些东西画到这个图像上。 然后,在响应“draw”信号的回调上,也就是说,实际将某物绘制到图形内存的方法,您只需抛出“幕后”图像

代码中的理论(test.py):

Glade文件(test.Glade):

Python 3:

sudo apt-get install python3-gi-cairo
现在执行以下操作:

python test.py

它看起来像什么:

cairo的所有文档都可以在中找到


您可以检查Qt中的scribble示例以获取逻辑。我也会这么做。在内部拥有的cairo_曲面中绘制,然后在每个绘制信号上,将缓冲区复制到小部件上下文,然后完成,
sudo apt-get install python-cairo
sudo apt-get install python3-gi-cairo
python test.py
python3 test.py