Проблемы PyQt4 / QProcess с Nuke v9 ...
Я пытаюсь использовать QProcess для запуска рендеров в Nuke на моем рабочем месте. Причина, по которой я хочу использовать QProcess, заключается в том, что я настроил этот диспетчер задач с помощью сообщества в stackoverflow, которое принимает список команд и последовательно запускает его одну за другой, а также позволяет отображать вывод. Вы можете просмотреть вопрос, который я разместил здесь:
Как обновить пользовательский интерфейс с выводом из цикла QProcess без зависания пользовательского интерфейса?
Теперь я пытаюсь в основном запустить рендеринг Nukeчерез этот «Диспетчер задач». Но каждый раз, когда я делаю это, просто выдает ошибку, что QProcess уничтожается во время работы. Я имею в виду, я проверил это с подпроцессом, и это работало совершенно нормально. Поэтому я не уверен, почему рендеры не работают через QProcess.
Поэтому, чтобы провести дополнительное тестирование, я просто написал упрощенную версию дома. Первая проблема, с которой я столкнулся, заключается в том, что PyQt4, по-видимому, нельзя найти в python.exe Nuke. Хотя у меня есть PyQt4 для моей основной версии Python. Однако очевидно, что есть проблема совместимости с моим установленным PyQt4, так как моя основная версия Python - 2.7.12, а версия моего Nuke для Python - 2.7.3. Поэтому я подумал: «Хорошо, тогда я просто установлю PyQt4 внутри моей директории Nuke». Поэтому я взял эту ссылку и установил эту версию PyQt в свой каталог Nuke:
http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.10.3/PyQt4-4.10.3-gpl-Py2.7-Qt4.8.5-x64.exe
Итак, я запускаю свой маленький тест и, похоже, делаю то же самое, что и на своем рабочем месте. где QProcess просто уничтожается. Поэтому я подумал, что, возможно, добавление «waitForFinished ()» может сделать что-то другое, но тогда он выдаст мне эту ошибку, которая гласит:
The procedure entry point ??4QString@@QEAAAEAV0@$$QEAV0@@Z could not be located in the dynamic link library QtCore4.dll
И также выдаст мне эту ошибку:
ImportError: Не удалось загрузить C: \ Program Files \ Nuke9.0v8 \ nuke-9.0.8.dll
Сейчас я не могу больше проводить тестирование дома, и моя студия закрыта дляканикулы. Итак, у меня есть два вопроса, которые я хотел бы задать:
1) Что это за ошибка, которую я вижу о «точке входа в процедуру»? Это происходит только тогда, когда я пытаюсь вызвать что-то в экземпляре QProcess.
2) Почему мой QProcess уничтожается до завершения рендеринга? Почему это не происходит с подпроцессом? Как я могу отправить задание Nuke, получая те же результаты, что и подпроцесс?
Вот мой тестовый код:
import os
import sys
import subprocess
import PyQt4
from PyQt4 import QtCore
class Task:
def __init__(self, program, args=None):
self._program = program
self._args = args or []
@property
def program(self):
return self._program
@property
def args(self):
return self._args
class SequentialManager(QtCore.QObject):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
progressChanged = QtCore.pyqtSignal(int)
dataChanged = QtCore.pyqtSignal(str)
#^ this is how we can send a signal and can declare what type
# of information we want to pass with this signal
def __init__(self, parent=None):
# super(SequentialManager, self).__init__(parent)
# QtCore.QObject.__init__(self,parent)
QtCore.QObject.__init__(self)
self._progress = 0
self._tasks = []
self._process = QtCore.QProcess(self)
self._process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
self._process.finished.connect(self._on_finished)
self._process.readyReadStandardOutput.connect(self._on_readyReadStandardOutput)
def execute(self, tasks):
self._tasks = iter(tasks)
#this 'iter()' method creates an iterator object
self.started.emit()
self._progress = 0
self.progressChanged.emit(self._progress)
self._execute_next()
def _execute_next(self):
try:
task = next(self._tasks)
except StopIteration:
return False
else:
print 'starting %s' % task.args
self._process.start(task.program, task.args)
return True
def _on_finished(self):
self._process_task()
if not self._execute_next():
self.finished.emit()
def _on_readyReadStandardOutput(self):
output = self._process.readAllStandardOutput()
result = output.data().decode()
self.dataChanged.emit(result)
def _process_task(self):
self._progress += 1
self.progressChanged.emit(self._progress)
class outputLog(QtCore.QObject):
def __init__(self, parent=None, parentWindow=None):
QtCore.QObject.__init__(self)
self._manager = SequentialManager(self)
def startProcess(self, tasks):
# self._manager.progressChanged.connect(self._progressbar.setValue)
self._manager.dataChanged.connect(self.on_dataChanged)
self._manager.started.connect(self.on_started)
self._manager.finished.connect(self.on_finished)
self._manager.execute(tasks)
@QtCore.pyqtSlot()
def on_started(self):
print 'process started'
@QtCore.pyqtSlot()
def on_finished(self):
print 'finished'
@QtCore.pyqtSlot(str)
def on_dataChanged(self, message):
if message:
print message
def nukeTestRender():
import nuke
nuke.scriptOpen('D:/PC6/Documents/nukeTestRender/nukeTestRender.nk')
writeNode = None
for node in nuke.allNodes():
if node.Class() == 'Write':
writeNode = node
framesList = [1, 20, 30, 40]
fr = nuke.FrameRanges(framesList)
# nuke.execute(writeNode, fr)
for x in range(20):
print 'random'
def run():
nukePythonEXE = 'C:/Program Files/Nuke9.0v8/python.exe'
thisFile = os.path.dirname(os.path.abspath("__file__"))
print thisFile
cmd = '"%s" %s renderCheck' %(nukePythonEXE, __file__)
cmd2 = [__file__, 'renderCheck']
cmdList = [Task(nukePythonEXE, cmd2)]
# subprocess.call(cmd, stdin=None, stdout=None, stderr=None, shell=False)
taskManager = outputLog()
taskManager.startProcess(cmdList)
taskManager._manager._process.waitForFinished()
if __name__ == "__main__":
print sys.argv
if len(sys.argv) == 1:
run()
elif len(sys.argv) == 2:
nukeTestRender()