4

我想让 UI 基本上是一个图像,用户可以通过线连接的点来追踪路径。我希望它是跨平台的,所以我正在考虑尝试 enaml。我不确定如何做到这一点。

我浏览了文档和示例,但找不到像画布小部件这样的东西。是否可以使用搪瓷在表面上进行任意绘图(点、线等)?

4

1 回答 1

3

enaml 没有画布小部件,但您可以使用RawWidget以及自定义 QWidget 和 QPainter 来绘制您需要的任何内容。

from atom.api import Typed, Event
from enaml.widgets.api import Window, Container, RawWidget
from enaml.core.declarative import d_
from enaml.qt.QtCore import Qt
from enaml.qt.QtGui import QPainter, QPainterPath, QMouseEvent
from enaml.qt.QtWidgets import QWidget


class QtPaintWidget(QWidget):
    """ A widget that delegates drawing to enaml """
    def __init__(self, parent, widget):
        super(QtPaintWidget, self).__init__(parent)
        self.widget = widget

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        # Trigger the 'paint' event on th PaintWidget
        self.widget.paint(qp)
        qp.end()

    def mouseReleaseEvent(self, e):
        super(QtPaintWidget, self).mouseReleaseEvent(e)
        self.widget.mouse_event(e)


class PaintWidget(RawWidget):

    #: Push the paint event up to enaml
    paint = d_(Event(QPainter))

    #: Handle mouse event in enaml
    mouse_event = d_(Event(QMouseEvent))

    def create_widget(self, parent):
        return QtPaintWidget(parent, self)

    def update(self):
        self.proxy.widget.update()


enamldef Main(Window):
    Container:
        padding = 0
        PaintWidget: canvas:
            attr points = []
            minimum_size = (500, 500)
            paint ::
                # See https://doc.qt.io/qt-5/qpainter.html
                # for how to use the QPainter
                qp = change['value']
                qp.setBrush(Qt.white)
                qp.drawRect(0, 0, 500,  500)
                qp.setBrush(Qt.NoBrush)
                qp.setPen(Qt.blue)
                for p in points:
                    qp.drawPoint(p)
                qp.setPen(Qt.red)
                path = QPainterPath()
                if len(points) > 1:
                    for i, p in enumerate(points):
                        if i==0:
                            path.moveTo(p)
                        else:
                            path.lineTo(p)
                qp.drawPath(path)
            mouse_event ::
                # Save the position
                e = change['value']
                print(e)
                if e.button() == Qt.RightButton:
                    del points[:]
                else:
                    points.append(e.pos())
                canvas.update()

和瓦拉

绘画

您不必将绘制事件推送到 enaml,它只是使与其他小部件的交互更容易。有关在 Qt 中绘图的更多信息,请参阅QtPainter 文档http://zetcode.com/gui/pyqt5/painting/

于 2018-05-17T00:21:19.253 回答