Hi all, I’m playing with AkiR’s code now, which is very helpful.
The code works well using Scripter, but when I make it into an extension, it fails to work. It’s a straightforward combination of AkiR’s code and the extension example given in Krita’s Manual.
When I load the plugin and click the menu tools->My Plugin, I see that eventFilter function is executed only once and draw_sierpinski is not called at all. So what’s wrong??
from krita import Krita, Extension
from PyQt5.QtCore import (
Qt,
QEvent,
QPointF,
QRect)
from PyQt5.QtGui import (
QTransform,
QPainter,
QBrush,
QColor,
QPolygonF,
QInputEvent)
from PyQt5.QtWidgets import (
QMenu,
QAction,
QWidget,
QMdiArea,
QAbstractScrollArea)
def get_q_view(view):
window = view.window()
q_window = window.qwindow()
q_stacked_widget = q_window.centralWidget()
q_mdi_area = q_stacked_widget.findChild(QMdiArea)
for v, q_mdi_view in zip(window.views(), q_mdi_area.subWindowList()):
if v == view:
return q_mdi_view.widget()
def get_transform(view):
def _offset(scroller):
mid = (scroller.minimum() + scroller.maximum()) / 2.0
return -(scroller.value() - mid)
canvas = view.canvas()
document = view.document()
q_view = get_q_view(view)
area = q_view.findChild(QAbstractScrollArea)
zoom = (canvas.zoomLevel() * 72.0) / document.resolution()
transform = QTransform()
transform.translate(
_offset(area.horizontalScrollBar()),
_offset(area.verticalScrollBar()))
transform.rotate(canvas.rotation())
transform.scale(zoom, zoom)
return transform
class MyOverlay(QWidget):
_degree = 6
_colors = [
QBrush(QColor(0, 0, 255)),
QBrush(QColor(0, 255, 0)),
QBrush(QColor(255, 0, 0)),
QBrush(QColor(255, 0, 255)),
QBrush(QColor(0, 255, 255)),
QBrush(QColor(255, 255, 0))]
def __init__(self, view):
print("init")
parent = get_q_view(view)
super().__init__(parent)
# ToDo: is there better way to ignore events?
self.setAttribute(Qt.WA_TransparentForMouseEvents)
self.setFocusPolicy(Qt.NoFocus)
self._view = view
q_canvas = parent.findChild(QAbstractScrollArea).viewport()
size = q_canvas.size()
self.setGeometry(QRect(0, 0, size.width(), size.height()))
parent.installEventFilter(self)
def paintEvent(self, e):
print("paintEvent")
document = self._view.document()
width = float(document.width())
height = float(document.height())
half_width = 0.5 * width
half_height = 0.5 * height
triangle = (
QPointF(-half_width, half_height),
QPointF(0.0, -half_height),
QPointF(half_width, half_height))
# Turtles all the way down
painter = QPainter(self)
try:
painter.setRenderHint(QPainter.Antialiasing, True)
painter.translate(self.rect().center())
painter.setTransform(get_transform(self._view), combine=True)
painter.setPen(Qt.NoPen)
self.draw_sierpinski(painter, triangle, self._degree)
finally:
painter.end()
def draw_sierpinski(self, painter, triangle, degree):
print("Sierpinski")
painter.setBrush(self._colors[degree % len(self._colors)])
polygon = QPolygonF()
polygon.append(triangle[0])
polygon.append(triangle[1])
polygon.append(triangle[2])
painter.drawConvexPolygon(polygon)
if degree > 0:
next_degree = degree - 1
mid_1 = 0.5 * (triangle[0] + triangle[1])
mid_2 = 0.5 * (triangle[0] + triangle[2])
mid_3 = 0.5 * (triangle[1] + triangle[2])
self.draw_sierpinski(painter, (triangle[0], mid_1, mid_2), next_degree)
self.draw_sierpinski(painter, (triangle[1], mid_1, mid_3), next_degree)
self.draw_sierpinski(painter, (triangle[2], mid_3, mid_2), next_degree)
def eventFilter(self, obj, e):
print("eventFilter")
if e.type() == QEvent.Resize:
q_canvas = self.parent().findChild(QAbstractScrollArea).viewport()
size = q_canvas.size()
self.setGeometry(QRect(0, 0, size.width(), size.height()))
return super().eventFilter(obj, e)
def drawAction():
print("drawAction")
active_window = Application.activeWindow()
active_view = active_window.activeView()
if active_view.document() is None:
raise RuntimeError('Document of active view is None!')
my_overlay = MyOverlay(active_view)
my_overlay.show()
class MyExtension(Extension):
def __init__(self, parent):
super().__init__(parent)
def setup(self):
pass
def createActions(self, window):
action = window.createAction("myplugin", i18n("My Plugin"), "tools")
action.triggered.connect(drawAction)
Krita.instance().addExtension(MyExtension(Krita.instance()))