2017-05-31 2 views
0

Dieser Code ist über After Effects Render. Ich habe pyqt5 und Python 3.4 installiert Ich bin kein Experte in Python CodierungPython Fehler (QThread ist nicht definiert)

""" 
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 
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() 

     self.connect(renderThread, SIGNAL("STARTED"), self.single_render_started) 
     self.connect(renderThread, SIGNAL("FINISHED"), 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_()) 

ich folgende Fehlermeldung erhalten, wenn ich es laufen. Es ist sehr frustrierend.

Bitte antworten Sie in der Sprache des Laien, da ich nicht viel Python-Terminologie kenne. Wenn möglich, geben Sie bitte den geänderten Code direkt an.

Dank und Grüße. Der Link zur Website, wo ich diesen Code bekam ist https://www.highend3d.com/downloads/applications/render-managers/c/after-effects-render-queue

Antwort

0

Das Problem Klassen importieren, eine einfache Art und Weise zu lösen ist das folgende in dem Teil der Importe zu platzieren:

from PyQt5.QtCore import * 
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 

Plus: Ein weiterer mögliche Fehler Sie haben könnte, ist, dass der Code eine alte Verbindung Stil verwendet, wenn Sie Fehler haben, ändern Sie die folgenden Schritte aus:

self.connect(renderThread, SIGNAL("STARTED"), self.single_render_started) 
self.connect(renderThread, SIGNAL("FINISHED"), self.single_render_finished) 

zu:

renderThread.started.connect(self.single_render_started) 
renderThread.finished.connect(self.single_render_finished) 

vollständigen Code:

""" 
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_()) 
+0

Thank u sehr viel funktioniert es jetzt richtig –

Verwandte Themen