Найти - Пользователи
Полная версия: Blender, Python, PyQt4: нужен анализ профессионала
Начало » Центр помощи » Blender, Python, PyQt4: нужен анализ профессионала
1
leonid_10
Здравствуйте!
Занимаясь привязкой pyQt4 к Блендеру набрёл на какое-то непреодолимое препятствие.
Изначально, есть пример анимации картинки в pyQt4
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import time
from PIL import Image, ImageEnhance, ImageQt
class TestWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.button = QPushButton("Do test")
        layout = QVBoxLayout()
        layout.addWidget(self.button)
        layout.addWidget(self.view)
        self.setLayout(layout)
        self.button.clicked.connect(self.do_test)
    def do_test(self):
        img = Image.open("/home/leonid/blender/textures/green_gradient_rotate.png")
        enhancer = ImageEnhance.Brightness(img)
        for i in range(1, 8):
            img = enhancer.enhance(i)
            self.display_image(img)
            QCoreApplication.processEvents()  # let Qt do his work
            time.sleep(0.5)
    def display_image(self, img):
        self.scene.clear()
        w, h = img.size
        self.imgQ = ImageQt.ImageQt(img)  # we need to hold reference to imgQ, or it will crash
        pixMap = QPixmap.fromImage(self.imgQ)
        self.scene.addPixmap(pixMap)
        self.view.fitInView(QRectF(0, 0, w, h), Qt.KeepAspectRatio)
        self.scene.update()
if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = TestWidget()
    widget.resize(640, 480)
    widget.show()
    sys.exit(app.exec_())
Взяв за исходное пример интеграции pythonAPI Блендера с PyQT4 переношу вышеуказанный код в пример, заменив
def do_test(self) на def timerEvent(self, event). Получил работающий в Блендере код:
bl_info = {
    "name": "aoi",
    "author": "Leonid Desyatkov",
    "version": (0, 0, 1),
    "blender": (2, 73, 0),
    "location": "View3D > UI",
    "description": "GI renderer",
    "warning": "",
    "wiki_url": "",
    "category": "Render",
}
import bpy
from bpy.props import IntProperty, BoolProperty, PointerProperty
try:
    from PySide import QtCore, QtGui
    from PySide.QtGui import *
    from PySide.QtCore import * 
except ImportError:
    from PyQt4 import QtCore, QtGui
    from PyQt4.QtGui import *
    from PyQt4.QtCore import * 
from PIL import Image, ImageEnhance, ImageQt
from . import darea
class AOIRenderSettings(bpy.types.PropertyGroup):
    @classmethod
    def register(cls):
        bpy.types.Scene.aoi = PointerProperty(
                name="Aoi Render Settings",
                description="Art Of Illusion render settings",
                type=cls,
                )
    render_process = BoolProperty(
            name="Process",
            description="",
            default=False)
    timer_step = IntProperty(
            name="Step",
            description="",
            default=0)
    @classmethod
    def unregister(cls):
        del bpy.types.Scene.aoi
class AOI_Display(QWidget):
    def __init__(self, parent=None):
        super(AOI_Display, self).__init__(parent)
        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.button = QPushButton("Do test")
        self.timer = QBasicTimer()
        layout = QVBoxLayout()
        layout.addWidget(self.button)
        layout.addWidget(self.view)
        self.setLayout(layout)
        self.timer.start(1, self)
        self.pixmap = QPixmap()
        self.pixmap.load("/home/leonid/blender/textures/green_gradient_rotate.png")
        self.step = -100
        self.resize(640, 480)
        self.show()
    def timerEvent(self, event):
        img = Image.open("/home/leonid/blender/textures/green_gradient_rotate.png")
        enhancer = ImageEnhance.Brightness(img)
        for i in range(1, 8):
            img = enhancer.enhance(i)
            self.display_image(img)
            QCoreApplication.processEvents()  # let Qt do his work
    def display_image(self, img):
        self.scene.clear()
        w, h = img.size
        self.imgQ = ImageQt.ImageQt(img)  # we need to hold reference to imgQ, or it will crash
        pixMap = QPixmap.fromImage(self.imgQ)
        self.scene.addPixmap(pixMap)
        self.view.fitInView(QRectF(0, 0, w, h), Qt.KeepAspectRatio)
        self.scene.update()
    def closeEvent(self, event):
        bpy.context.scene.aoi.render_process = False
class PyQtEventLoopOp(bpy.types.Operator):
    bl_idname = "wm.aoi"
    bl_label = "AOI: image"
    _timer = None
    _window = None
    @classmethod
    def poll(cls, context):
        return bpy.context.scene.aoi.render_process == False
    def modal(self, context, event):
        if event.type == 'TIMER':
            self._event_loop.processEvents()
            self._application.sendPostedEvents(None, 0) 
        return {'PASS_THROUGH'}
    def execute(self, context):
        if bpy.context.scene.aoi.render_process == False:
            self._application = QApplication.instance()
            if self._application is None:
                self._application = QApplication(['blender'])
            self._event_loop = QtCore.QEventLoop()
            self.window = AOI_Display()
            self._timer = context.window_manager.event_timer_add(1, context.window)
            context.window_manager.modal_handler_add(self)
            bpy.context.scene.aoi.render_process = True
            return {'RUNNING_MODAL'}
        else:
            return {'CANCELLED'}
def menu_func_aoi(self, context):
    layout = self.layout
    #layout.active = bpy.context.scene.aoi.render_process == False
    layout.operator("wm.aoi")
    
def register():
    bpy.utils.register_class(AOIRenderSettings)
    bpy.utils.register_class(PyQtEventLoopOp)
    bpy.types.RENDER_PT_render.prepend(menu_func_aoi)
def unregister():
    bpy.utils.unregister_class(AOIRenderSettings)
    bpy.utils.unregister_class(PyQtEventLoopOp)
    bpy.types.RENDER_PT_render.remove(menu_func_aoi)
if __name__ == "__main__":
    register()
Теперь пытаюсь изменить условия анимации.
    def timerEvent(self, event):
        self.display_image(self.img)
        QCoreApplication.processEvents()  # let Qt do his work
        self.step+=1
    def display_image(self, img):
        if self.step>-1 and self.step<self.h:
            self.scene.clear()
            w, h = img.size
            self.imgQ = ImageQt.ImageQt(img)  # we need to hold reference to imgQ, or it will crash
            for x in range(self.imgQ.width()):
                self.imgQ.setPixel(x, 0+self.step,QColor(Qt.red).rgb())
            pixMap = QPixmap.fromImage(self.imgQ)
            self.scene.addPixmap(pixMap)
            self.view.fitInView(QRectF(0, 0, w, h), Qt.KeepAspectRatio)
            self.scene.update()
В изначальном коде это работает, в случае с Блендером нет.
На эту тему в гугле ничего нету, но, может, мои знания прихрамывают и ошибка очевидна?
leonid_10
Вопрос снят. Проблема была в оффициальной версии Блендера.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB