此代码是关于效果渲染后的。我已经安装了pyqt5和python 3.4 我不是python编码的专家
"""
By:
---
Jared Glass
www.linkedin.com/in/JaredMushuGlass
Description:
------------
Render Queue/Batch Render tool for After Effects.
Automatically searches for latest versions of After Effects Projects
in a specified folder and adds to the queue. You can then choose to
remove or add other After Effects Projects. The tool will render
everything in each After Effects Project’s Render Queue using multiple
processors if available.
Requirements:
------------
This tool has been created and tested on windows but should work on Mac and Linux too.
It requires Python and PyQt be installed.
I’m using Python 2.6 and PyQt 4.9.6.
Demo Video: http://www.youtube.com/watch?v=3ktHj_PDI0M
After Effects Blog: www.codingForAfterEffects.wordpress.com
Logic:
------
1. Prompt user for root folder in which to search for all ".aep" files.
2. Get the latest versions (by highest version number) of all ".aep" files found in
the user specified root and all child directories.
3. Allow user to add or remove files from the queue.
4. Render the files in the queue in order when the render button is clicked.
4.1 Find the "aerender" executable.
4.2 Start a thread to render the aep files.
"""
#from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sip
import sys, os, subprocess
###################
#### Functions ####
###################
def aerender_path():
'''Find the aerender executable'''
aerenderPath = None
for programFolder in program_folders():
for root, dirs, files in os.walk(programFolder):
# check if "after" and "effects" are in folder path
if not "after" in root.lower() or not "effects" in root.lower():
continue
for file in files:
fileName, fileExt = os.path.splitext(file)
if fileName == "aerender":
aerenderPath = os.path.join(root, file)
break
if aerenderPath != None:
break
return aerenderPath
def program_folders():
'''Program folder(s) for this platform'''
folders = []
if sys.platform == "darwin":
folders = ["/Applications"]
elif sys.platform == "win32":
folders = [r"C:\Program Files", r"C:\Program Files (x86)"]
elif sys.platform == "linux2":
folders = ["/Applications", "/usr"]
return folders
def open_folder(path):
'''open folder for each platform'''
if sys.platform == 'darwin':
subprocess.Popen(['open', '--', path])
elif sys.platform == 'linux2':
subprocess.Popen(['gnome-open', '--', path])
elif sys.platform == 'win32':
subprocess.Popen(['explorer', path])
def get_aep_files(searchFolder):
'''Find all latest .aep files in the "searchFolder"'''
aepDict = {}
for root, dirs, files in os.walk(searchFolder):
for file in files:
fileName, fileExt = os.path.splitext(file)
if fileExt != ".aep":
continue
# Reverse string to get rid of version numbers
fileName = os.path.splitext(file)[0]
reversed = fileName[::-1]
splitIndex = False
for index in range(len(reversed)):
char = reversed[index]
try:
int(char)
except ValueError:
splitIndex = index
break
version = 0
name = fileName
if splitIndex:
name = reversed[splitIndex:][::-1]
version = int(reversed[:splitIndex][::-1])
# remove whitespace from end of name
name = name.rstrip()
# If an aep file with the same name is already stored, check for the latest version
if name in aepDict.keys():
aepData = aepDict[name]
aepPath = aepData[0]
aepVersion = aepData[1]
if aepVersion > version:
continue
path = os.path.join(root, file)
aepDict[name] = [path, version]
aepFiles = [ aepDict[key][0] for key in aepDict.keys() ]
aepFiles.sort()
return aepFiles
#################
#### Classes ####
#################
class RenderThread(QThread):
'''Thread to handle the aerender executable so the main GUI
stays responsive while render processing takes place'''
def __init__(self, parent, aerenderPath, aepList):
QThread.__init__(self, parent)
self.aerenderPath = aerenderPath
self.aepList = aepList
def run(self):
while len(self.aepList) > 0:
aepPath = self.aepList.pop(0)
self.emit(SIGNAL("STARTED"), aepPath)
procStr = '"' + self.aerenderPath + '"'
procStr += ' -project "' + aepPath + '"'
procStr += ' -mp '
procStr += ' -close DO_NOT_SAVE_CHANGES'
proc = subprocess.Popen(procStr)
proc.wait()
self.emit(SIGNAL("FINISHED"), aepPath)
class RenderDialog(QDialog):
'''Main GUI'''
def __init__(self):
QDialog.__init__(self)
# Widgets
queueGroup = QGroupBox("Queue")
self.queueList = QListWidget()
removeBtn = QPushButton("Remove")
addBtn = QPushButton("Add")
self.renderBtn = QPushButton("Render")
self.proBar = QProgressBar()
doneGroup = QGroupBox("Done")
self.doneList = QListWidget()
# Layout
layout = QGridLayout(queueGroup)
layout.addWidget(self.queueList, 0, 0, 1, 2)
layout.addWidget(removeBtn, 1, 0)
layout.addWidget(addBtn, 1, 1)
layout = QVBoxLayout(doneGroup)
layout.addWidget(self.doneList)
layout = QVBoxLayout(self)
layout.addWidget(queueGroup)
layout.addWidget(self.renderBtn)
layout.addWidget(self.proBar)
layout.addWidget(doneGroup)
# Connections
removeBtn.clicked.connect(self.remove_queue)
addBtn.clicked.connect(self.add_queue)
self.queueList.itemDoubleClicked[QListWidgetItem].connect(self.open_item_folder)
self.doneList.itemDoubleClicked[QListWidgetItem].connect(self.open_item_folder)
self.renderBtn.clicked.connect(self.render)
# Settings
self.setWindowTitle("AE Render Queue")
self.queueList.setSelectionMode(QAbstractItemView.MultiSelection)
self.doneList.setSelectionMode(QAbstractItemView.NoSelection)
# Run
searchFolder = str(QFileDialog.getExistingDirectory(self, "Select folder to search for all After Effects Projects in"))
aepFiles = get_aep_files(searchFolder)
self.queueList.addItems(aepFiles)
self.proBar.hide()
## Defs ##
def render(self):
self.renderBtn.hide()
self.proBar.show()
self.proBar.setMaximum(self.queueList.count() + 1)
self.proBar.setFormat("Locating aerender")
self.proBar.setValue(0)
aerenderPath = aerender_path()
if aerenderPath == None:
QMessageBox.critical(self, "ERROR", "Cannot locate the \"aerender\" file in the default install directory for your platform. \nPlease re-install After Effects to the default location or \nmodify this scripts \"program_folders\" function." )
self.close()
aepList = [ str(self.queueList.item(index).text()) for index in range(self.queueList.count()) ]
renderThread = RenderThread(self, aerenderPath, aepList)
renderThread.start()
renderThread.started.connect(self.single_render_started)
renderThread.finished.connect(self.single_render_finished)
def single_render_started(self, aepPath):
'''Increment progress when a new render is started.'''
self.proBar.setFormat(os.path.basename(aepPath))
self.proBar.setValue(self.proBar.value() + 1)
def single_render_finished(self, aepPath):
'''Move the aep file path from the render queue to the done
queue once completed.
Also if there are no more items to render, reset the GUI'''
item = self.queueList.takeItem(0)
self.doneList.insertItem(0, item)
if not self.queueList.count() > 0:
self.renderBtn.show()
self.proBar.hide()
def remove_queue(self):
'''Remove selected items from the queue'''
rows = []
for item in self.queueList.selectedItems():
rows.append(self.queueList.row(item))
rows.sort(reverse=True)
for row in rows:
item = self.queueList.takeItem(row)
sip.delete(item)
def add_queue(self):
'''Add specified items to the queue'''
files = QFileDialog.getOpenFileNames(self, "Select .aep files to add to the render queue", filter = "After Effects Projects (*.aep)")
files.sort()
self.queueList.addItems(files)
def open_item_folder(self, item):
'''Open the folder of the specified aep file'''
folder = os.path.dirname(str(item.text()))
open_folder(folder)
##############
#### Main ####
##############
if __name__ == "__main__":
app = QApplication(sys.argv)
renDlg= RenderDialog()
renDlg.show()
sys.exit(app.exec_())
运行时出现以下错误。
Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:25:23) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Traceback (most recent call last):
File "C:\Users\PrashSal\Downloads\AERenderQueue.py", line 256, in add_queue
files.sort()
AttributeError: 'tuple' object has no attribute 'sort'
Traceback (most recent call last):
File "C:\Users\PrashSal\Downloads\AERenderQueue.py", line 149, in run
self.emit(SIGNAL("STARTED"), aepPath)
TypeErrorAttributeError: : single_render_started() missing 1 required positional argument: 'aepPath''RenderThread' object has no attribute 'emit'
TypeError: single_render_finished() missing 1 required positional argument: 'aepPath'
请用外行的语言回答,因为我不太了解很多python术语。 如果可能,请直接提供修改后的代码。
谢谢和问候。 我获得此代码的网站链接是https://www.highend3d.com/downloads/applications/render-managers/c/after-effects-render-queue
答案 0 :(得分:1)
出现问题的原因是你在插槽和信号之间使用旧式连接,你的代码清楚地说你应该使用PyQt 4.9.6,在进行到PyQt5的迁移时你会得到类似的错误。在您的情况下,您必须进行以下修改:
class RenderThread(QThread):
started = pyqtSignal(str)
finished = pyqtSignal(str)
'''Thread to handle the aerender executable so the main GUI
stays responsive while render processing takes place'''
def __init__(self, parent, aerenderPath, aepList):
QThread.__init__(self, parent)
self.aerenderPath = aerenderPath
self.aepList = aepList
def run(self):
while len(self.aepList) > 0:
aepPath = self.aepList.pop(0)
self.started.emit(aepPath)
procStr = '"' + self.aerenderPath + '"'
procStr += ' -project "' + aepPath + '"'
procStr += ' -mp '
procStr += ' -close DO_NOT_SAVE_CHANGES'
proc = subprocess.Popen(procStr)
proc.wait()
self.finished.emit(aepPath)
完整代码:
"""
By:
---
Jared Glass
www.linkedin.com/in/JaredMushuGlass
Description:
------------
Render Queue/Batch Render tool for After Effects.
Automatically searches for latest versions of After Effects Projects
in a specified folder and adds to the queue. You can then choose to
remove or add other After Effects Projects. The tool will render
everything in each After Effects Project’s Render Queue using multiple
processors if available.
Requirements:
------------
This tool has been created and tested on windows but should work on Mac and Linux too.
It requires Python and PyQt be installed.
I’m using Python 2.6 and PyQt 4.9.6.
Demo Video: http://www.youtube.com/watch?v=3ktHj_PDI0M
After Effects Blog: www.codingForAfterEffects.wordpress.com
Logic:
------
1. Prompt user for root folder in which to search for all ".aep" files.
2. Get the latest versions (by highest version number) of all ".aep" files found in
the user specified root and all child directories.
3. Allow user to add or remove files from the queue.
4. Render the files in the queue in order when the render button is clicked.
4.1 Find the "aerender" executable.
4.2 Start a thread to render the aep files.
"""
#from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sip
import sys, os, subprocess
###################
#### Functions ####
###################
def aerender_path():
'''Find the aerender executable'''
aerenderPath = None
for programFolder in program_folders():
for root, dirs, files in os.walk(programFolder):
# check if "after" and "effects" are in folder path
if not "after" in root.lower() or not "effects" in root.lower():
continue
for file in files:
fileName, fileExt = os.path.splitext(file)
if fileName == "aerender":
aerenderPath = os.path.join(root, file)
break
if aerenderPath != None:
break
return aerenderPath
def program_folders():
'''Program folder(s) for this platform'''
folders = []
if sys.platform == "darwin":
folders = ["/Applications"]
elif sys.platform == "win32":
folders = [r"C:\Program Files", r"C:\Program Files (x86)"]
elif sys.platform == "linux2":
folders = ["/Applications", "/usr"]
return folders
def open_folder(path):
'''open folder for each platform'''
if sys.platform == 'darwin':
subprocess.Popen(['open', '--', path])
elif sys.platform == 'linux2':
subprocess.Popen(['gnome-open', '--', path])
elif sys.platform == 'win32':
subprocess.Popen(['explorer', path])
def get_aep_files(searchFolder):
'''Find all latest .aep files in the "searchFolder"'''
aepDict = {}
for root, dirs, files in os.walk(searchFolder):
for file in files:
fileName, fileExt = os.path.splitext(file)
if fileExt != ".aep":
continue
# Reverse string to get rid of version numbers
fileName = os.path.splitext(file)[0]
reversed = fileName[::-1]
splitIndex = False
for index in range(len(reversed)):
char = reversed[index]
try:
int(char)
except ValueError:
splitIndex = index
break
version = 0
name = fileName
if splitIndex:
name = reversed[splitIndex:][::-1]
version = int(reversed[:splitIndex][::-1])
# remove whitespace from end of name
name = name.rstrip()
# If an aep file with the same name is already stored, check for the latest version
if name in aepDict.keys():
aepData = aepDict[name]
aepPath = aepData[0]
aepVersion = aepData[1]
if aepVersion > version:
continue
path = os.path.join(root, file)
aepDict[name] = [path, version]
aepFiles = [ aepDict[key][0] for key in aepDict.keys() ]
aepFiles.sort()
return aepFiles
#################
#### Classes ####
#################
class RenderThread(QThread):
started = pyqtSignal(str)
finished = pyqtSignal(str)
'''Thread to handle the aerender executable so the main GUI
stays responsive while render processing takes place'''
def __init__(self, parent, aerenderPath, aepList):
QThread.__init__(self, parent)
self.aerenderPath = aerenderPath
self.aepList = aepList
def run(self):
while len(self.aepList) > 0:
aepPath = self.aepList.pop(0)
self.started.emit(aepPath)
procStr = '"' + self.aerenderPath + '"'
procStr += ' -project "' + aepPath + '"'
procStr += ' -mp '
procStr += ' -close DO_NOT_SAVE_CHANGES'
proc = subprocess.Popen(procStr)
proc.wait()
self.finished.emit(aepPath)
class RenderDialog(QDialog):
'''Main GUI'''
def __init__(self):
QDialog.__init__(self)
# Widgets
queueGroup = QGroupBox("Queue")
self.queueList = QListWidget()
removeBtn = QPushButton("Remove")
addBtn = QPushButton("Add")
self.renderBtn = QPushButton("Render")
self.proBar = QProgressBar()
doneGroup = QGroupBox("Done")
self.doneList = QListWidget()
# Layout
layout = QGridLayout(queueGroup)
layout.addWidget(self.queueList, 0, 0, 1, 2)
layout.addWidget(removeBtn, 1, 0)
layout.addWidget(addBtn, 1, 1)
layout = QVBoxLayout(doneGroup)
layout.addWidget(self.doneList)
layout = QVBoxLayout(self)
layout.addWidget(queueGroup)
layout.addWidget(self.renderBtn)
layout.addWidget(self.proBar)
layout.addWidget(doneGroup)
# Connections
removeBtn.clicked.connect(self.remove_queue)
addBtn.clicked.connect(self.add_queue)
self.queueList.itemDoubleClicked[QListWidgetItem].connect(self.open_item_folder)
self.doneList.itemDoubleClicked[QListWidgetItem].connect(self.open_item_folder)
self.renderBtn.clicked.connect(self.render)
# Settings
self.setWindowTitle("AE Render Queue")
self.queueList.setSelectionMode(QAbstractItemView.MultiSelection)
self.doneList.setSelectionMode(QAbstractItemView.NoSelection)
# Run
searchFolder = str(QFileDialog.getExistingDirectory(self, "Select folder to search for all After Effects Projects in"))
aepFiles = get_aep_files(searchFolder)
self.queueList.addItems(aepFiles)
self.proBar.hide()
## Defs ##
def render(self):
self.renderBtn.hide()
self.proBar.show()
self.proBar.setMaximum(self.queueList.count() + 1)
self.proBar.setFormat("Locating aerender")
self.proBar.setValue(0)
aerenderPath = aerender_path()
if aerenderPath == None:
QMessageBox.critical(self, "ERROR", "Cannot locate the \"aerender\" file in the default install directory for your platform. \nPlease re-install After Effects to the default location or \nmodify this scripts \"program_folders\" function." )
self.close()
aepList = [ str(self.queueList.item(index).text()) for index in range(self.queueList.count()) ]
renderThread = RenderThread(self, aerenderPath, aepList)
renderThread.start()
renderThread.started.connect(self.single_render_started)
renderThread.finished.connect(self.single_render_finished)
def single_render_started(self, aepPath):
'''Increment progress when a new render is started.'''
self.proBar.setFormat(os.path.basename(aepPath))
self.proBar.setValue(self.proBar.value() + 1)
def single_render_finished(self, aepPath):
'''Move the aep file path from the render queue to the done
queue once completed.
Also if there are no more items to render, reset the GUI'''
item = self.queueList.takeItem(0)
self.doneList.insertItem(0, item)
if not self.queueList.count() > 0:
self.renderBtn.show()
self.proBar.hide()
def remove_queue(self):
'''Remove selected items from the queue'''
rows = []
for item in self.queueList.selectedItems():
rows.append(self.queueList.row(item))
rows.sort(reverse=True)
for row in rows:
item = self.queueList.takeItem(row)
sip.delete(item)
def add_queue(self):
'''Add specified items to the queue'''
files = QFileDialog.getOpenFileNames(self, "Select .aep files to add to the render queue", filter = "After Effects Projects (*.aep)")
files.sort()
self.queueList.addItems(files)
def open_item_folder(self, item):
'''Open the folder of the specified aep file'''
folder = os.path.dirname(str(item.text()))
open_folder(folder)
##############
#### Main ####
##############
if __name__ == "__main__":
app = QApplication(sys.argv)
renDlg= RenderDialog()
renDlg.show()
sys.exit(app.exec_())
另一个建议是学习python和pyqt5,这对你所放的论坛不好:"我不是python编码的专家"