├── .gitignore ├── MANIFEST.in ├── README.md ├── docs ├── Makefile ├── make.bat └── source │ ├── compatibility.rst │ ├── conf.py │ ├── index.rst │ ├── installation.rst │ ├── media │ └── images │ │ ├── general │ │ ├── icn_renderthreads.png │ │ └── renderthreads_header.png │ │ ├── installation │ │ └── renderthreads_blank.jpg │ │ ├── options │ │ ├── menu_command_line.jpg │ │ ├── menu_options.jpg │ │ ├── menu_render.jpg │ │ └── menu_threads.jpg │ │ └── quickstart │ │ ├── add_selected_write_nodes.jpg │ │ ├── check_script_name_and_nuke_version.jpg │ │ ├── check_the_command_line.jpg │ │ ├── disable_rendering.jpg │ │ ├── execute_script.jpg │ │ ├── render_selected_node.jpg │ │ ├── render_started.jpg │ │ └── selected_write_node_added.jpg │ ├── options.rst │ └── quickstart.rst ├── renderthreads ├── __init__.py ├── lib │ ├── __init__.py │ ├── gui │ │ ├── __init__.py │ │ ├── renderthreads_command_line_flag_widget.py │ │ ├── renderthreads_dock_widget.py │ │ ├── renderthreads_gui_helper.py │ │ ├── renderthreads_progressbar.py │ │ ├── renderthreads_signal_remapper.py │ │ ├── renderthreads_slider_widget.py │ │ └── renderthreads_stylesheets.py │ ├── mvc │ │ ├── __init__.py │ │ ├── renderthreads_item_delegate.py │ │ ├── renderthreads_model.py │ │ ├── renderthreads_model_context_menu.py │ │ ├── renderthreads_node.py │ │ └── renderthreads_view.py │ ├── renderthreads_command_line_engine.py │ ├── renderthreads_globals.py │ ├── renderthreads_gui_setup.py │ ├── renderthreads_logging.py │ ├── renderthreads_mvc_setup.py │ ├── renderthreads_nuke.py │ ├── renderthreads_render.py │ ├── renderthreads_services_setup.py │ ├── renderthreads_threads.py │ └── third_party │ │ ├── __init__.py │ │ └── pysideuic │ │ ├── Compiler │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── __init__.pyo │ │ ├── compiler.py │ │ ├── compiler.pyc │ │ ├── compiler.pyo │ │ ├── indenter.py │ │ ├── indenter.pyc │ │ ├── indenter.pyo │ │ ├── misc.py │ │ ├── misc.pyc │ │ ├── misc.pyo │ │ ├── proxy_type.py │ │ ├── proxy_type.pyc │ │ ├── proxy_type.pyo │ │ ├── qobjectcreator.py │ │ ├── qobjectcreator.pyc │ │ ├── qobjectcreator.pyo │ │ ├── qtproxies.py │ │ ├── qtproxies.pyc │ │ └── qtproxies.pyo │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── __init__.pyo │ │ ├── driver.py │ │ ├── driver.pyc │ │ ├── driver.pyo │ │ ├── exceptions.py │ │ ├── exceptions.pyc │ │ ├── exceptions.pyo │ │ ├── icon_cache.py │ │ ├── icon_cache.pyc │ │ ├── icon_cache.pyo │ │ ├── objcreator.py │ │ ├── objcreator.pyc │ │ ├── objcreator.pyo │ │ ├── port_v2 │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── __init__.pyo │ │ ├── as_string.py │ │ ├── as_string.pyc │ │ ├── as_string.pyo │ │ ├── ascii_upper.py │ │ ├── ascii_upper.pyc │ │ ├── ascii_upper.pyo │ │ ├── invoke.py │ │ ├── invoke.pyc │ │ ├── invoke.pyo │ │ ├── load_plugin.py │ │ ├── load_plugin.pyc │ │ ├── load_plugin.pyo │ │ ├── proxy_base.py │ │ ├── proxy_base.pyc │ │ ├── proxy_base.pyo │ │ ├── string_io.py │ │ ├── string_io.pyc │ │ └── string_io.pyo │ │ ├── properties.py │ │ ├── properties.pyc │ │ ├── properties.pyo │ │ ├── pyside-uic.1 │ │ ├── uiparser.py │ │ ├── uiparser.pyc │ │ ├── uiparser.pyo │ │ └── widget-plugins │ │ ├── __init__.py │ │ ├── phonon.py │ │ ├── phonon.pyc │ │ ├── phonon.pyo │ │ ├── qtdeclarative.py │ │ ├── qtdeclarative.pyc │ │ ├── qtdeclarative.pyo │ │ ├── qtwebkit.py │ │ ├── qtwebkit.pyc │ │ └── qtwebkit.pyo ├── media │ ├── __init__.py │ ├── fonts │ │ ├── __init__.py │ │ └── futura-lt-light.ttf │ ├── icons │ │ ├── __init__.py │ │ ├── icn_renderthreads.png │ │ └── renderthreads_header.png │ └── ui │ │ ├── __init__.py │ │ └── renderthreads.ui └── renderthreads.py ├── requirements.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #------------------------- 5 | #Ignore List 6 | #------------------------- 7 | 8 | 9 | #File extensions 10 | #------------------------- 11 | *.pyc 12 | *.pyo 13 | *.db 14 | 15 | 16 | #Folders 17 | #------------------------- 18 | docs/build 19 | renderthreads.egg-info 20 | dist 21 | 22 | 23 | #Allow specific folders and subfolders 24 | #(never allow .db though) 25 | #------------------------- 26 | !renderthreads/lib/third_party/** 27 | *.db -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include renderthreads/media/ui * 2 | recursive-include renderthreads/media/fonts * 3 | recursive-include renderthreads/media/icons * 4 | recursive-include renderthreads/lib/third_party/pysideuic * 5 | recursive-include renderthreads/lib/third_party/pysideuic/Compiler * 6 | recursive-include renderthreads/lib/third_party/pysideuic/port_v2 * 7 | recursive-include renderthreads/lib/third_party/pysideuic/widget-plugins * -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | ----------------------- 7 |
8 | 9 | 10 | 11 | 12 |
13 | ----------------------- 14 | 15 | [![Documentation Status](https://readthedocs.org/projects/renderthreads/badge/?version=latest)](https://readthedocs.org/projects/renderthreads/?badge=latest) 16 | [![Downloads](https://pypip.in/download/renderthreads/badge.svg?style=flat)](https://pypi.python.org/pypi/renderthreads/) 17 | [![Latest Version](https://pypip.in/version/renderthreads/badge.svg?style=flat)](https://pypi.python.org/pypi/renderthreads/) 18 | [![Development Status](https://pypip.in/status/renderthreads/badge.svg?style=flat)](https://pypi.python.org/pypi/renderthreads/) 19 | [![Download format](https://pypip.in/format/renderthreads/badge.svg?style=flat)](https://pypi.python.org/pypi/renderthreads/) 20 | [![License](https://pypip.in/license/renderthreads/badge.svg?style=flat)](https://pypi.python.org/pypi/renderthreads/) 21 | [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/timmwagener/renderthreads) 22 | 23 | ----------------------- 24 | 25 | 26 | What is it ? 27 | ----------------------- 28 | **renderthreads** is a [Python](https://www.python.org/) package that enables per-frame easy command-line multithreaded rendering for the popular compositing application [Nuke](http://www.thefoundry.co.uk/products/nuke/). You can find the documentation [here](http://renderthreads.readthedocs.org/). 29 | 30 | 31 | Features 32 | ----------------------- 33 | * **Improve render speed** 34 | Per-frame parallel command-line rendering made easy. 35 | * **Safety fallback** 36 | Jobs that terminated unsuccessfully are added back to the job list. 37 | * **Monitor and adjust while rendering** 38 | You can adjust several parameters during command-line rendering, like the number of cores or the verbosity. 39 | * **Enable/disable jobs while rendering** 40 | More flexible and fine grained than default *divide and render* approach due to task queue. You can disable the rest of the range of jobs during the rendering. 41 | * **Easy Commandline management** 42 | Adjust the command line via UI. 43 | 44 | ----------------------- 45 | 46 | [**Documentation**](http://renderthreads.readthedocs.org/) [**Quickstart**](http://renderthreads.readthedocs.org/quickstart.html) [**Download**](https://pypi.python.org/pypi/renderthreads/) [**Vimeo**](https://vimeo.com/timmwagener/renderthreads) [**Author**](http://www.timmwagener.com/) 47 | 48 | ----------------------- 49 | 50 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/renderthreads.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/renderthreads.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/renderthreads" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/renderthreads" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 10 | set I18NSPHINXOPTS=%SPHINXOPTS% source 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | goto end 41 | ) 42 | 43 | if "%1" == "clean" ( 44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 45 | del /q /s %BUILDDIR%\* 46 | goto end 47 | ) 48 | 49 | 50 | %SPHINXBUILD% 2> nul 51 | if errorlevel 9009 ( 52 | echo. 53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 54 | echo.installed, then set the SPHINXBUILD environment variable to point 55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 56 | echo.may add the Sphinx directory to PATH. 57 | echo. 58 | echo.If you don't have Sphinx installed, grab it from 59 | echo.http://sphinx-doc.org/ 60 | exit /b 1 61 | ) 62 | 63 | if "%1" == "html" ( 64 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 65 | if errorlevel 1 exit /b 1 66 | echo. 67 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 68 | goto end 69 | ) 70 | 71 | if "%1" == "dirhtml" ( 72 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 73 | if errorlevel 1 exit /b 1 74 | echo. 75 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 76 | goto end 77 | ) 78 | 79 | if "%1" == "singlehtml" ( 80 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 81 | if errorlevel 1 exit /b 1 82 | echo. 83 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 84 | goto end 85 | ) 86 | 87 | if "%1" == "pickle" ( 88 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 89 | if errorlevel 1 exit /b 1 90 | echo. 91 | echo.Build finished; now you can process the pickle files. 92 | goto end 93 | ) 94 | 95 | if "%1" == "json" ( 96 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 97 | if errorlevel 1 exit /b 1 98 | echo. 99 | echo.Build finished; now you can process the JSON files. 100 | goto end 101 | ) 102 | 103 | if "%1" == "htmlhelp" ( 104 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 105 | if errorlevel 1 exit /b 1 106 | echo. 107 | echo.Build finished; now you can run HTML Help Workshop with the ^ 108 | .hhp project file in %BUILDDIR%/htmlhelp. 109 | goto end 110 | ) 111 | 112 | if "%1" == "qthelp" ( 113 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 114 | if errorlevel 1 exit /b 1 115 | echo. 116 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 117 | .qhcp project file in %BUILDDIR%/qthelp, like this: 118 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\renderthreads.qhcp 119 | echo.To view the help file: 120 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\renderthreads.ghc 121 | goto end 122 | ) 123 | 124 | if "%1" == "devhelp" ( 125 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished. 129 | goto end 130 | ) 131 | 132 | if "%1" == "epub" ( 133 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 134 | if errorlevel 1 exit /b 1 135 | echo. 136 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 137 | goto end 138 | ) 139 | 140 | if "%1" == "latex" ( 141 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 142 | if errorlevel 1 exit /b 1 143 | echo. 144 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 145 | goto end 146 | ) 147 | 148 | if "%1" == "latexpdf" ( 149 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 150 | cd %BUILDDIR%/latex 151 | make all-pdf 152 | cd %BUILDDIR%/.. 153 | echo. 154 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 155 | goto end 156 | ) 157 | 158 | if "%1" == "latexpdfja" ( 159 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 160 | cd %BUILDDIR%/latex 161 | make all-pdf-ja 162 | cd %BUILDDIR%/.. 163 | echo. 164 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 165 | goto end 166 | ) 167 | 168 | if "%1" == "text" ( 169 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 170 | if errorlevel 1 exit /b 1 171 | echo. 172 | echo.Build finished. The text files are in %BUILDDIR%/text. 173 | goto end 174 | ) 175 | 176 | if "%1" == "man" ( 177 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 178 | if errorlevel 1 exit /b 1 179 | echo. 180 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 181 | goto end 182 | ) 183 | 184 | if "%1" == "texinfo" ( 185 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 186 | if errorlevel 1 exit /b 1 187 | echo. 188 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 189 | goto end 190 | ) 191 | 192 | if "%1" == "gettext" ( 193 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 194 | if errorlevel 1 exit /b 1 195 | echo. 196 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 197 | goto end 198 | ) 199 | 200 | if "%1" == "changes" ( 201 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 202 | if errorlevel 1 exit /b 1 203 | echo. 204 | echo.The overview file is in %BUILDDIR%/changes. 205 | goto end 206 | ) 207 | 208 | if "%1" == "linkcheck" ( 209 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 210 | if errorlevel 1 exit /b 1 211 | echo. 212 | echo.Link check complete; look for any errors in the above output ^ 213 | or in %BUILDDIR%/linkcheck/output.txt. 214 | goto end 215 | ) 216 | 217 | if "%1" == "doctest" ( 218 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 219 | if errorlevel 1 exit /b 1 220 | echo. 221 | echo.Testing of doctests in the sources finished, look at the ^ 222 | results in %BUILDDIR%/doctest/output.txt. 223 | goto end 224 | ) 225 | 226 | if "%1" == "xml" ( 227 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 228 | if errorlevel 1 exit /b 1 229 | echo. 230 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 231 | goto end 232 | ) 233 | 234 | if "%1" == "pseudoxml" ( 235 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 236 | if errorlevel 1 exit /b 1 237 | echo. 238 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 239 | goto end 240 | ) 241 | 242 | :end 243 | -------------------------------------------------------------------------------- /docs/source/compatibility.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .. _compatibility: 5 | 6 | .. 7 | Renderthreads compatibility issues. 8 | 9 | 10 | .. figure:: media/images/general/icn_renderthreads.png 11 | :width: 100px 12 | :align: center 13 | :alt: renderthreads icon 14 | 15 | ------------------------------------------ 16 | 17 | Compatibility 18 | ============= 19 | 20 | ------------------------------------------ 21 | 22 | Here i will note environments (OS, Nuke versions) that **renderthreads** was tested in and is known to work with.....or not. 23 | If you encounter any issues running the tool with your version of Nuke or your operating system, `feel free to drop me a line `_. Or file a bug report on the `github issue tracker `_. 24 | 25 | ------------------------------------------ 26 | 27 | Operating systems 28 | ----------------- 29 | 30 | ------------------------------------------ 31 | 32 | Compatible 33 | ********** 34 | * Windows7 35 | 36 | Incompatible 37 | ************ 38 | 39 | Untested 40 | ******** 41 | * Linux 42 | * MacOS 43 | 44 | Nuke versions 45 | ------------- 46 | 47 | ------------------------------------------ 48 | 49 | Compatible 50 | ********** 51 | * 9.x 52 | * 8.x 53 | 54 | Incompatible 55 | ************ 56 | * 7.x/below: **renderthreads** needs **Python 2.7** -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # renderthreads documentation build configuration file, created by 4 | # sphinx-quickstart on Sat Jan 10 13:10:35 2015. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | #Import 16 | #------------------------------------------------ 17 | #------------------------------------------------ 18 | 19 | #python 20 | import sys 21 | import os 22 | #custom 23 | import sphinx_rtd_theme 24 | import sphinx_bootstrap_theme 25 | import mock 26 | 27 | # If extensions (or modules to document with autodoc) are in another directory, 28 | # add these directories to sys.path here. If the directory is relative to the 29 | # documentation root, use os.path.abspath to make it absolute, like shown here. 30 | #sys.path.insert(0, os.path.abspath('.')) 31 | 32 | # -- General configuration ------------------------------------------------ 33 | 34 | # If your documentation needs a minimal Sphinx version, state it here. 35 | #needs_sphinx = '1.0' 36 | 37 | # Add any Sphinx extension module names here, as strings. They can be 38 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 39 | # ones. 40 | extensions = [ 41 | 'sphinx.ext.autodoc', 42 | 'sphinx.ext.doctest', 43 | 'sphinx.ext.intersphinx', 44 | 'sphinx.ext.todo', 45 | 'sphinx.ext.ifconfig', 46 | 'sphinx.ext.viewcode', 47 | ] 48 | 49 | # Add any paths that contain templates here, relative to this directory. 50 | templates_path = ['_templates'] 51 | 52 | # The suffix of source filenames. 53 | source_suffix = '.rst' 54 | 55 | # The encoding of source files. 56 | #source_encoding = 'utf-8-sig' 57 | 58 | # The master toctree document. 59 | master_doc = 'index' 60 | 61 | # General information about the project. 62 | project = u'renderthreads' 63 | copyright = u'2015, timmwagener' 64 | 65 | # The version info for the project you're documenting, acts as replacement for 66 | # |version| and |release|, also used in various other places throughout the 67 | # built documents. 68 | # 69 | # The short X.Y version. 70 | version = '0.1' 71 | # The full version, including alpha/beta/rc tags. 72 | release = '0.1' 73 | 74 | # The language for content autogenerated by Sphinx. Refer to documentation 75 | # for a list of supported languages. 76 | #language = None 77 | 78 | # There are two options for replacing |today|: either, you set today to some 79 | # non-false value, then it is used: 80 | #today = '' 81 | # Else, today_fmt is used as the format for a strftime call. 82 | #today_fmt = '%B %d, %Y' 83 | 84 | # List of patterns, relative to source directory, that match files and 85 | # directories to ignore when looking for source files. 86 | exclude_patterns = [] 87 | 88 | # The reST default role (used for this markup: `text`) to use for all 89 | # documents. 90 | #default_role = None 91 | 92 | # If true, '()' will be appended to :func: etc. cross-reference text. 93 | #add_function_parentheses = True 94 | 95 | # If true, the current module name will be prepended to all description 96 | # unit titles (such as .. function::). 97 | #add_module_names = True 98 | 99 | # If true, sectionauthor and moduleauthor directives will be shown in the 100 | # output. They are ignored by default. 101 | #show_authors = False 102 | 103 | # The name of the Pygments (syntax highlighting) style to use. 104 | pygments_style = 'sphinx' 105 | 106 | # A list of ignored prefixes for module index sorting. 107 | #modindex_common_prefix = [] 108 | 109 | # If true, keep warnings as "system message" paragraphs in the built documents. 110 | #keep_warnings = False 111 | 112 | 113 | # -- Options for HTML output ---------------------------------------------- 114 | 115 | # The theme to use for HTML and HTML Help pages. See the documentation for 116 | # a list of builtin themes. 117 | html_theme = 'sphinx_rtd_theme' # Options: default, haiku, sphinx_rtd_theme, bootstrap 118 | 119 | # Theme options are theme-specific and customize the look and feel of a theme 120 | # further. For a list of options available for each theme, see the 121 | # documentation. 122 | #html_theme_options = {} 123 | 124 | # Add any paths that contain custom themes here, relative to this directory. 125 | #Possible option 126 | #sphinx_rtd_theme.get_html_theme_path() 127 | #sphinx_bootstrap_theme.get_html_theme_path() 128 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 129 | 130 | # The name for this set of Sphinx documents. If None, it defaults to 131 | # " v documentation". 132 | #html_title = None 133 | 134 | # A shorter title for the navigation bar. Default is the same as html_title. 135 | #html_short_title = None 136 | 137 | # The name of an image file (relative to this directory) to place at the top 138 | # of the sidebar. 139 | #html_logo = None 140 | 141 | # The name of an image file (within the static path) to use as favicon of the 142 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 143 | # pixels large. 144 | #html_favicon = None 145 | 146 | # Add any paths that contain custom static files (such as style sheets) here, 147 | # relative to this directory. They are copied after the builtin static files, 148 | # so a file named "default.css" will overwrite the builtin "default.css". 149 | html_static_path = ['_static'] 150 | 151 | # Add any extra paths that contain custom files (such as robots.txt or 152 | # .htaccess) here, relative to this directory. These files are copied 153 | # directly to the root of the documentation. 154 | #html_extra_path = [] 155 | 156 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 157 | # using the given strftime format. 158 | #html_last_updated_fmt = '%b %d, %Y' 159 | 160 | # If true, SmartyPants will be used to convert quotes and dashes to 161 | # typographically correct entities. 162 | #html_use_smartypants = True 163 | 164 | # Custom sidebar templates, maps document names to template names. 165 | #html_sidebars = {} 166 | 167 | # Additional templates that should be rendered to pages, maps page names to 168 | # template names. 169 | #html_additional_pages = {} 170 | 171 | # If false, no module index is generated. 172 | #html_domain_indices = True 173 | 174 | # If false, no index is generated. 175 | #html_use_index = True 176 | 177 | # If true, the index is split into individual pages for each letter. 178 | #html_split_index = False 179 | 180 | # If true, links to the reST sources are added to the pages. 181 | #html_show_sourcelink = True 182 | 183 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 184 | #html_show_sphinx = True 185 | 186 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 187 | #html_show_copyright = True 188 | 189 | # If true, an OpenSearch description file will be output, and all pages will 190 | # contain a tag referring to it. The value of this option must be the 191 | # base URL from which the finished HTML is served. 192 | #html_use_opensearch = '' 193 | 194 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 195 | #html_file_suffix = None 196 | 197 | # Output file base name for HTML help builder. 198 | htmlhelp_basename = 'renderthreadsdoc' 199 | 200 | 201 | # -- Options for LaTeX output --------------------------------------------- 202 | 203 | latex_elements = { 204 | # The paper size ('letterpaper' or 'a4paper'). 205 | #'papersize': 'letterpaper', 206 | 207 | # The font size ('10pt', '11pt' or '12pt'). 208 | #'pointsize': '10pt', 209 | 210 | # Additional stuff for the LaTeX preamble. 211 | #'preamble': '', 212 | } 213 | 214 | # Grouping the document tree into LaTeX files. List of tuples 215 | # (source start file, target name, title, 216 | # author, documentclass [howto, manual, or own class]). 217 | latex_documents = [ 218 | ('index', 'renderthreads.tex', u'renderthreads Documentation', 219 | u'timmwagener', 'manual'), 220 | ] 221 | 222 | # The name of an image file (relative to this directory) to place at the top of 223 | # the title page. 224 | #latex_logo = None 225 | 226 | # For "manual" documents, if this is true, then toplevel headings are parts, 227 | # not chapters. 228 | #latex_use_parts = False 229 | 230 | # If true, show page references after internal links. 231 | #latex_show_pagerefs = False 232 | 233 | # If true, show URL addresses after external links. 234 | #latex_show_urls = False 235 | 236 | # Documents to append as an appendix to all manuals. 237 | #latex_appendices = [] 238 | 239 | # If false, no module index is generated. 240 | #latex_domain_indices = True 241 | 242 | 243 | # -- Options for manual page output --------------------------------------- 244 | 245 | # One entry per manual page. List of tuples 246 | # (source start file, name, description, authors, manual section). 247 | man_pages = [ 248 | ('index', 'renderthreads', u'renderthreads Documentation', 249 | [u'timmwagener'], 1) 250 | ] 251 | 252 | # If true, show URL addresses after external links. 253 | #man_show_urls = False 254 | 255 | 256 | # -- Options for Texinfo output ------------------------------------------- 257 | 258 | # Grouping the document tree into Texinfo files. List of tuples 259 | # (source start file, target name, title, author, 260 | # dir menu entry, description, category) 261 | texinfo_documents = [ 262 | ('index', 'renderthreads', u'renderthreads Documentation', 263 | u'timmwagener', 'renderthreads', 'One line description of project.', 264 | 'Miscellaneous'), 265 | ] 266 | 267 | # Documents to append as an appendix to all manuals. 268 | #texinfo_appendices = [] 269 | 270 | # If false, no module index is generated. 271 | #texinfo_domain_indices = True 272 | 273 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 274 | #texinfo_show_urls = 'footnote' 275 | 276 | # If true, do not generate a @detailmenu in the "Top" node's menu. 277 | #texinfo_no_detailmenu = False 278 | 279 | 280 | # Example configuration for intersphinx: refer to the Python standard library. 281 | intersphinx_mapping = {'http://docs.python.org/': None} 282 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _index: 3 | 4 | .. renderthreads documentation master file, created by 5 | sphinx-quickstart on Sat Jan 10 13:10:35 2015. 6 | You can adapt this file completely to your liking, but it should at least 7 | contain the root `toctree` directive. 8 | 9 | 10 | .. figure:: media/images/general/renderthreads_header.png 11 | :width: 700px 12 | :align: center 13 | :alt: renderthreads header 14 | 15 | ------------------------------------------ 16 | 17 | .. raw:: html 18 | 19 |

renderthreads is a Python package that enables per-frame easy command-line multithreaded rendering for the popular compositing application Nuke. It is created and maintained by Timm Wagener.

20 | 21 | ------------------------------------------ 22 | 23 | .. raw:: html 24 | 25 |
26 | 27 | 28 | 29 | 30 |
31 | 32 | ------------------------------------------ 33 | 34 | .. image:: https://readthedocs.org/projects/renderthreads/badge/?version=latest 35 | :target: https://readthedocs.org/projects/renderthreads/?badge=latest 36 | :alt: Documentation Status 37 | 38 | .. image:: https://pypip.in/download/renderthreads/badge.svg?style=flat 39 | :target: https://pypi.python.org/pypi//renderthreads/ 40 | :alt: Downloads 41 | 42 | .. image:: https://pypip.in/version/renderthreads/badge.svg?style=flat 43 | :target: https://pypi.python.org/pypi/renderthreads/ 44 | :alt: Latest Version 45 | 46 | .. image:: https://pypip.in/status/renderthreads/badge.svg?style=flat 47 | :target: https://pypi.python.org/pypi/renderthreads/ 48 | :alt: Development Status 49 | 50 | .. image:: https://pypip.in/format/renderthreads/badge.svg?style=flat 51 | :target: https://pypi.python.org/pypi/renderthreads/ 52 | :alt: Download format 53 | 54 | .. image:: https://pypip.in/license/renderthreads/badge.svg?style=flat 55 | :target: https://pypi.python.org/pypi/renderthreads/ 56 | :alt: License 57 | 58 | .. image:: https://badges.gitter.im/gitterHQ/gitter.png 59 | :target: https://gitter.im/timmwagener/renderthreads 60 | :alt: Gitter 61 | 62 | ------------------------------------------ 63 | 64 | Content 65 | ------- 66 | 67 | .. toctree:: 68 | :maxdepth: 1 69 | 70 | installation 71 | quickstart 72 | options 73 | compatibility 74 | 75 | 76 | -------------------------------------------------------------------------------- /docs/source/installation.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .. _installation: 5 | 6 | .. 7 | How to install renderthreads. 8 | 9 | 10 | .. figure:: media/images/general/icn_renderthreads.png 11 | :width: 100px 12 | :align: center 13 | :alt: renderthreads icon 14 | 15 | ------------------------------------------ 16 | 17 | Installation 18 | ============ 19 | 20 | The installation is easy. Choose one of several options. 21 | 22 | Manual installation 23 | ------------------- 24 | ------------------------------------------ 25 | 26 | * Go to `PyPI `_ and download the package. 27 | * Then extract the zip and go into the folder renderthreads-x.x.x (for example renderthreads-0.2.3). In there you'll find a folder called **renderthreads**. 28 | * Take it and copy it into your Nuke **site-packages** (usually *NukeX.YvZ/lib/site-packages/*) or anywhere else on your Nuke Python path. 29 | 30 | pip 31 | --- 32 | ------------------------------------------ 33 | 34 | If you have pip installed for your Python interpreter in Nuke you can just type the following: 35 | 36 | .. code:: 37 | 38 | pip install renderthreads 39 | 40 | To verify the installation type: 41 | 42 | .. code:: 43 | 44 | pip list 45 | 46 | and see if renderthreads is amongst the listed packages. 47 | 48 | .. note:: 49 | 50 | In case you have pip but **NOT** for your Nuke Python interpreter, which might often be the case, i would still recommend doing the above procedure. 51 | **renderthreads** will then be installed into your default system Python and you have to copy it into your Nuke 52 | site-packages by hand **but** pip still provides an easy and clean way to quickly update **renderthreads**. 53 | 54 | Run it 55 | ------ 56 | ------------------------------------------ 57 | 58 | To start it open up your **Nuke Python script editor**, copy this and run: 59 | 60 | 61 | .. code:: 62 | 63 | from renderthreads import renderthreads 64 | reload(renderthreads) 65 | renderthreads.run() 66 | 67 | In the case of a successful execution you should see the following window: 68 | 69 | .. figure:: media/images/installation/renderthreads_blank.jpg 70 | :width: 700px 71 | :align: center 72 | :alt: renderthreads blank 73 | 74 | You successfully installed renderthreads. -------------------------------------------------------------------------------- /docs/source/media/images/general/icn_renderthreads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/general/icn_renderthreads.png -------------------------------------------------------------------------------- /docs/source/media/images/general/renderthreads_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/general/renderthreads_header.png -------------------------------------------------------------------------------- /docs/source/media/images/installation/renderthreads_blank.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/installation/renderthreads_blank.jpg -------------------------------------------------------------------------------- /docs/source/media/images/options/menu_command_line.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/options/menu_command_line.jpg -------------------------------------------------------------------------------- /docs/source/media/images/options/menu_options.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/options/menu_options.jpg -------------------------------------------------------------------------------- /docs/source/media/images/options/menu_render.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/options/menu_render.jpg -------------------------------------------------------------------------------- /docs/source/media/images/options/menu_threads.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/options/menu_threads.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/add_selected_write_nodes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/add_selected_write_nodes.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/check_script_name_and_nuke_version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/check_script_name_and_nuke_version.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/check_the_command_line.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/check_the_command_line.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/disable_rendering.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/disable_rendering.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/execute_script.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/execute_script.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/render_selected_node.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/render_selected_node.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/render_started.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/render_started.jpg -------------------------------------------------------------------------------- /docs/source/media/images/quickstart/selected_write_node_added.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/docs/source/media/images/quickstart/selected_write_node_added.jpg -------------------------------------------------------------------------------- /docs/source/options.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .. _options: 5 | 6 | .. 7 | Renderthreads options. 8 | 9 | 10 | .. figure:: media/images/general/icn_renderthreads.png 11 | :width: 100px 12 | :align: center 13 | :alt: renderthreads icon 14 | ------------------------------------------ 15 | 16 | Options 17 | ======= 18 | 19 | ------------------------------------------ 20 | 21 | **renderthreads** gives you a few menus to adjust things and influence the rendering. 22 | All the widgets provide reasonable **tooltips** that tell you what they are doing. 23 | Anyways, here's another source of information on what those settings do. 24 | 25 | ------------------------------------------ 26 | 27 | Render 28 | ------ 29 | 30 | ------------------------------------------ 31 | 32 | .. figure:: media/images/options/menu_render.jpg 33 | :align: center 34 | :alt: renderthreads icon 35 | 36 | ------------------------------------------ 37 | 38 | * **Nuke node** is the name of the write node you are about to render. You can edit it from within renderthreads. Write nodes within nested groups are also valid. 39 | * **Start frame** of your render sequence. The initial value is taken from the root node. 40 | * **End frame** of your render sequence. The initial value is taken from the root node. 41 | * **Progress** of the rendering of your specific write node. The blue number is the total amount of jobs/frames. The progressbar at the bottom displays the **sum of all write nodes**. 42 | * **Priority** of the rendering of the specific write node. This cannot be adjusted once the jobs are added. In case of equal priorities the jobs are prioritized by the write node alphabetic order. 43 | * **Log** displays success/fail messages for the command-line jobs. By default only error messages are logged, but you can change that in the **Threads** menu. 44 | 45 | Threads 46 | ------- 47 | 48 | ------------------------------------------ 49 | 50 | .. figure:: media/images/options/menu_threads.jpg 51 | :align: center 52 | :alt: renderthreads icon 53 | 54 | ------------------------------------------ 55 | 56 | * **Threadcount** lets you adjust how many threads/cores you want to use for rendering. Each core renders a single frame. By default the number of cores is **half the number of the available cores in your system**, which is a conservative setting ment to prevent **memory overflow**. 57 | 58 | .. warning:: 59 | 60 | Be aware that each command-line render opens your Nuke script to process it. Therefore it needs a certain amount of memory. When too many jobs are started that eat a lot of memory you might want to pick a lower threadcount to prevent **memory overflow**. 61 | 62 | * **Thread interval** is the rate at which a new job is started by a thread after the thread finished the current job. The should rarely be a reason to increase this value. 63 | * **Thread timeout** is a more **important value**. It sets the time in minutes that a rendering is allowed to take before it is forcibly closed. The default is 10 minutes, but demanding nuke comps can easily take longer. **If you wonder why all your renderings are terminated, a too low timeout setting might be the reason.** 64 | * **Display render shell** lets you adjust wether or not you want shell windows popping up. 65 | * **Log exitcode errors only** Wether you just want errors and their exit codes logged (process terminated, timed out, was disabled...) or also sucess messages. 66 | * **Re-add broken job** Wether or not to add a job to the queue again that terminated unsuccessfully. (With an exitcode different from 0). 67 | * **Re-add broken job count** How often such an error job gets added again. The default is 2. 68 | * **Start/Stop threads** Pause rendering. Will finish all currently running jobs and then re/start or stop rendering. All the jobs remain, so this is like a **pause** function. 69 | * **Print queue size** Print complete count of all jobs. 70 | 71 | Command-line 72 | ------------ 73 | 74 | ------------------------------------------ 75 | 76 | .. figure:: media/images/options/menu_command_line.jpg 77 | :align: center 78 | :alt: renderthreads icon 79 | 80 | ------------------------------------------ 81 | 82 | * **Command-line flags** Assemble the Nuke command line used for rendering. Here you have the default command line options (Taken from Nuke 8.05). At the top you see the command line that you assembled. Some values like **-X, -x or -F are locked and cannot be changed. They are handled internally**. Each flag has a tooltip that describes what it does. 83 | 84 | .. warning:: 85 | 86 | **renderthreads** does not restrict you in the combination of flags. Therefore you can set flags that are incompatible or make no sense (like enabling proxy mode while forcing full size rendering). 87 | 88 | * **Nuke script** is the currently open script. If the value is Root (script not saved yet), you might be prompted to save before rendering starts. The value updates automatically when you save the script. You cannot change this value. 89 | * **Nuke executable** The nuke exe that is used for rendering. You are free to pick the Nuke version you want. **Nuke is always started with the environment of the Nuke that is starting the jobs.** 90 | 91 | Options 92 | ------- 93 | 94 | ------------------------------------------ 95 | 96 | .. figure:: media/images/options/menu_options.jpg 97 | :align: center 98 | :alt: renderthreads icon 99 | 100 | ------------------------------------------ 101 | 102 | * **Logging level** How verbose **renderthreads** tells you about its state. 103 | * **Save script before render** lets you adjust if you want to automatically save before before starting a render. The default is on. **If this is off you might not render the latest adjustments in your comp unless you saved manually** 104 | 105 | -------------------------------------------------------------------------------- /docs/source/quickstart.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .. _quickstart: 5 | 6 | .. 7 | Up and running in a minute. 8 | 9 | 10 | .. figure:: media/images/general/icn_renderthreads.png 11 | :width: 100px 12 | :align: center 13 | :alt: renderthreads icon 14 | 15 | ------------------------------------------ 16 | 17 | Quickstart 18 | ========== 19 | 20 | ------------------------------------------ 21 | 22 | Have your first renderings up and running in under a minute (...or 2). 23 | To start a command-line rendering with **renderthreads** do the following. 24 | 25 | ------------------------------------------ 26 | 27 | 28 | .. figure:: media/images/quickstart/execute_script.jpg 29 | :width: 200px 30 | :align: center 31 | :alt: renderthreads icon 32 | 33 | Run the startup script like so. You may want to make a button out of it and integrate it in a menu. (Forgot how to install it? :ref:`Here's how `.) 34 | 35 | .. figure:: media/images/quickstart/add_selected_write_nodes.jpg 36 | :width: 200px 37 | :align: center 38 | :alt: renderthreads icon 39 | 40 | Select a write node and add it like so. 41 | 42 | .. figure:: media/images/quickstart/selected_write_node_added.jpg 43 | :width: 200px 44 | :align: center 45 | :alt: renderthreads icon 46 | 47 | Success. Your Write node is in **renderthreads** along with a **frame range** and a **priority**. 48 | 49 | .. figure:: media/images/quickstart/check_the_command_line.jpg 50 | :width: 200px 51 | :align: center 52 | :alt: renderthreads icon 53 | 54 | **Optional:** Check the command line menu if the command line settings are fine. For example you could tell Nuke to use render licenses over interactive ones. Each command line flag has a tooltip to (more or less) explain it. The explanations are copied from *../Nuke.exe -help* 55 | 56 | .. figure:: media/images/quickstart/check_script_name_and_nuke_version.jpg 57 | :width: 200px 58 | :align: center 59 | :alt: renderthreads icon 60 | 61 | **Optional:** Check the script name and the Nuke path under **Constants**. The nuke script is always the one you have open right now. If it says **Root** you might be prompted to save before rendering can start. The Nuke version can be choosen. 62 | 63 | .. figure:: media/images/quickstart/render_selected_node.jpg 64 | :width: 200px 65 | :align: center 66 | :alt: renderthreads icon 67 | 68 | Start the rendering like so. By default rendering will happen on half of the cores you have available. (You can adjust the number of cores in the *Threads* menu) 69 | 70 | .. figure:: media/images/quickstart/render_started.jpg 71 | :width: 200px 72 | :align: center 73 | :alt: renderthreads icon 74 | 75 | Success, you are rendering. A lot of command shells pop up by default (No worries, you can disable this in the *Threads* menu). The progress is displayed in the interface. 76 | 77 | ------------------------------------------ 78 | 79 | .. figure:: media/images/quickstart/disable_rendering.jpg 80 | :width: 200px 81 | :align: center 82 | :alt: renderthreads icon 83 | 84 | You can disable the rendering anytime, like so. Disabling will kill the jobs currently running and not start those that are still queued up anymore. -------------------------------------------------------------------------------- /renderthreads/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | RenderThreads Package 5 | ========================================== 6 | 7 | Tool to facilitate multithreaded export out of Nuke. 8 | 9 | 10 | ----------------------- 11 | 12 | **Author:** `Timm Wagener `_ 13 | *Version:* 0.1 14 | """ -------------------------------------------------------------------------------- /renderthreads/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/__init__.py -------------------------------------------------------------------------------- /renderthreads/lib/gui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/gui/__init__.py -------------------------------------------------------------------------------- /renderthreads/lib/gui/renderthreads_dock_widget.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | renderthreads_dock_widget 4 | ========================================== 5 | 6 | Subclass of QDockWidget to provide ability for custom type checks. 7 | """ 8 | 9 | 10 | # Import 11 | # ------------------------------------------------------------------ 12 | # python 13 | import logging 14 | # PySide 15 | from PySide import QtGui 16 | from PySide import QtCore 17 | 18 | 19 | # Import variable 20 | do_reload = True 21 | 22 | 23 | # renderthreads 24 | 25 | # lib 26 | 27 | # renderthreads_logging 28 | from .. import renderthreads_logging 29 | if(do_reload): 30 | reload(renderthreads_logging) 31 | 32 | # lib.gui 33 | 34 | # renderthreads_stylesheets 35 | import renderthreads_stylesheets 36 | if(do_reload): 37 | reload(renderthreads_stylesheets) 38 | 39 | 40 | # Globals 41 | # ------------------------------------------------------------------ 42 | 43 | 44 | # RenderThreadsDockWidget class 45 | # ------------------------------------------------------------------ 46 | class RenderThreadsDockWidget(QtGui.QDockWidget): 47 | """ 48 | Subclass of QWidget to allow for custom styling and 49 | type checking. 50 | """ 51 | 52 | # Signals 53 | # ------------------------------------------------------------------ 54 | 55 | # Create and initialize 56 | # ------------------------------------------------------------------ 57 | def __new__(cls, *args, **kwargs): 58 | """ 59 | RenderThreadsDockWidget instance factory. 60 | """ 61 | 62 | # renderthreads_dock_widget_instance 63 | renderthreads_dock_widget_instance = super(RenderThreadsDockWidget, cls).__new__(cls, args, kwargs) 64 | 65 | return renderthreads_dock_widget_instance 66 | 67 | def __init__(self, 68 | parent=None): 69 | """ 70 | RenderThreadsDockWidget instance customization. 71 | """ 72 | 73 | # parent_class 74 | self.parent_class = super(RenderThreadsDockWidget, self) 75 | self.parent_class.__init__(parent) 76 | 77 | # objectName 78 | self.setObjectName(self.__class__.__name__) 79 | 80 | # instance variables 81 | # ------------------------------------------------------------------ 82 | 83 | # logger 84 | self.logger = renderthreads_logging.get_logger(self.__class__.__name__) 85 | 86 | # Init procedure 87 | # ------------------------------------------------------------------ 88 | 89 | # setup_ui 90 | self.setup_ui() 91 | 92 | # connect_ui 93 | self.connect_ui() 94 | 95 | # style_ui 96 | self.style_ui() 97 | 98 | # UI setup methods 99 | # ------------------------------------------------------------------ 100 | 101 | def setup_ui(self): 102 | """ 103 | Setup UI. 104 | """ 105 | 106 | pass 107 | 108 | def connect_ui(self): 109 | """ 110 | Connect UI widgets with slots or functions. 111 | """ 112 | 113 | pass 114 | 115 | def style_ui(self): 116 | """ 117 | Style UI widgets. 118 | """ 119 | 120 | # set_stylesheet 121 | self.setStyleSheet(renderthreads_stylesheets.get_stylesheet()) 122 | 123 | # Events 124 | # ------------------------------------------------------------------ 125 | 126 | def closeEvent(self, event): 127 | """ 128 | Customized closeEvent 129 | """ 130 | 131 | # log 132 | self.logger.debug('Close Event') 133 | 134 | try: 135 | 136 | # stop_all_threads_and_timer 137 | self.widget().stop_all_threads_and_timer() 138 | 139 | except: 140 | 141 | # log 142 | self.logger.debug('Error stopping threads and timers for widget().') 143 | 144 | # parent close event 145 | self.parent_class.closeEvent(event) 146 | -------------------------------------------------------------------------------- /renderthreads/lib/gui/renderthreads_gui_helper.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads_gui_helper 5 | ========================================== 6 | 7 | This module encapsulates global ui related 8 | helper functions. 9 | """ 10 | 11 | 12 | # Import 13 | # ------------------------------------------------------------------ 14 | # Python 15 | import os 16 | import logging 17 | import webbrowser 18 | # PySide 19 | from PySide import QtGui 20 | from PySide import QtCore 21 | 22 | 23 | # Import variable 24 | do_reload = True 25 | 26 | # renderthreads 27 | 28 | # lib 29 | 30 | # renderthreads_globals 31 | from .. import renderthreads_globals 32 | if(do_reload): 33 | reload(renderthreads_globals) 34 | 35 | # renderthreads_logging 36 | from .. import renderthreads_logging 37 | if(do_reload): 38 | reload(renderthreads_logging) 39 | 40 | # lib.gui 41 | 42 | # renderthreads_dock_widget 43 | from ..gui import renderthreads_dock_widget 44 | if(do_reload): 45 | reload(renderthreads_dock_widget) 46 | 47 | 48 | # Globals 49 | # ------------------------------------------------------------------ 50 | # Pathes 51 | THIRD_PARTY_PATH = renderthreads_globals.THIRD_PARTY_PATH 52 | 53 | 54 | # logger (Module Level) 55 | # ------------------------------------------------------------------ 56 | logger = renderthreads_logging.get_logger(__name__) 57 | 58 | 59 | # Cleanup 60 | # ------------------------------------------------------------------ 61 | def get_widget_by_class_name_closure(wdgt_class_name): 62 | """ 63 | Practicing closures. Doesnt really make sense here, or could at least 64 | be done much simpler/better. 65 | Want to try it with filter in order to get more into the builtins. 66 | """ 67 | 68 | def get_widget_by_class_name(wdgt): 69 | """ 70 | Function that is closed in. Accepts and checks all 71 | widgets against wdgt_class_name from enclosing function. 72 | All this mess to be able to use it with filter. 73 | """ 74 | try: 75 | if (type(wdgt).__name__ == wdgt_class_name): 76 | return True 77 | except: 78 | pass 79 | return False 80 | 81 | return get_widget_by_class_name 82 | 83 | 84 | def get_widget_by_name_closure(wdgt_name): 85 | """ 86 | Practicing closures. Doesnt really make sense here, or could at least 87 | be done much simpler/better. 88 | Want to try it with filter in order to get more into the builtins. 89 | """ 90 | 91 | def get_widget_by_name(wdgt): 92 | """ 93 | Function that is closed in. Accepts and checks all 94 | widgets against wdgt_name from enclosing function. 95 | ALl this mess to be able to use it with filter. 96 | """ 97 | try: 98 | if (wdgt.objectName() == wdgt_name): 99 | return True 100 | except: 101 | pass 102 | return False 103 | 104 | return get_widget_by_name 105 | 106 | 107 | def check_and_delete_wdgt_instances_with_class_name(wdgt_class_name): 108 | """ 109 | Search for all occurences with wdgt_class_name and delete them. 110 | """ 111 | 112 | # get_wdgt_closure 113 | get_wdgt_closure = get_widget_by_class_name_closure(wdgt_class_name) 114 | 115 | # wdgt_list 116 | wdgt_list = filter(get_wdgt_closure, QtGui.QApplication.allWidgets()) 117 | 118 | # iterate and delete 119 | for index, wdgt in enumerate(wdgt_list): 120 | 121 | # Enable when threads are in. 122 | # try to stop threads 123 | try: 124 | wdgt.stop_all_threads_and_timer() 125 | logger.debug('Stopped threads for wdgt {0}'.format(wdgt.objectName())) 126 | except: 127 | pass 128 | 129 | # schedule widget for deletion 130 | try: 131 | # log 132 | logger.debug('Scheduled widget {0} for deletion'.format(wdgt.objectName())) 133 | # delete 134 | wdgt.deleteLater() 135 | except: 136 | pass 137 | 138 | return wdgt_list 139 | 140 | 141 | def check_and_delete_wdgt_instances_with_name(wdgt_name): 142 | """ 143 | Search for all occurences with wdgt_name and delete them. 144 | """ 145 | 146 | # get_wdgt_closure 147 | get_wdgt_closure = get_widget_by_name_closure(wdgt_name) 148 | 149 | # wdgt_list 150 | wdgt_list = filter(get_wdgt_closure, QtGui.QApplication.allWidgets()) 151 | 152 | # iterate and delete 153 | for index, wdgt in enumerate(wdgt_list): 154 | 155 | # schedule widget for deletion 156 | try: 157 | # log 158 | logger.debug('Scheduled widget {0} for deletion'.format(wdgt.objectName())) 159 | # delete 160 | wdgt.deleteLater() 161 | except: 162 | pass 163 | 164 | return wdgt_list 165 | 166 | 167 | # Organize and Compile 168 | # ------------------------------------------------------------------ 169 | def load_ui_type(ui_file): 170 | """ 171 | Pyside lacks the "loadUiType" command, so we have to convert the ui file to py code in-memory first 172 | and then execute it in a special frame to retrieve the form_class. 173 | This function return the form and base classes for the given qtdesigner ui file. 174 | """ 175 | 176 | # add path for pysideuic 177 | import sys 178 | sys.path.append(THIRD_PARTY_PATH) 179 | 180 | # lazy import 181 | 182 | try: 183 | # python 184 | import os 185 | import logging 186 | import re 187 | import shutil 188 | from cStringIO import StringIO 189 | import xml.etree.ElementTree as xml 190 | import types 191 | # PySide 192 | from PySide import QtGui 193 | from PySide import QtCore 194 | from PySide import QtUiTools 195 | import pysideuic 196 | 197 | except Exception as exception_instance: 198 | # log 199 | logger.debug('Import failed: {0}'.format(exception_instance)) 200 | # return None 201 | return None 202 | 203 | # compile ui 204 | 205 | parsed = xml.parse(ui_file) 206 | widget_class = parsed.find('widget').get('class') 207 | form_class = parsed.find('class').text 208 | 209 | with open(ui_file, 'r') as f: 210 | o = StringIO() 211 | frame = {} 212 | 213 | pysideuic.compileUi(f, o, indent=0) 214 | pyc = compile(o.getvalue(), '', 'exec') 215 | exec pyc in frame 216 | 217 | # Fetch the base_class and form class based on their type in the xml from designer 218 | form_class = frame['Ui_%s' % form_class] 219 | base_class = eval('QtGui.%s' % widget_class) 220 | 221 | return form_class, base_class 222 | 223 | 224 | def get_nuke_main_window(): 225 | """ 226 | Return the Maya main window. 227 | """ 228 | 229 | try: 230 | # PySide 231 | from PySide import QtGui 232 | from PySide import QtCore 233 | 234 | except Exception as exception_instance: 235 | 236 | # log 237 | logger.debug('Import failed: {0}'.format(exception_instance)) 238 | # return None 239 | return None 240 | 241 | # ptr_main_window 242 | ptr_main_window = QtGui.QApplication.activeWindow() 243 | 244 | # if True 245 | if (ptr_main_window): 246 | return ptr_main_window 247 | 248 | return None 249 | 250 | 251 | # Style 252 | # ------------------------------------------------------------------ 253 | def correct_styled_background_attribute(wdgt): 254 | """ 255 | Set QtCore.Qt.WA_StyledBackground True for all widgets. 256 | Without this attr. set, the background-color stylesheet 257 | will have no effect on QWidgets. This should replace the 258 | need for palette settings. 259 | ToDo: 260 | Maybe add exclude list when needed. 261 | """ 262 | 263 | # wdgt_list 264 | wdgt_list = wdgt.findChildren(QtGui.QWidget) # Return several types ?!?! 265 | 266 | # iterate and set 267 | for wdgt in wdgt_list: 268 | 269 | # check type 270 | if(type(wdgt) is QtGui.QWidget): 271 | 272 | # styled_background 273 | wdgt.setAttribute(QtCore.Qt.WA_StyledBackground, True) 274 | 275 | 276 | def set_margins_and_spacing_for_child_layouts(wdgt, margin_list=[0, 0, 0, 0]): 277 | """ 278 | Eliminate margin and spacing for all layout widgets. 279 | """ 280 | 281 | # lyt_classes_list 282 | lyt_classes_list = [QtGui.QStackedLayout, QtGui.QGridLayout, QtGui.QFormLayout, 283 | QtGui.QBoxLayout, QtGui.QVBoxLayout, QtGui.QHBoxLayout, QtGui.QBoxLayout] 284 | 285 | # lyt_list 286 | lyt_list = [] 287 | for lyt_class in lyt_classes_list: 288 | lyt_list += [child_wdgt for child_wdgt in wdgt.findChildren(lyt_class)] 289 | 290 | # set margin and spacing 291 | for lyt in lyt_list: 292 | 293 | # check type 294 | if(type(lyt) in lyt_classes_list): 295 | 296 | # set 297 | lyt.setContentsMargins(*margin_list) 298 | lyt.setSpacing(0) 299 | 300 | 301 | def insert_spacer_widget(wdgt_or_lyt, minimum_width=0, minimum_height=0, parent=None): 302 | """ 303 | Insert spacer widget into layout with given min width 304 | and min height. 305 | """ 306 | 307 | # lyt 308 | lyt = wdgt_or_lyt 309 | 310 | # not instance of layout 311 | if not (isinstance(lyt, QtGui.QLayout)): 312 | 313 | # lyt 314 | lyt = wdgt_or_lyt.layout() 315 | 316 | # wdgt_spacer 317 | wdgt_spacer = QtGui.QWidget(parent=parent) 318 | wdgt_spacer.setMinimumWidth(minimum_width) 319 | wdgt_spacer.setMinimumHeight(minimum_height) 320 | 321 | # add to lyt 322 | lyt.addWidget(wdgt_spacer) 323 | 324 | 325 | def prepare_string_for_word_wrap(string_to_prepare, steps=20): 326 | """ 327 | Insert spaces into string at steps 328 | to make sure word wrap has an effect. 329 | This aids the display of long, continous 330 | strings in widgets with word-wrap enabled. 331 | """ 332 | 333 | # string_to_prepare_broken 334 | string_to_prepare_broken = '' 335 | 336 | # step_count 337 | step_count = 0 338 | 339 | # iterate 340 | for char in string_to_prepare: 341 | 342 | # char is whitespace 343 | if (char == ' '): 344 | 345 | # reset step_count 346 | step_count = 0 347 | 348 | # else 349 | else: 350 | 351 | # check step_count 352 | if (step_count > steps): 353 | 354 | # insert space 355 | char = ' {0}'.format(char) 356 | 357 | # reset step_count 358 | step_count = 0 359 | 360 | # else 361 | else: 362 | 363 | # increment step_count 364 | step_count += 1 365 | 366 | # append 367 | string_to_prepare_broken += char 368 | 369 | # return 370 | return string_to_prepare_broken 371 | 372 | 373 | # Docking 374 | # ------------------------------------------------------------------ 375 | def make_dockable(wdgt): 376 | """ 377 | Make this wdgt dockable. 378 | """ 379 | 380 | # nuke_main_window 381 | nuke_main_window = get_nuke_main_window() 382 | 383 | # q_main_window_list 384 | q_main_window_list = nuke_main_window.findChildren(QtGui.QMainWindow) 385 | # check 386 | if not (q_main_window_list): 387 | # log 388 | logger.debug('Current Nuke configuration has no QMainWindow instance which is needed for docking\ 389 | Not performing dock behaviour.') 390 | return 391 | 392 | # q_main_window 393 | q_main_window = q_main_window_list[0] 394 | 395 | # wdgt_dock 396 | wdgt_dock = renderthreads_dock_widget.RenderThreadsDockWidget(parent=q_main_window) 397 | wdgt_dock.setAllowedAreas(QtCore.Qt.AllDockWidgetAreas) 398 | 399 | # set wdgt 400 | wdgt_dock.setWidget(wdgt) 401 | 402 | # add to maya main window 403 | q_main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, wdgt_dock) 404 | 405 | 406 | # File/Directory picking 407 | # ------------------------------------------------------------------ 408 | 409 | def pick_file(wdgt_display=None, filter_string=None): 410 | """ 411 | Pick a file and display it on wdgt_display 412 | if set. 413 | """ 414 | 415 | # file_path 416 | file_path, selected_filter = QtGui.QFileDialog.getOpenFileName(filter=filter_string) 417 | file_path = str(file_path) 418 | 419 | # check 420 | if not (file_path): 421 | # log 422 | logger.debug('File path invalid. Returning None.') 423 | return None 424 | 425 | # absolute path 426 | file_path = os.path.abspath(file_path).replace('\\', '/') 427 | 428 | # wdgt_display 429 | if (wdgt_display): 430 | 431 | # setText() 432 | if (type(wdgt_display) is QtGui.QLineEdit or 433 | type(wdgt_display) is QtGui.QLabel): 434 | 435 | # set 436 | wdgt_display.setText(file_path) 437 | 438 | # unknown 439 | else: 440 | 441 | # log 442 | logger.debug('wdgt_display type {0} is unknown. File path cannot be set.'.format(type(wdgt_display))) 443 | 444 | # log 445 | logger.debug('{0}'.format(file_path)) 446 | 447 | # return 448 | return file_path 449 | 450 | 451 | # Web 452 | # ------------------------------------------------------------------ 453 | def open_website(url, new=2): 454 | """ 455 | Wrapper around webbrowser.open(). 456 | """ 457 | 458 | try: 459 | # open 460 | webbrowser.open(url, new) 461 | except: 462 | # log 463 | logger.error('Error opening {0}'.format(url)) 464 | -------------------------------------------------------------------------------- /renderthreads/lib/gui/renderthreads_progressbar.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | renderthreads_progressbar 4 | ========================================== 5 | 6 | Subclass of QProgressBar to provide ability for custom type checks 7 | and events. 8 | """ 9 | 10 | 11 | # Import 12 | # ------------------------------------------------------------------ 13 | # python 14 | import logging 15 | # PySide 16 | from PySide import QtGui 17 | from PySide import QtCore 18 | 19 | 20 | # Import variable 21 | do_reload = True 22 | 23 | 24 | # renderthreads 25 | 26 | # lib 27 | 28 | # renderthreads_globals 29 | from .. import renderthreads_globals 30 | if(do_reload): 31 | reload(renderthreads_globals) 32 | 33 | # renderthreads_logging 34 | from .. import renderthreads_logging 35 | if(do_reload): 36 | reload(renderthreads_logging) 37 | 38 | 39 | # Globals 40 | # ------------------------------------------------------------------ 41 | # Colors 42 | BLUE = renderthreads_globals.BLUE 43 | 44 | 45 | # RenderThreadsProgressBar class 46 | # ------------------------------------------------------------------ 47 | class RenderThreadsProgressBar(QtGui.QProgressBar): 48 | """ 49 | Subclass of QProgressBar to provide ability for 50 | custom type checks and events. 51 | """ 52 | 53 | # Signals 54 | # ------------------------------------------------------------------ 55 | 56 | # Create and initialize 57 | # ------------------------------------------------------------------ 58 | def __new__(cls, *args, **kwargs): 59 | """ 60 | RenderThreadsProgressBar instance factory. 61 | """ 62 | 63 | # renderthreads_progressbar_instance 64 | renderthreads_progressbar_instance = super(RenderThreadsProgressBar, cls).__new__(cls, args, kwargs) 65 | 66 | return renderthreads_progressbar_instance 67 | 68 | def __init__(self, 69 | parent=None): 70 | """ 71 | RenderThreadsProgressBar instance customization. 72 | """ 73 | 74 | # parent_class 75 | self.parent_class = super(RenderThreadsProgressBar, self) 76 | self.parent_class.__init__(parent) 77 | 78 | # objectName 79 | self.setObjectName(self.__class__.__name__) 80 | 81 | # instance variables 82 | # ------------------------------------------------------------------ 83 | 84 | # logger 85 | self.logger = renderthreads_logging.get_logger(self.__class__.__name__) 86 | 87 | # Init procedure 88 | # ------------------------------------------------------------------ 89 | 90 | # setup_ui 91 | self.setup_ui() 92 | 93 | # connect_ui 94 | self.connect_ui() 95 | 96 | # style_ui 97 | self.style_ui() 98 | 99 | # UI setup methods 100 | # ------------------------------------------------------------------ 101 | 102 | def setup_ui(self): 103 | """ 104 | Setup UI. 105 | """ 106 | 107 | pass 108 | 109 | def connect_ui(self): 110 | """ 111 | Connect UI widgets with slots or functions. 112 | """ 113 | 114 | pass 115 | 116 | def style_ui(self): 117 | """ 118 | Style UI widgets. 119 | """ 120 | 121 | pass 122 | 123 | # Slots 124 | # ------------------------------------------------------------------ 125 | @QtCore.Slot(int) 126 | def increment_range(self, step=1): 127 | """ 128 | Increment range by step. 129 | """ 130 | 131 | # set 132 | self.setMaximum(self.maximum() + step) 133 | 134 | @QtCore.Slot(int) 135 | def increment_value(self, step=1): 136 | """ 137 | Increment value by step. 138 | """ 139 | 140 | # new_value 141 | new_value = self.value() + step 142 | 143 | # if new value == maximum - 1 144 | if (new_value >= (self.maximum() - 1)): 145 | 146 | # set 147 | self.setValue(0) 148 | # reset 149 | self.setRange(0, 1) 150 | 151 | # else increment 152 | else: 153 | 154 | # set 155 | self.setValue(new_value) 156 | 157 | # Events 158 | # ------------------------------------------------------------------ 159 | def closeEvent(self, event): 160 | """ 161 | Customized closeEvent 162 | """ 163 | 164 | # parent close event 165 | self.parent_class.closeEvent(event) 166 | 167 | def paintEvent(self, event): 168 | """ 169 | Customized paintEvent to display complete 170 | job count. 171 | """ 172 | 173 | # parent class paint event 174 | self.parent_class.paintEvent(event) 175 | 176 | # painter 177 | painter = QtGui.QPainter(self) 178 | 179 | # painter 180 | painter.setPen(QtGui.QColor(BLUE)) 181 | 182 | # font 183 | font = QtGui.QFont() 184 | font.setBold(True) 185 | painter.setFont(font) 186 | 187 | # job_count 188 | job_count = 'jobs: {0}'.format(self.maximum() - 1) 189 | 190 | # drawText 191 | painter.drawText(self.rect(), QtCore.Qt.AlignRight, job_count) 192 | -------------------------------------------------------------------------------- /renderthreads/lib/gui/renderthreads_signal_remapper.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads_signal_remapper 5 | ========================================== 6 | 7 | This module encapsulates a handy signal remapper 8 | widget specific to the renderthreads tool. 9 | SignalRemapper remaps signals with from input 10 | ranges or values to the needed signals or values. 11 | """ 12 | 13 | 14 | # Import 15 | # ------------------------------------------------------------------ 16 | # Python 17 | import os 18 | import logging 19 | # PySide 20 | from PySide import QtGui 21 | from PySide import QtCore 22 | 23 | 24 | # Import variable 25 | do_reload = True 26 | 27 | # renderthreads 28 | 29 | # lib 30 | 31 | # renderthreads_globals 32 | from .. import renderthreads_globals 33 | if(do_reload): 34 | reload(renderthreads_globals) 35 | 36 | # renderthreads_logging 37 | from .. import renderthreads_logging 38 | if(do_reload): 39 | reload(renderthreads_logging) 40 | 41 | 42 | # Globals 43 | # ------------------------------------------------------------------ 44 | 45 | 46 | # SignalRemapper 47 | # ------------------------------------------------------------------ 48 | class SignalRemapper(QtCore.QObject): 49 | """ 50 | Simple class that remaps signals from 51 | input widgets whose values dont match 52 | the needed format. 53 | For example it remaps the logging 54 | slider signal from a range of 1-5 55 | to the real logging constant values. 56 | (DEBUG, INFO etc.) 57 | """ 58 | 59 | # Signals 60 | # ------------------------------------------------------------------ 61 | sgnl_set_logging = QtCore.Signal(int) 62 | 63 | # Creation and Initialization 64 | # ------------------------------------------------------------------ 65 | def __new__(cls, *args, **kwargs): 66 | """ 67 | SignalRemapper instance factory. 68 | """ 69 | 70 | # signal_remapper_instance 71 | signal_remapper_instance = super(SignalRemapper, cls).__new__(cls, args, kwargs) 72 | 73 | return signal_remapper_instance 74 | 75 | def __init__(self): 76 | """ 77 | Customize instance. 78 | """ 79 | 80 | # super and objectName 81 | # ------------------------------------------------------------------ 82 | # parent_class 83 | self.parent_class = super(SignalRemapper, self) 84 | self.parent_class.__init__() 85 | 86 | self.setObjectName(self.__class__.__name__) 87 | 88 | # instance variables 89 | # ------------------------------------------------------------------ 90 | # logger 91 | self.logger = renderthreads_logging.get_logger(self.__class__.__name__) 92 | 93 | # Slots 94 | # ------------------------------------------------------------------ 95 | 96 | @QtCore.Slot(int) 97 | def remap_logging(self, value): 98 | """ 99 | Remap for logging. 100 | """ 101 | 102 | # emit 103 | self.sgnl_set_logging.emit(value * 10) 104 | -------------------------------------------------------------------------------- /renderthreads/lib/gui/renderthreads_slider_widget.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | renderthreads_slider_widget 4 | ========================================== 5 | 6 | Widget that offers a label used as header and a slider 7 | with signals and slots. 8 | """ 9 | 10 | # Import 11 | # ------------------------------------------------------------------ 12 | # python 13 | import logging 14 | # PySide 15 | from PySide import QtGui 16 | from PySide import QtCore 17 | 18 | 19 | # Import variable 20 | do_reload = True 21 | 22 | 23 | # renderthreads 24 | 25 | # lib 26 | 27 | # renderthreads_globals 28 | from .. import renderthreads_globals 29 | if(do_reload): 30 | reload(renderthreads_globals) 31 | 32 | # renderthreads_logging 33 | from .. import renderthreads_logging 34 | if(do_reload): 35 | reload(renderthreads_logging) 36 | 37 | # lib.gui 38 | 39 | # renderthreads_gui_helper 40 | import renderthreads_gui_helper 41 | if(do_reload): 42 | reload(renderthreads_gui_helper) 43 | 44 | 45 | # Globals 46 | # ------------------------------------------------------------------ 47 | 48 | 49 | # Slider 50 | # ------------------------------------------------------------------ 51 | class Slider(QtGui.QWidget): 52 | """ 53 | Widget that offers a label used as header and a slider 54 | with signals and slots. 55 | """ 56 | 57 | # Signals 58 | # ------------------------------------------------------------------ 59 | value_changed = QtCore.Signal(int) 60 | 61 | # Create and initialize 62 | # ------------------------------------------------------------------ 63 | def __new__(cls, *args, **kwargs): 64 | """ 65 | Slider instance factory. 66 | """ 67 | 68 | # slider_instance 69 | slider_instance = super(Slider, cls).__new__(cls, args, kwargs) 70 | 71 | return slider_instance 72 | 73 | def __init__(self, 74 | header='Slider', 75 | minimum=0, 76 | maximum=99, 77 | initial_value=50, 78 | tracking=True, 79 | parent=None): 80 | """ 81 | Slider instance customization. 82 | """ 83 | 84 | # super and objectName 85 | # ------------------------------------------------------------------ 86 | # parent_class 87 | self.parent_class = super(Slider, self) 88 | # super class constructor 89 | self.parent_class.__init__(parent) 90 | 91 | # objectName 92 | self.setObjectName(self.__class__.__name__) 93 | 94 | # instance variables 95 | # ------------------------------------------------------------------ 96 | # initial_value 97 | self.initial_value = initial_value 98 | # minimum 99 | self.minimum = minimum 100 | # maximum 101 | self.maximum = maximum 102 | # header 103 | self.header = header 104 | # tracking 105 | self.tracking = tracking 106 | 107 | # wdgt_spinbox_complete 108 | self.wdgt_spinbox_complete = None 109 | 110 | # logger 111 | self.logger = renderthreads_logging.get_logger(self.__class__.__name__) 112 | 113 | # Init procedure 114 | # ------------------------------------------------------------------ 115 | # setup_ui 116 | self.setup_ui() 117 | 118 | # connect_ui 119 | self.connect_ui() 120 | 121 | # style_ui 122 | self.style_ui() 123 | 124 | # UI setup methods 125 | # ------------------------------------------------------------------ 126 | def setup_ui(self): 127 | """ 128 | Setup additional UI. 129 | """ 130 | 131 | # lyt_slider 132 | self.lyt_slider = QtGui.QVBoxLayout(self) 133 | 134 | # lbl_slider 135 | self.lbl_slider = QtGui.QLabel(text=self.header) 136 | self.lbl_slider.setObjectName(self.__class__.__name__ + type(self.lbl_slider).__name__) 137 | self.lyt_slider.addWidget(self.lbl_slider) 138 | 139 | # wdgt_slider_and_display 140 | self.wdgt_slider_and_display = QtGui.QWidget() 141 | self.lyt_slider.addWidget(self.wdgt_slider_and_display) 142 | 143 | # lyt_wdgt_slider_and_display 144 | self.lyt_wdgt_slider_and_display = QtGui.QHBoxLayout(self.wdgt_slider_and_display) 145 | 146 | # slider 147 | self.slider = QtGui.QSlider() 148 | self.slider.setObjectName(self.__class__.__name__ + 149 | type(self.slider).__name__) 150 | self.slider.setOrientation(QtCore.Qt.Horizontal) 151 | self.slider.setRange(self.minimum, self.maximum) 152 | self.slider.setValue(self.initial_value) 153 | self.slider.setTracking(self.tracking) 154 | self.lyt_wdgt_slider_and_display.addWidget(self.slider) 155 | 156 | # lcd_slider_value 157 | self.lcd_slider_value = QtGui.QLCDNumber() 158 | self.lcd_slider_value.display(self.initial_value) 159 | self.lyt_wdgt_slider_and_display.addWidget(self.lcd_slider_value) 160 | 161 | def connect_ui(self): 162 | """ 163 | Connect UI widgets with slots or functions. 164 | """ 165 | 166 | # slider 167 | self.slider.valueChanged.connect(self.on_value_changed) 168 | 169 | def style_ui(self): 170 | """ 171 | Setup tool palette, tool stylesheet and specific widget stylesheets. 172 | """ 173 | 174 | # correct_styled_background_attribute 175 | renderthreads_gui_helper.correct_styled_background_attribute(self) 176 | 177 | # set_margins_and_spacing_for_child_layouts 178 | renderthreads_gui_helper.set_margins_and_spacing_for_child_layouts(self) 179 | 180 | # Getter and Setter 181 | # ------------------------------------------------------------------ 182 | def set_tick_position(self, position): 183 | """ 184 | Set Tick position and appearance on slider. 185 | Tick visibility is off by default. 186 | """ 187 | 188 | self.slider.setTickPosition(position) 189 | 190 | def set_tick_interval(self, value): 191 | """ 192 | Set Tick interval value. This has no implications 193 | on the slider steps. 194 | """ 195 | 196 | self.slider.setTickInterval(value) 197 | 198 | def get_value(self): 199 | """ 200 | Return self.slider.value(). 201 | """ 202 | 203 | return self.slider.value() 204 | 205 | # Slots 206 | # ------------------------------------------------------------------ 207 | @QtCore.Slot(int) 208 | def on_value_changed(self, value): 209 | """ 210 | Value of spinbox changed. 211 | """ 212 | 213 | # change display 214 | self.lcd_slider_value.display(value) 215 | 216 | # emit value_changed 217 | self.value_changed.emit(value) 218 | -------------------------------------------------------------------------------- /renderthreads/lib/mvc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/mvc/__init__.py -------------------------------------------------------------------------------- /renderthreads/lib/mvc/renderthreads_item_delegate.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | renderthreads_item_delegate 4 | ========================================== 5 | 6 | Subclass of QStyledItemDelegate to format view 7 | """ 8 | 9 | 10 | # Import 11 | # ------------------------------------------------------------------ 12 | # python 13 | import logging 14 | # PySide 15 | from PySide import QtGui 16 | from PySide import QtCore 17 | # nuke 18 | import nuke 19 | 20 | # Import variable 21 | do_reload = True 22 | 23 | 24 | # renderthreads 25 | 26 | # lib 27 | 28 | # renderthreads_globals 29 | from .. import renderthreads_globals 30 | if(do_reload): 31 | reload(renderthreads_globals) 32 | 33 | # renderthreads_logging 34 | from .. import renderthreads_logging 35 | if(do_reload): 36 | reload(renderthreads_logging) 37 | 38 | # lib.gui 39 | 40 | # renderthreads_progressbar 41 | from ..gui import renderthreads_progressbar 42 | if(do_reload): 43 | reload(renderthreads_progressbar) 44 | 45 | 46 | # Globals 47 | # ------------------------------------------------------------------ 48 | # Colors 49 | BLACK = renderthreads_globals.BLACK 50 | RED = renderthreads_globals.RED 51 | BLUE = renderthreads_globals.BLUE 52 | 53 | 54 | # RenderThreadsItemDelegate 55 | # ------------------------------------------------------------------ 56 | class RenderThreadsItemDelegate(QtGui.QStyledItemDelegate): 57 | """ 58 | Subclass of QStyledItemDelegate. 59 | """ 60 | 61 | # Creation and Initialization 62 | # ------------------------------------------------------------------ 63 | def __new__(cls, *args, **kwargs): 64 | """ 65 | RenderThreadsItemDelegate instance factory. 66 | """ 67 | 68 | # renderthreads_item_delegate_instance 69 | renderthreads_item_delegate_instance = super(RenderThreadsItemDelegate, cls).__new__(cls, args, kwargs) 70 | 71 | return renderthreads_item_delegate_instance 72 | 73 | def __init__(self, 74 | parent=None): 75 | """ 76 | Customize instance. 77 | """ 78 | 79 | # super and objectName 80 | # ------------------------------------------------------------------ 81 | # parent_class 82 | self.parent_class = super(RenderThreadsItemDelegate, self) 83 | self.parent_class.__init__(parent=parent) 84 | 85 | # setObjectName 86 | self.setObjectName(self.__class__.__name__) 87 | 88 | # instance variables 89 | # ------------------------------------------------------------------ 90 | # logger 91 | self.logger = renderthreads_logging.get_logger(self.__class__.__name__) 92 | 93 | # Size Hint 94 | # ------------------------------------------------------------------ 95 | def sizeHint(self, option, index): 96 | """ 97 | Returns the size for a type a certain index represents. 98 | ----------------------- 99 | 100 | Types handled: 101 | #. Lists 102 | #. nuke.Node 103 | """ 104 | 105 | # index invalid 106 | if not(index.isValid()): 107 | 108 | # parent_class sizeHint 109 | return self.parent_class.sizeHint(option, index) 110 | 111 | # data 112 | data = index.data(QtCore.Qt.DisplayRole) 113 | 114 | # row & col 115 | row = index.row() 116 | col = index.column() 117 | 118 | # check types 119 | 120 | # list 121 | if(type(data) is list): 122 | 123 | # value_string 124 | value_string = '' 125 | for index, value in enumerate(data): 126 | 127 | # last value 128 | if(index == len(data) - 1): 129 | value_string += str(value) 130 | continue 131 | 132 | # append 133 | value_string += str(value + ';\n') 134 | 135 | # text_size 136 | q_font_metrics = QtGui.QFontMetrics(QtGui.QApplication.font()) 137 | text_size = q_font_metrics.size(0, value_string) 138 | return text_size 139 | 140 | # nuke.Node 141 | elif(type(data) is nuke.Node): 142 | 143 | # value_string 144 | value_string = data.fullName() 145 | 146 | # text_size 147 | q_font_metrics = QtGui.QFontMetrics(QtGui.QApplication.font()) 148 | text_size = q_font_metrics.size(0, value_string) 149 | return text_size 150 | 151 | # other type 152 | else: 153 | 154 | # parent_class sizeHint 155 | return self.parent_class.sizeHint(option, index) 156 | 157 | # Paint 158 | # ------------------------------------------------------------------ 159 | def paint(self, painter, option, index): 160 | """ 161 | Define the look of the current item based on its type. 162 | ----------------------- 163 | 164 | Types handled: 165 | #. Lists 166 | #. nuke.Node 167 | """ 168 | 169 | # index invalid 170 | if not(index.isValid()): 171 | 172 | # parent_class paint 173 | self.parent_class.paint(painter, option, index) 174 | return 175 | 176 | # data 177 | data = index.data(QtCore.Qt.DisplayRole) 178 | 179 | # row & col 180 | row = index.row() 181 | col = index.column() 182 | 183 | # list 184 | if(type(data) is list): 185 | 186 | # paint_list_as_string_with_lines 187 | self.paint_list_as_string_with_lines(painter, option, data) 188 | 189 | # nuke.Node 190 | elif(type(data) is nuke.Node): 191 | 192 | # paint_nuke_node 193 | self.paint_nuke_node(painter, option, data) 194 | 195 | # renderthreads_progressbar.RenderThreadsProgressBar 196 | elif(type(data) is renderthreads_progressbar.RenderThreadsProgressBar): 197 | 198 | # paint_renderthreads_progressbar 199 | self.paint_renderthreads_progressbar(painter, option, data) 200 | 201 | # other type 202 | else: 203 | 204 | # parent_class paint 205 | self.parent_class.paint(painter, option, index) 206 | 207 | def paint_list_as_string_with_lines(self, painter, option, data): 208 | """ 209 | Paint list as string with a seperate 210 | line for each list entry. 211 | """ 212 | 213 | # save painter 214 | painter.save() 215 | 216 | # value_string 217 | value_string = '' 218 | for index, value in enumerate(data): 219 | 220 | # last value 221 | if(index == len(data) - 1): 222 | value_string += str(value) 223 | continue 224 | 225 | # append 226 | value_string += str(value + ';\n') 227 | 228 | # draw 229 | painter.drawText(option.rect, QtCore.Qt.AlignLeft, value_string) 230 | 231 | # restore painter 232 | painter.restore() 233 | 234 | def paint_nuke_node(self, painter, option, data): 235 | """ 236 | Paint nuke.Node as string 237 | consisting of nuke_node full name. 238 | """ 239 | 240 | # save painter 241 | painter.save() 242 | 243 | # value_string 244 | value_string = str(data.fullName()) 245 | 246 | # draw 247 | painter.drawText(option.rect, QtCore.Qt.AlignLeft, value_string) 248 | 249 | # restore painter 250 | painter.restore() 251 | 252 | def paint_renderthreads_progressbar(self, painter, option, data, custom=True): 253 | """ 254 | Paint renderthreads_progressbar.RenderThreadsProgressBar 255 | as QStyleOptionProgressBar in ui. 256 | """ 257 | 258 | # custom 259 | if (custom): 260 | 261 | # custom 262 | self.paint_renderthreads_progressbar_custom(painter, option, data) 263 | 264 | # else (style option): 265 | else: 266 | 267 | # style option 268 | self.paint_renderthreads_progressbar_style_option(painter, option, data) 269 | 270 | def paint_renderthreads_progressbar_custom(self, painter, option, data): 271 | """ 272 | Paint renderthreads_progressbar.RenderThreadsProgressBar 273 | as QStyleOptionProgressBar in ui. 274 | """ 275 | 276 | # save painter 277 | painter.save() 278 | 279 | # no pen 280 | painter.setPen(QtGui.QPen(QtCore.Qt.NoPen)) 281 | 282 | # draw background 283 | painter.setBrush(QtGui.QBrush(QtGui.QColor(QtCore.Qt.transparent))) 284 | painter.drawRect(option.rect) 285 | 286 | # maximum 287 | maximum = float(data.maximum()) 288 | # minimum 289 | minimum = float(data.minimum()) 290 | # value 291 | value = float(data.value()) 292 | 293 | # percent 294 | percent = float(0) 295 | if (value): 296 | percent = value / maximum 297 | 298 | # x, y, width, height 299 | x = option.rect.x() 300 | y = option.rect.y() 301 | width = float(option.rect.width()) 302 | height = option.rect.height() 303 | 304 | # rect_progress 305 | rect_progress = QtCore.QRectF(x, y, width * percent, height) 306 | 307 | # draw progress 308 | painter.setBrush(QtGui.QBrush(QtGui.QColor(RED))) 309 | painter.drawRect(rect_progress) 310 | 311 | # pen text progress 312 | painter.setPen(QtGui.QPen(QtGui.QColor(BLACK))) 313 | painter.drawText(option.rect, QtCore.Qt.AlignCenter, data.text()) 314 | 315 | # job_count 316 | job_count = '{0}'.format(data.maximum() - 1) 317 | 318 | # pen text job_count 319 | painter.setPen(QtGui.QPen(QtGui.QColor(BLUE))) 320 | painter.drawText(option.rect, QtCore.Qt.AlignRight, job_count) 321 | 322 | # restore painter 323 | painter.restore() 324 | 325 | def paint_renderthreads_progressbar_style_option(self, painter, option, data): 326 | """ 327 | Paint renderthreads_progressbar.RenderThreadsProgressBar 328 | as QStyleOptionProgressBar in ui. 329 | """ 330 | 331 | # maximum 332 | maximum = data.maximum() 333 | # minimum 334 | minimum = data.minimum() 335 | # value 336 | value = data.value() 337 | 338 | # progressbar_option 339 | progressbar_option = QtGui.QStyleOptionProgressBarV2() 340 | progressbar_option.rect = option.rect 341 | progressbar_option.minimum = 0 342 | progressbar_option.maximum = maximum 343 | progressbar_option.progress = value 344 | progressbar_option.text = '{0} %'.format(value) 345 | progressbar_option.textVisible = True 346 | 347 | # draw 348 | QtGui.QApplication.instance().style().drawControl(QtGui.QStyle.CE_ProgressBar, progressbar_option, painter) 349 | 350 | # Custom Editors 351 | # ------------------------------------------------------------------ 352 | def createEditor(self, parent, option, index): 353 | """ 354 | Virtual method of itemDelegate that creates an editor widget and returns 355 | it when EditRole requests it. 356 | """ 357 | 358 | # index invalid 359 | if not(index.isValid()): 360 | 361 | # parent_class setEditorData 362 | return self.parent_class.createEditor(parent, option, index) 363 | 364 | # row & col 365 | row = index.row() 366 | col = index.column() 367 | 368 | # nuke_node 369 | if(col == 0): 370 | 371 | # editor 372 | editor = QtGui.QLineEdit(parent=parent) 373 | return editor 374 | 375 | # other columns 376 | else: 377 | 378 | # parent_class setEditorData 379 | return self.parent_class.createEditor(parent, option, index) 380 | 381 | def setEditorData(self, editor, index): 382 | """ 383 | Virtual method of itemDelegate that sets the editor data after 384 | the editor is initialized. 385 | """ 386 | 387 | # index invalid 388 | if not(index.isValid()): 389 | 390 | # parent_class setEditorData 391 | return self.parent_class.setEditorData(editor, index) 392 | 393 | # data 394 | data = index.data(QtCore.Qt.DisplayRole) 395 | 396 | # row & col 397 | row = index.row() 398 | col = index.column() 399 | 400 | # nuke_node 401 | if(col == 0): 402 | 403 | # set 404 | editor.setText(str(data.name())) 405 | 406 | # other columns 407 | else: 408 | 409 | # evaluate in superclass 410 | self.parent_class.setEditorData(editor, index) 411 | 412 | def setModelData(self, editor, model, index): 413 | """ 414 | Set data into model. 415 | """ 416 | 417 | # index invalid 418 | if not(index.isValid()): 419 | 420 | # parent_class setModelData 421 | return self.parent_class.setModelData(editor, model, index) 422 | 423 | # row & col 424 | row = index.row() 425 | col = index.column() 426 | 427 | # nuke_node 428 | if(col == 0): 429 | 430 | # set 431 | model.setData(index, editor.text()) 432 | 433 | # other columns 434 | else: 435 | 436 | # parent_class setModelData 437 | self.parent_class.setModelData(editor, model, index) 438 | -------------------------------------------------------------------------------- /renderthreads/lib/mvc/renderthreads_view.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | renderthreads_view 4 | ========================================== 5 | 6 | Subclass of QTableView to display renderthread 7 | nodes. 8 | """ 9 | 10 | 11 | # Import 12 | # ------------------------------------------------------------------ 13 | # python 14 | import logging 15 | # PySide 16 | from PySide import QtGui 17 | from PySide import QtCore 18 | 19 | 20 | # Import variable 21 | do_reload = True 22 | 23 | 24 | # renderthreads 25 | 26 | # lib 27 | 28 | # renderthreads_globals 29 | from .. import renderthreads_globals 30 | if(do_reload): 31 | reload(renderthreads_globals) 32 | 33 | # renderthreads_logging 34 | from .. import renderthreads_logging 35 | if(do_reload): 36 | reload(renderthreads_logging) 37 | 38 | 39 | # RenderThreadsView 40 | # ------------------------------------------------------------------ 41 | class RenderThreadsView(QtGui.QTableView): 42 | """ 43 | Subclass of QTableView. 44 | """ 45 | 46 | def __new__(cls, *args, **kwargs): 47 | """ 48 | RenderThreadsView instance factory. 49 | """ 50 | 51 | # renderthreads_view_instance 52 | renderthreads_view_instance = super(RenderThreadsView, cls).__new__(cls, args, kwargs) 53 | 54 | return renderthreads_view_instance 55 | 56 | def __init__(self, 57 | parent=None): 58 | """ 59 | Customize instance. 60 | """ 61 | 62 | # super and objectName 63 | # ------------------------------------------------------------------ 64 | # parent_class 65 | self.parent_class = super(RenderThreadsView, self) 66 | self.parent_class.__init__(parent=parent) 67 | 68 | # setObjectName 69 | self.setObjectName(self.__class__.__name__) 70 | 71 | # instance variables 72 | # ------------------------------------------------------------------ 73 | # logger 74 | self.logger = renderthreads_logging.get_logger(self.__class__.__name__) 75 | -------------------------------------------------------------------------------- /renderthreads/lib/renderthreads_command_line_engine.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads_command_line_engine 5 | ========================================== 6 | 7 | This module handles the creation of the 8 | command line string used for rendering. 9 | """ 10 | 11 | 12 | # Import 13 | # ------------------------------------------------------------------ 14 | # Python 15 | import logging 16 | import functools 17 | import re 18 | 19 | 20 | # Import variable 21 | do_reload = True 22 | 23 | # renderthreads 24 | 25 | # lib 26 | 27 | # renderthreads_globals 28 | import renderthreads_globals 29 | if(do_reload): 30 | reload(renderthreads_globals) 31 | 32 | # renderthreads_logging 33 | import renderthreads_logging 34 | if(do_reload): 35 | reload(renderthreads_logging) 36 | 37 | 38 | # Globals 39 | # ------------------------------------------------------------------ 40 | WRITE_NODE_REPLACEMENT_TEMPLATE = renderthreads_globals.WRITE_NODE_REPLACEMENT_TEMPLATE 41 | 42 | 43 | # logger (Module Level) 44 | # ------------------------------------------------------------------ 45 | logger = renderthreads_logging.get_logger(__name__) 46 | 47 | 48 | # Command line engine 49 | # ------------------------------------------------------------------ 50 | def get_command_line_string(wdgt, 51 | renderthreads_node=None, 52 | frame=None): 53 | """ 54 | Convert given list of CommandLineFlag objects into 55 | a command line string that can be used for 56 | rendering. 57 | """ 58 | 59 | # script_path 60 | script_path = wdgt.le_script_path.text() 61 | # nuke_path 62 | nuke_path = wdgt.le_nuke_path.text() 63 | # flag_list 64 | flag_list = wdgt.command_line_flag_list 65 | 66 | # command_line_string 67 | command_line_string = r'"{0}"'.format(nuke_path) 68 | command_line_string += ' ' 69 | 70 | # flag_string 71 | flag_string = get_flag_string(flag_list, renderthreads_node, frame) 72 | 73 | # add 74 | command_line_string += flag_string 75 | command_line_string += ' ' 76 | 77 | # script_path 78 | command_line_string += r'"{0}"'.format(script_path) 79 | 80 | # return 81 | return command_line_string 82 | 83 | 84 | def get_flag_string(flag_list, 85 | renderthreads_node=None, 86 | frame=None): 87 | """ 88 | Return flag string ready to be used in 89 | command line string from list of 90 | RenderThreadsCommandLineFlag objects. 91 | Replace frame and write_node_name 92 | if not None with regexprs. 93 | """ 94 | 95 | # flag_string 96 | flag_string = r'' 97 | 98 | # iterate flag list 99 | for index, flag in enumerate(sorted(flag_list)): 100 | 101 | # check state 102 | if (flag.get_state()): 103 | 104 | # append flag 105 | flag_string += flag.get_flag() 106 | 107 | # last entry 108 | if not (index == len(flag_list) - 1): 109 | 110 | # add space 111 | flag_string += ' ' 112 | 113 | # renderthreads_node 114 | if not(renderthreads_node is None): 115 | 116 | # write_node_name 117 | write_node_name = renderthreads_node.fullName() 118 | 119 | # pattern 120 | pattern = re.compile('-X\s[\w]+') 121 | 122 | # replace template 123 | flag_string = pattern.sub('-X {0}'.format(write_node_name), flag_string) 124 | 125 | # frame 126 | if not(frame is None): 127 | 128 | # pattern 129 | pattern = re.compile('-F\s-?\d+') 130 | 131 | # replace frame 132 | flag_string = pattern.sub('-F {0}'.format(frame), flag_string) 133 | 134 | # return 135 | return flag_string 136 | -------------------------------------------------------------------------------- /renderthreads/lib/renderthreads_globals.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | renderthreads_globals 4 | ========================================== 5 | 6 | Module that has renderthreads tool globals 7 | """ 8 | 9 | 10 | # Import 11 | # ------------------------------------------------------------------ 12 | # import 13 | import os 14 | import logging 15 | # PySide 16 | from PySide import QtGui 17 | from PySide import QtCore 18 | 19 | 20 | # Version and Title 21 | # ------------------------------------------------------------------ 22 | TITLE = 'renderthreads' 23 | VERSION = 0.1 24 | 25 | 26 | # Logging 27 | # ------------------------------------------------------------------ 28 | INITIAL_LOGGING_LEVEL = logging.INFO 29 | 30 | 31 | # Pathes 32 | # ------------------------------------------------------------------ 33 | TOOL_ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) 34 | LIB_PATH = os.path.join(TOOL_ROOT_PATH, 'lib') 35 | GUI_PATH = os.path.join(LIB_PATH, 'gui') 36 | MVC_PATH = os.path.join(LIB_PATH, 'mvc') 37 | THIRD_PARTY_PATH = os.path.join(LIB_PATH, 'third_party') 38 | 39 | MEDIA_PATH = os.path.join(TOOL_ROOT_PATH, 'media') 40 | ICONS_PATH = os.path.join(MEDIA_PATH, 'icons') 41 | FONTS_PATH = os.path.join(MEDIA_PATH, 'fonts') 42 | UI_PATH = os.path.join(MEDIA_PATH, 'ui') 43 | 44 | 45 | # Fonts 46 | # ------------------------------------------------------------------ 47 | # Sizes 48 | FONT_SIZE_DEFAULT = 10 49 | FONT_SIZE_LARGE = 14 50 | FONT_SIZE_SMALL = 8 51 | # Fonts 52 | FUTURA_LT_LIGHT = ('Futura LT Light', 'futura-lt-light.ttf') 53 | 54 | # FONTS_LIST [(Font Name, Font File Name), (Font Name, Font File Name)...] 55 | FONTS_LIST = [FUTURA_LT_LIGHT] 56 | 57 | # iterate and install if not installed 58 | for font_name, font_file_name in FONTS_LIST: 59 | # font not installed 60 | if not (font_name in QtGui.QFontDatabase().families()): 61 | # current_font_path 62 | current_font_path = os.path.join(FONTS_PATH, font_file_name).replace('\\', '/') 63 | # add font 64 | QtGui.QFontDatabase.addApplicationFont(current_font_path) 65 | 66 | 67 | # Colors 68 | # ------------------------------------------------------------------ 69 | # darkening_factor 70 | DARKENING_FACTOR = 120 71 | # brightening_factor 72 | BRIGHTENING_FACTOR = 150 73 | # transparency 74 | TRANSPARENCY = 100 75 | 76 | BLACK = QtGui.QColor('#000000') 77 | WHITE = QtGui.QColor('#f5f5f5') 78 | WHITE_DARK = WHITE.darker(DARKENING_FACTOR) 79 | WHITE_BRIGHT = WHITE.lighter(DARKENING_FACTOR) 80 | GREY = QtGui.QColor('#484f57') 81 | GREY_DARK = GREY.darker(DARKENING_FACTOR) 82 | GREY_BRIGHT = GREY.lighter(DARKENING_FACTOR) 83 | RED = QtGui.QColor('#fb3e2a') 84 | RED_DARK = RED.darker(DARKENING_FACTOR) 85 | RED_BRIGHT = RED.lighter(DARKENING_FACTOR) 86 | BLUE = QtGui.QColor('#07faff') 87 | BLUE_DARK = BLUE.darker(DARKENING_FACTOR) 88 | BLUE_BRIGHT = BLUE.lighter(DARKENING_FACTOR) 89 | 90 | 91 | # Images 92 | # ------------------------------------------------------------------ 93 | HEADER_IMAGE = os.path.join(ICONS_PATH, 'renderthreads_header.png').replace('\\', '/') 94 | ICON_RENDERTHREADS = os.path.join(ICONS_PATH, 'icn_renderthreads.png').replace('\\', '/') 95 | 96 | 97 | # Text 98 | # ------------------------------------------------------------------ 99 | WRITE_NODE_REPLACEMENT_TEMPLATE = 'write_node_template' 100 | TEXT_DIVIDER = '---------------------------' 101 | 102 | 103 | # Misc. 104 | # ------------------------------------------------------------------ 105 | COMMAND_LINE_FLAG_SPACING = 4 106 | 107 | 108 | # Threads 109 | # ------------------------------------------------------------------ 110 | INITIAL_THREAD_INTERVAL = 200 # msec 111 | INITIAL_THREAD_TIMEOUT = 10 # min 112 | INITIAL_DISPLAY_SHELL = 0 # Can be 0 or 1 113 | INITIAL_LOG_EXITCODE_ERRORS_ONLY = 1 # Can be 0 or 1 114 | INITIAL_READD_BROKEN_JOB_COUNT = 2 115 | INITIAL_SAVE_SCRIPT_BEFORE_RENDER = 1 # msec 116 | 117 | INITIAL_PRIORITY = 50 # Range is from 1 - 100. PriorityQueue values are negated so 1 is highest, 100 lowest 118 | 119 | 120 | # Websites 121 | # ------------------------------------------------------------------ 122 | WEBSITE_DOCS = r'http://renderthreads.readthedocs.org/' 123 | WEBSITE_DOCS_QUICK = r'http://renderthreads.readthedocs.org/quickstart.html' 124 | WEBSITE_PYPI = r'https://pypi.python.org/pypi/renderthreads/' 125 | WEBSITE_GITHUB = r'https://github.com/timmwagener/renderthreads' 126 | WEBSITE_GITHUB_ISSUES = r'https://github.com/timmwagener/renderthreads/issues' 127 | WEBSITE_AUTHOR = r'http://www.timmwagener.com/' 128 | WEBSITE_VIMEO = r'https://vimeo.com/timmwagener/renderthreads' 129 | WEBSITE_LINKEDIN = r'https://www.linkedin.com/pub/timm-wagener/54/5a2/b55' 130 | 131 | 132 | # Tooltips 133 | # ------------------------------------------------------------------ 134 | TT_THREADCOUNT = 'Threadcount\n\ 135 | {0}\n\ 136 | Number of threads to use for command-line rendering.\n\ 137 | Minimum is 1 and maximum is the number of available\n\ 138 | cores in the system. The default is half of all available\n\ 139 | cores.\n\ 140 | {0}\n\ 141 | Be carefull with the thread count in case of low system memory.'.format(TEXT_DIVIDER) 142 | 143 | TT_THREAD_INTERVAL = 'Thread interval (msec.)\n\ 144 | {0}\n\ 145 | Interval in milliseconds in which the threads repeatedly\n\ 146 | ask their queue for new work. The default is 200 msec.'.format(TEXT_DIVIDER) 147 | 148 | TT_THREAD_TIMEOUT = 'Thread Timeout (min.)\n\ 149 | {0}\n\ 150 | Time in minutes till the current render process is forcibly\n\ 151 | terminated. The exit code of a terminated process is 1. A terminated\n\ 152 | process will be logged as an error.'.format(TEXT_DIVIDER) 153 | 154 | TT_DISPLAY_SHELL = 'Display shell\n\ 155 | {0}\n\ 156 | Wether or not to open a new shell for each rendered frame.'.format(TEXT_DIVIDER) 157 | 158 | TT_LOG_EXITCODE_ERRORS_ONLY = 'Log exitcode errors only\n\ 159 | {0}\n\ 160 | Each frame is rendered in a new instance of Nuke in a separate\n\ 161 | process. Each of these processes gives a return code when closed\n\ 162 | which can happen when it has finished or has been terminated etc.\n\ 163 | The return code indicates whether or not the process was successfull.\n\ 164 | This flag determines if all return codes or just the ones that were\n\ 165 | not sucessfull should be logged. The default is logging only errors.'.format(TEXT_DIVIDER) 166 | 167 | TT_INITIAL_READD_BROKEN_JOB_COUNT = 'Re-add broken job count\n\ 168 | {0}\n\ 169 | When a process has returned an exit code that indicates\n\ 170 | an error, it can be added to the render queue again.\n\ 171 | This value determines how many times a broken job will be added to the queue again.\n\ 172 | A value of 0 means that the job is not added again.'.format(TEXT_DIVIDER) 173 | 174 | TT_LOGGING_LEVEL = 'Logging level\n\ 175 | {0}\n\ 176 | Verbosity of the tool. Values from 1-5 correspond to the logging\n\ 177 | constants from DEBUG to CRITICAL (10-50).\n\ 178 | The default is 2.'.format(TEXT_DIVIDER) 179 | 180 | TT_SAVE_SCRIPT = 'Save script before render\n\ 181 | {0}\n\ 182 | Save the current script before command-line rendering starts.\n\ 183 | If this is off the latest changes to your comp might not be rendered\n\ 184 | because they are not in the version of the comp that is opened\n\ 185 | by the command-line Nuke.'.format(TEXT_DIVIDER) 186 | -------------------------------------------------------------------------------- /renderthreads/lib/renderthreads_logging.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads_logging 5 | ========================================== 6 | 7 | Module to handle all things related to logging in 8 | the renderthreads package. 9 | 10 | ------------------------------------------ 11 | 12 | Members: 13 | 14 | #. UniversalPrintObject 15 | Implements the print_message interface 16 | used in UniversalStreamHandler. 17 | 18 | #. UniversalStreamHandler 19 | Stream handler subclass that is initialized with 20 | a UniversalPrintObject that delivers the correct 21 | print behaviour under the same interface. 22 | 23 | ... 24 | """ 25 | 26 | 27 | # Import 28 | # ------------------------------------------------------------------ 29 | # python 30 | import sys 31 | import logging 32 | import functools 33 | # PySide 34 | from PySide import QtGui 35 | from PySide import QtCore 36 | 37 | 38 | # Import variable 39 | do_reload = True 40 | 41 | # renderthreads 42 | 43 | # lib 44 | 45 | # renderthreads_globals 46 | import renderthreads_globals 47 | if(do_reload): 48 | reload(renderthreads_globals) 49 | 50 | 51 | # Globals 52 | # ------------------------------------------------------------------ 53 | INITIAL_LOGGING_LEVEL = renderthreads_globals.INITIAL_LOGGING_LEVEL 54 | 55 | 56 | # Decorators 57 | # ------------------------------------------------------------------ 58 | 59 | def execute_with_logger(logger_class): 60 | """ 61 | Closure logger with argument. 62 | """ 63 | 64 | def execute_with_logger_func_decorator(func): 65 | """ 66 | Use enclosed logger_class and 67 | return func object to use. 68 | """ 69 | 70 | def wrapped_func(*args, **kwargs): 71 | 72 | # current_logger_class 73 | current_logger_class = logging.getLoggerClass() 74 | 75 | # set default logger 76 | logging.setLoggerClass(logger_class) 77 | 78 | # execute func 79 | result = func(*args, **kwargs) 80 | 81 | # reset logger 82 | logging.setLoggerClass(current_logger_class) 83 | 84 | # return 85 | return result 86 | 87 | return wrapped_func 88 | 89 | return execute_with_logger_func_decorator 90 | 91 | 92 | # UniversalPrintObject 93 | # ------------------------------------------------------------------ 94 | class UniversalPrintObject(object): 95 | """ 96 | UniversalPrintObject implements the print_message interface 97 | used in UniversalStreamHandler. 98 | UniversalStreamHandler gets initialized with an instance var. 99 | of type UniversalPrintObject which in turn is initialized 100 | with a display member. Based on the type of display, 101 | UniversalPrintObject delivers the correct print behaviour 102 | to UniversalStreamHandler. 103 | """ 104 | 105 | def __init__(self, 106 | display=sys.stdout, 107 | logging_level=INITIAL_LOGGING_LEVEL): 108 | """ 109 | Initialize UniversalPrintObject 110 | """ 111 | 112 | # super 113 | # ------------------------------------------------------------------ 114 | self.parent_class = super(UniversalPrintObject, self) 115 | self.parent_class.__init__() 116 | 117 | # logger 118 | # ------------------------------------------------------------------ 119 | self.logger = logging.getLogger(self.__class__.__name__) 120 | self.logging_level = logging_level 121 | self.logger.setLevel(self.logging_level) 122 | 123 | # instance vars 124 | # ------------------------------------------------------------------ 125 | # display 126 | self.display = display 127 | 128 | # Methods 129 | # ------------------------------------------------------------------ 130 | def get_print_message(self): 131 | """ 132 | Return correct print method based on 133 | type of self.display. 134 | """ 135 | 136 | # stdout 137 | if (self.display == sys.stdout): 138 | return self.print_message_stdout 139 | 140 | # QtGui.QTextEdit 141 | elif (type(self.display) == QtGui.QTextEdit): 142 | return self.print_message_qtextedit 143 | 144 | # unknown 145 | else: 146 | return None 147 | 148 | print_message = property(fget=get_print_message) 149 | """descriptor object""" 150 | 151 | def print_message_stdout(*args): 152 | """ 153 | Print message on self.display object. 154 | """ 155 | 156 | # self 157 | self = args[0] 158 | # message 159 | message = args[1] 160 | # print 161 | print(message) 162 | 163 | def print_message_qtextedit(*args): 164 | """ 165 | Print message on self.display object. 166 | """ 167 | 168 | # self 169 | self = args[0] 170 | # message 171 | message = args[1] 172 | # append 173 | self.display.append(message) 174 | 175 | 176 | # UniversalStreamHandler 177 | # ------------------------------------------------------------------ 178 | class UniversalStreamHandler(logging.StreamHandler): 179 | """ 180 | Stream handler subclass that is initialized with 181 | a UniversalPrintObject that delivers the correct 182 | print behaviour under the same interface. 183 | """ 184 | 185 | def __init__(self, 186 | universal_print_object=UniversalPrintObject(), 187 | logging_level=INITIAL_LOGGING_LEVEL): 188 | """ 189 | Initialize UniversalStreamHandler 190 | """ 191 | 192 | # super class init 193 | super(UniversalStreamHandler, self).__init__() 194 | 195 | # logger 196 | # ------------------------------------------------------------------ 197 | self.logger = logging.getLogger(self.__class__.__name__) 198 | self.logging_level = logging_level 199 | self.logger.setLevel(self.logging_level) 200 | 201 | # instance vars 202 | # ------------------------------------------------------------------ 203 | # universal_print_object 204 | self.universal_print_object = universal_print_object 205 | 206 | # Methods 207 | # ------------------------------------------------------------------ 208 | def emit(self, record): 209 | """ 210 | Custom emit for UniversalStreamHandler. 211 | """ 212 | 213 | try: 214 | # message 215 | message = self.format(record) 216 | # print (just a wrapper around sys.stdout.write()) 217 | self.universal_print_object.print_message(message) 218 | # flush 219 | self.flush() 220 | 221 | except (KeyboardInterrupt, SystemExit): 222 | raise 223 | 224 | except: 225 | self.handleError(record) 226 | 227 | 228 | # RenderThreadsLogger 229 | # ------------------------------------------------------------------ 230 | class RenderThreadsLogger(logging.getLoggerClass()): 231 | """ 232 | Custom logging class RenderThreadsLogger to 233 | be able to test against type. 234 | """ 235 | 236 | 237 | # Functions 238 | # ------------------------------------------------------------------ 239 | def get_formatter(verbose_level=logging.WARNING): 240 | """ 241 | Return correctly formatted handler for display. 242 | For ease of use, verbose_level corresponds to 243 | known logging constants. 244 | """ 245 | 246 | # debug 247 | if (verbose_level == logging.DEBUG): 248 | return logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 249 | 250 | # info 251 | elif (verbose_level == logging.INFO): 252 | return logging.Formatter('%(name)s - %(levelname)s - %(message)s') 253 | 254 | # warning 255 | elif (verbose_level == logging.WARNING): 256 | return logging.Formatter('%(name)s - %(message)s') 257 | 258 | # error 259 | elif (verbose_level >= logging.ERROR): 260 | return logging.Formatter('%(message)s') 261 | 262 | 263 | def get_handler(display=sys.stdout): 264 | """ 265 | Return correctly formatted handler for display. 266 | """ 267 | 268 | # formatter 269 | formatter = get_formatter() 270 | # universal_print_object 271 | universal_print_object = UniversalPrintObject(display) 272 | # handler 273 | handler = UniversalStreamHandler(universal_print_object) 274 | # add formatter 275 | handler.setFormatter(formatter) 276 | 277 | # return 278 | return handler 279 | 280 | 281 | @execute_with_logger(RenderThreadsLogger) 282 | def get_logger(name, 283 | display=sys.stdout, 284 | logging_level=INITIAL_LOGGING_LEVEL): 285 | """ 286 | Return correctly formatted logger from single source. 287 | """ 288 | 289 | # handler 290 | handler = get_handler(display) 291 | 292 | # logger 293 | logger = logging.getLogger(name) 294 | logger.setLevel(logging_level) 295 | logger.handlers = [] 296 | logger.addHandler(handler) 297 | 298 | # return 299 | return logger 300 | 301 | 302 | def set_logging_level(logging_level): 303 | """ 304 | Set logging level for all instances of 305 | RenderThreads loggers. (That is all loggers in 306 | global dict of type RenderThreadsLogger) 307 | """ 308 | 309 | # iterate 310 | for logger_name, logger in logging.Logger.manager.loggerDict.iteritems(): 311 | 312 | # check type (a direct type check fails here, for whatever reason) 313 | # Instead check against __name__ of type which succeeds 314 | if (type(logger).__name__ == RenderThreadsLogger.__name__): 315 | 316 | # set level 317 | logger.setLevel(logging_level) 318 | 319 | # print 320 | print('Set logger {0} to {1}'.format(logger_name, logging_level)) 321 | -------------------------------------------------------------------------------- /renderthreads/lib/renderthreads_mvc_setup.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads_mvc_setup 5 | ========================================== 6 | 7 | This module encapsulates the creation of the 8 | renderthreads MVC. 9 | """ 10 | 11 | 12 | # Import 13 | # ------------------------------------------------------------------ 14 | # Python 15 | import logging 16 | import functools 17 | # PySide 18 | from PySide import QtGui 19 | from PySide import QtCore 20 | 21 | 22 | # Import variable 23 | do_reload = True 24 | 25 | # renderthreads 26 | 27 | # lib 28 | 29 | # renderthreads_globals 30 | import renderthreads_globals 31 | if(do_reload): 32 | reload(renderthreads_globals) 33 | 34 | # renderthreads_logging 35 | import renderthreads_logging 36 | if(do_reload): 37 | reload(renderthreads_logging) 38 | 39 | # lib.mvc 40 | 41 | # renderthreads_model 42 | from mvc import renderthreads_model 43 | if(do_reload): 44 | reload(renderthreads_model) 45 | 46 | # renderthreads_view 47 | from mvc import renderthreads_view 48 | if(do_reload): 49 | reload(renderthreads_view) 50 | 51 | # renderthreads_item_delegate 52 | from mvc import renderthreads_item_delegate 53 | if(do_reload): 54 | reload(renderthreads_item_delegate) 55 | 56 | 57 | # Globals 58 | # ------------------------------------------------------------------ 59 | 60 | 61 | # logger (Module Level) 62 | # ------------------------------------------------------------------ 63 | logger = renderthreads_logging.get_logger(__name__) 64 | 65 | 66 | # Setup 67 | # ------------------------------------------------------------------ 68 | def setup_mvc(wdgt): 69 | """ 70 | Main method that sets up the entire additional ui. 71 | """ 72 | 73 | # log 74 | logger.debug('create_mvc') 75 | # create_mvc 76 | create_mvc(wdgt) 77 | 78 | # log 79 | logger.debug('connect_mvc') 80 | # connect_mvc 81 | connect_mvc(wdgt) 82 | 83 | 84 | # Create 85 | # ------------------------------------------------------------------ 86 | def create_mvc(wdgt): 87 | """ 88 | Create MVC for RenderThreads instance. 89 | """ 90 | 91 | # nodes_view 92 | wdgt.nodes_view = renderthreads_view.RenderThreadsView(parent=wdgt) 93 | wdgt.nodes_view.setWordWrap(True) 94 | wdgt.nodes_view.setShowGrid(False) 95 | # set resize mode for horizontal header 96 | wdgt.nodes_view.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) 97 | wdgt.nodes_view.horizontalHeader().setStretchLastSection(False) 98 | wdgt.nodes_view.verticalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents) 99 | wdgt.nodes_view.setAlternatingRowColors(True) 100 | # objectNames 101 | wdgt.nodes_view.setObjectName('nodes_view') 102 | wdgt.nodes_view.horizontalHeader().setObjectName('nodes_view_horizontal_header') 103 | wdgt.nodes_view.verticalHeader().setObjectName('nodes_view_vertical_header') 104 | # hide vertical header 105 | wdgt.nodes_view.verticalHeader().hide() 106 | # context menu 107 | wdgt.nodes_view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 108 | # add to ui 109 | wdgt.frm_nodes.layout().addWidget(wdgt.nodes_view) 110 | 111 | # nodes_item_delegate 112 | wdgt.nodes_item_delegate = renderthreads_item_delegate.RenderThreadsItemDelegate(parent=wdgt) 113 | wdgt.nodes_item_delegate.setObjectName('nodes_item_delegate') 114 | # set in view 115 | wdgt.nodes_view.setItemDelegate(wdgt.nodes_item_delegate) 116 | 117 | # nodes_model 118 | wdgt.nodes_model = renderthreads_model.RenderThreadsModel(parent=wdgt) 119 | # set model in view 120 | wdgt.nodes_view.setModel(wdgt.nodes_model) 121 | 122 | # nodes_selection_model 123 | wdgt.nodes_selection_model = QtGui.QItemSelectionModel(wdgt.nodes_model) 124 | wdgt.nodes_view.setSelectionModel(wdgt.nodes_selection_model) 125 | 126 | 127 | # Connect 128 | # ------------------------------------------------------------------ 129 | 130 | def connect_mvc(wdgt): 131 | """ 132 | Connect MVC components. 133 | """ 134 | 135 | pass 136 | -------------------------------------------------------------------------------- /renderthreads/lib/renderthreads_nuke.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads_nuke 5 | ========================================== 6 | 7 | This module encapsulates renderthreads nuke 8 | functionality. 9 | """ 10 | 11 | 12 | # Import 13 | # ------------------------------------------------------------------ 14 | # Python 15 | import logging 16 | import functools 17 | import collections 18 | # nuke 19 | import nuke 20 | 21 | 22 | # Import variable 23 | do_reload = True 24 | 25 | # renderthreads 26 | 27 | # lib 28 | 29 | # renderthreads_globals 30 | import renderthreads_globals 31 | if(do_reload): 32 | reload(renderthreads_globals) 33 | 34 | # renderthreads_logging 35 | import renderthreads_logging 36 | if(do_reload): 37 | reload(renderthreads_logging) 38 | 39 | # lib.mvc 40 | 41 | # renderthreads_node 42 | from mvc import renderthreads_node 43 | if(do_reload): 44 | reload(renderthreads_node) 45 | 46 | 47 | # Globals 48 | # ------------------------------------------------------------------ 49 | 50 | 51 | # logger (Module Level) 52 | # ------------------------------------------------------------------ 53 | logger = renderthreads_logging.get_logger(__name__) 54 | 55 | 56 | # MemoryInfo 57 | # ------------------------------------------------------------------ 58 | MemoryInfo = collections.namedtuple('MemoryInfo', 'info ram_total ram_in_use total_virtual_memory') 59 | 60 | 61 | # Scene Interaction 62 | # ------------------------------------------------------------------ 63 | def get_nodes(filter_type=None, selected=False): 64 | """ 65 | Return list of all write nodes in DAG. 66 | """ 67 | 68 | # selected 69 | if (selected): 70 | # all nodes (also group content) 71 | node_list = nuke.allNodes(recurseGroups=True) 72 | # selected_nodes 73 | node_list = [node for node in node_list if (node.isSelected())] 74 | # all 75 | else: 76 | node_list = nuke.allNodes(recurseGroups=True) 77 | 78 | # filter_type 79 | if (filter_type): 80 | node_list = [node for node in node_list if (node.Class() == filter_type)] 81 | 82 | # check 83 | if not (node_list): 84 | # log 85 | logger.debug('node_list empty or None. Returning empty list.') 86 | return [] 87 | 88 | return node_list 89 | 90 | 91 | def print_nodes(filter_type=None, selected=False, convert=False): 92 | """ 93 | Return list of all write nodes in DAG. 94 | """ 95 | 96 | # node_list 97 | node_list = get_nodes(filter_type, selected) 98 | 99 | # convert 100 | if (convert): 101 | node_list = convert_nodes(node_list) 102 | 103 | # iterate and print 104 | for node in node_list: 105 | print('{0} - {1}'.format(node.fullName(), node.Class())) 106 | 107 | 108 | def convert_nodes(nuke_node_list): 109 | """ 110 | Return list of renderthread_nodes 111 | from given list of nuke nodes. 112 | """ 113 | 114 | # renderthread_node_list 115 | renderthread_node_list = [] 116 | 117 | # convert 118 | for nuke_node in nuke_node_list: 119 | try: 120 | # renderthread_node 121 | renderthread_node = convert_nuke_to_renderthread_node(nuke_node) 122 | # append 123 | renderthread_node_list.append(renderthread_node) 124 | except: 125 | # log 126 | logger.debug('Error converting nuke_node {0} to renderthread_node. Not converting.'.format(nuke_node)) 127 | 128 | # return 129 | return renderthread_node_list 130 | 131 | 132 | def convert_nuke_to_renderthread_node(nuke_node): 133 | """ 134 | Convert a nuke to a renderthread node. 135 | """ 136 | 137 | start_frame = int(nuke.Root().firstFrame()) 138 | end_frame = int(nuke.Root().lastFrame()) 139 | 140 | # write 141 | if (nuke_node.Class() == 'Write'): 142 | return renderthreads_node.RenderThreadsNodeWrite(nuke_node, start_frame, end_frame) 143 | # generic 144 | else: 145 | return renderthreads_node.RenderThreadsNode(nuke_node, start_frame, end_frame) 146 | 147 | 148 | def node_exists(node): 149 | """ 150 | Check whether or not node exists. 151 | """ 152 | 153 | try: 154 | result = nuke.exists(node.name()) 155 | return result 156 | except: 157 | return False 158 | 159 | 160 | def deselect_all(): 161 | """ 162 | Deselect all nuke nodes. 163 | """ 164 | 165 | # all nodes (also group content) 166 | node_list = nuke.allNodes(recurseGroups=True) 167 | 168 | # deselect 169 | for node in node_list: 170 | try: 171 | node.setSelected(False) 172 | except: 173 | continue 174 | 175 | 176 | def select_nodes(nuke_node_list): 177 | """ 178 | Select nodes from given nuke_node_list. 179 | """ 180 | 181 | # iterate and select 182 | for nuke_node in nuke_node_list: 183 | 184 | # select 185 | try: 186 | select_node(nuke_node) 187 | except: 188 | logger.debug('Error selecting nuke node {0}. Continuing'.format(nuke_node)) 189 | continue 190 | 191 | 192 | def select_node(nuke_node, exclusive=False): 193 | """ 194 | Select nuke_node from given nuke_node. 195 | """ 196 | 197 | # exclusive 198 | if (exclusive): 199 | nuke_node.selectOnly() 200 | # else 201 | else: 202 | nuke_node.setSelected(True) 203 | 204 | 205 | def get_memory_info(display=False): 206 | """ 207 | Return list of memory info. 208 | """ 209 | 210 | # values 211 | info = str(nuke.memory('info')) 212 | ram_total = byte_to_megabyte(nuke.memory('total_ram')) 213 | ram_in_use = byte_to_megabyte(nuke.memory('usage')) 214 | total_virtual_memory = byte_to_megabyte(nuke.memory('total_vm')) 215 | 216 | # memory_info 217 | memory_info = MemoryInfo(info, ram_total, ram_in_use, total_virtual_memory) 218 | 219 | # display 220 | if (display): 221 | 222 | # log 223 | logger.debug('{0}'.format(memory_info)) 224 | 225 | 226 | def byte_to_megabyte(byte_number): 227 | """ 228 | Convert bytes to megabytes. 229 | For example a byte_number of 230 | 17135431680 returns 16341 megabyte. 231 | 1048576 byte are 1 mbyte. 232 | """ 233 | 234 | try: 235 | return int(byte_number / 1048576) 236 | except: 237 | return None 238 | 239 | 240 | def get_nuke_path(): 241 | """ 242 | Return path to currently used Nuke.exe. 243 | """ 244 | 245 | return nuke.EXE_PATH 246 | 247 | 248 | def get_script_path(): 249 | """ 250 | Return script path. 251 | """ 252 | 253 | return nuke.root().name() 254 | 255 | 256 | def save_script(): 257 | """ 258 | Save the current script under the 259 | same name. Return True or False depending on 260 | wether or not the operation was successful. 261 | """ 262 | 263 | try: 264 | 265 | result = nuke.scriptSave() 266 | return result 267 | 268 | except: 269 | 270 | # log 271 | logger.info('Error saving file.') 272 | 273 | return False 274 | -------------------------------------------------------------------------------- /renderthreads/lib/renderthreads_services_setup.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads_services_setup 5 | ========================================== 6 | 7 | This module encapsulates the creation of services 8 | for the renderthreads tool that run in the background. 9 | This might include timers that trigger something 10 | every once in a while or real daemon threads. 11 | """ 12 | 13 | 14 | # Import 15 | # ------------------------------------------------------------------ 16 | # Python 17 | import logging 18 | import functools 19 | # PySide 20 | from PySide import QtGui 21 | from PySide import QtCore 22 | 23 | 24 | # Import variable 25 | do_reload = True 26 | 27 | # renderthreads 28 | 29 | # lib 30 | 31 | # renderthreads_globals 32 | import renderthreads_globals 33 | if(do_reload): 34 | reload(renderthreads_globals) 35 | 36 | # renderthreads_logging 37 | import renderthreads_logging 38 | if(do_reload): 39 | reload(renderthreads_logging) 40 | 41 | # renderthreads_nuke 42 | import renderthreads_nuke 43 | if(do_reload): 44 | reload(renderthreads_nuke) 45 | 46 | # renderthreads_gui_setup 47 | import renderthreads_gui_setup 48 | if(do_reload): 49 | reload(renderthreads_gui_setup) 50 | 51 | 52 | # Globals 53 | # ------------------------------------------------------------------ 54 | 55 | 56 | # logger (Module Level) 57 | # ------------------------------------------------------------------ 58 | logger = renderthreads_logging.get_logger(__name__) 59 | 60 | 61 | # Setup 62 | # ------------------------------------------------------------------ 63 | def setup_services(wdgt): 64 | """ 65 | Main method that sets up the entire additional ui. 66 | """ 67 | 68 | # log 69 | logger.debug('create_services') 70 | # create_services 71 | create_services(wdgt) 72 | 73 | # log 74 | logger.debug('connect_services') 75 | # connect_services 76 | connect_services(wdgt) 77 | 78 | 79 | # Create 80 | # ------------------------------------------------------------------ 81 | def create_services(wdgt): 82 | """ 83 | Create services for RenderThreads instance. 84 | """ 85 | 86 | # create_mvc_validity_check 87 | create_mvc_validity_check(wdgt) 88 | 89 | # create_memory_check 90 | create_memory_check(wdgt) 91 | 92 | # create_script_check 93 | create_script_check(wdgt) 94 | 95 | 96 | def create_mvc_validity_check(wdgt, interval=1000): 97 | """ 98 | Setup check to remove invalid entries from 99 | model. invalid entries are renderthread nodes 100 | within the model whose nuke node in the 101 | scene DAG have been deleted. (renderthread nodes 102 | whose get_nuke_node delivers None) 103 | """ 104 | 105 | # tmr_validity_check 106 | wdgt.tmr_validity_check = QtCore.QTimer(wdgt) 107 | wdgt.tmr_validity_check.start(interval) 108 | 109 | 110 | def create_memory_check(wdgt, interval=2000): 111 | """ 112 | Create a timer that delivers info about memory 113 | constantly. 114 | """ 115 | 116 | # tmr_memory_check 117 | wdgt.tmr_memory_check = QtCore.QTimer(wdgt) 118 | wdgt.tmr_memory_check.start(interval) 119 | 120 | 121 | def create_script_check(wdgt, interval=1000): 122 | """ 123 | Create a timer that delivers the name of 124 | the current nuke script. 125 | """ 126 | 127 | # tmr_script_check 128 | wdgt.tmr_script_check = QtCore.QTimer(wdgt) 129 | wdgt.tmr_script_check.start(interval) 130 | 131 | 132 | # Connect 133 | # ------------------------------------------------------------------ 134 | def connect_services(wdgt): 135 | """ 136 | Connect services. 137 | """ 138 | 139 | # connect_mvc_validity_check 140 | connect_mvc_validity_check(wdgt) 141 | 142 | # connect_memory_check 143 | connect_memory_check(wdgt) 144 | 145 | # connect_script_check 146 | connect_script_check(wdgt) 147 | 148 | 149 | def connect_mvc_validity_check(wdgt): 150 | """ 151 | Connect mvc validity check service. 152 | """ 153 | 154 | # tmr_validity_check 155 | wdgt.tmr_validity_check.timeout.connect(functools.partial(wdgt.nodes_model.update_invalid)) 156 | 157 | 158 | def connect_memory_check(wdgt): 159 | """ 160 | Connect memory check service. 161 | """ 162 | 163 | # tmr_memory_check 164 | wdgt.tmr_memory_check.timeout.connect(functools.partial(renderthreads_nuke.get_memory_info)) 165 | 166 | 167 | def connect_script_check(wdgt): 168 | """ 169 | Connect script check service. 170 | """ 171 | 172 | # tmr_script_check 173 | wdgt.tmr_script_check.timeout.connect(functools.partial(renderthreads_gui_setup.update_script_path, wdgt)) 174 | 175 | 176 | # Close 177 | # ------------------------------------------------------------------ 178 | def stop_services(wdgt): 179 | """ 180 | Stop all services created in this module. 181 | """ 182 | 183 | # tmr_validity_check 184 | wdgt.tmr_validity_check.stop() 185 | 186 | # tmr_memory_check 187 | wdgt.tmr_memory_check.stop() 188 | 189 | # tmr_script_check 190 | wdgt.tmr_script_check.stop() 191 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/__init__.py -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/__init__.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2009 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/__init__.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/__init__.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/__init__.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/compiler.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | import sys 24 | 25 | from pysideuic.properties import Properties 26 | from pysideuic.uiparser import UIParser 27 | from pysideuic.Compiler import qtproxies 28 | from pysideuic.Compiler.indenter import createCodeIndenter, getIndenter, \ 29 | write_code 30 | from pysideuic.Compiler.qobjectcreator import CompilerCreatorPolicy 31 | from pysideuic.Compiler.misc import write_import 32 | 33 | 34 | class UICompiler(UIParser): 35 | def __init__(self): 36 | UIParser.__init__(self, qtproxies.QtCore, qtproxies.QtGui, 37 | CompilerCreatorPolicy()) 38 | 39 | def reset(self): 40 | qtproxies.i18n_strings = [] 41 | UIParser.reset(self) 42 | 43 | def setContext(self, context): 44 | qtproxies.i18n_context = context 45 | 46 | def createToplevelWidget(self, classname, widgetname): 47 | indenter = getIndenter() 48 | indenter.level = 0 49 | 50 | indenter.write("from PySide import QtCore, QtGui") 51 | indenter.write("") 52 | 53 | indenter.write("class Ui_%s(object):" % self.uiname) 54 | indenter.indent() 55 | indenter.write("def setupUi(self, %s):" % widgetname) 56 | indenter.indent() 57 | w = self.factory.createQObject(classname, widgetname, (), 58 | is_attribute = False, 59 | no_instantiation = True) 60 | w.baseclass = classname 61 | w.uiclass = "Ui_%s" % self.uiname 62 | return w 63 | 64 | def setDelayedProps(self): 65 | write_code("") 66 | write_code("self.retranslateUi(%s)" % self.toplevelWidget) 67 | UIParser.setDelayedProps(self) 68 | 69 | def finalize(self): 70 | indenter = getIndenter() 71 | indenter.level = 1 72 | indenter.write("") 73 | indenter.write("def retranslateUi(self, %s):" % self.toplevelWidget) 74 | indenter.indent() 75 | 76 | if qtproxies.i18n_strings: 77 | for s in qtproxies.i18n_strings: 78 | indenter.write(s) 79 | else: 80 | indenter.write("pass") 81 | 82 | indenter.dedent() 83 | indenter.dedent() 84 | 85 | # Make a copy of the resource modules to import because the parser will 86 | # reset() before returning. 87 | self._resources = self.resources 88 | 89 | def compileUi(self, input_stream, output_stream, from_imports): 90 | createCodeIndenter(output_stream) 91 | w = self.parse(input_stream) 92 | 93 | indenter = getIndenter() 94 | indenter.write("") 95 | 96 | self.factory._cpolicy._writeOutImports() 97 | 98 | for res in self._resources: 99 | write_import(res, from_imports) 100 | 101 | return {"widgetname": str(w), 102 | "uiclass" : w.uiclass, 103 | "baseclass" : w.baseclass} 104 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/compiler.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/compiler.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/compiler.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/compiler.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/indenter.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2009 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | indentwidth = 4 24 | 25 | _indenter = None 26 | 27 | class _IndentedCodeWriter(object): 28 | def __init__(self, output): 29 | self.level = 0 30 | self.output = output 31 | 32 | def indent(self): 33 | self.level += 1 34 | 35 | def dedent(self): 36 | self.level -= 1 37 | 38 | def write(self, line): 39 | if line.strip(): 40 | if indentwidth > 0: 41 | indent = " " * indentwidth 42 | line = line.replace("\t", indent) 43 | else: 44 | indent = "\t" 45 | 46 | self.output.write("%s%s\n" % (indent * self.level, line)) 47 | else: 48 | self.output.write("\n") 49 | 50 | 51 | def createCodeIndenter(output): 52 | global _indenter 53 | _indenter = _IndentedCodeWriter(output) 54 | 55 | def getIndenter(): 56 | return _indenter 57 | 58 | def write_code(string): 59 | _indenter.write(string) 60 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/indenter.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/indenter.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/indenter.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/indenter.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/misc.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | 24 | from pysideuic.Compiler.indenter import write_code 25 | 26 | 27 | def write_import(module_name, from_imports): 28 | if from_imports: 29 | write_code("from . import %s" % module_name) 30 | else: 31 | write_code("import %s" % module_name) 32 | 33 | 34 | def moduleMember(module, name): 35 | if module: 36 | return "%s.%s" % (module, name) 37 | 38 | return name 39 | 40 | 41 | class Literal(object): 42 | """Literal(string) -> new literal 43 | 44 | string will not be quoted when put into an argument list""" 45 | def __init__(self, string): 46 | self.string = string 47 | 48 | def __str__(self): 49 | return self.string 50 | 51 | def __or__(self, r_op): 52 | return Literal("%s|%s" % (self, r_op)) 53 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/misc.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/misc.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/misc.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/misc.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/proxy_type.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | from pysideuic.Compiler.misc import Literal, moduleMember 24 | 25 | 26 | class ProxyType(type): 27 | def __init__(*args): 28 | type.__init__(*args) 29 | for cls in args[0].__dict__.values(): 30 | if type(cls) is ProxyType: 31 | cls.module = args[0].__name__ 32 | 33 | if not hasattr(args[0], "module"): 34 | args[0].module = "" 35 | 36 | def __getattribute__(cls, name): 37 | try: 38 | return type.__getattribute__(cls, name) 39 | except AttributeError: 40 | # Handle internal (ie. non-PySide) attributes as normal. 41 | if name == "module": 42 | raise 43 | 44 | # Avoid a circular import. 45 | from pysideuic.Compiler.qtproxies import LiteralProxyClass 46 | 47 | return type(name, (LiteralProxyClass, ), 48 | {"module": moduleMember(type.__getattribute__(cls, "module"), 49 | type.__getattribute__(cls, "__name__"))}) 50 | 51 | def __str__(cls): 52 | return moduleMember(type.__getattribute__(cls, "module"), 53 | type.__getattribute__(cls, "__name__")) 54 | 55 | def __or__(self, r_op): 56 | return Literal("%s|%s" % (self, r_op)) 57 | 58 | def __eq__(self, other): 59 | return str(self) == str(other) 60 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/proxy_type.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/proxy_type.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/proxy_type.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/proxy_type.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/qobjectcreator.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | 24 | import logging 25 | 26 | try: 27 | set() 28 | except NameError: 29 | from sets import Set as set 30 | 31 | from pysideuic.Compiler.indenter import write_code 32 | from pysideuic.Compiler.qtproxies import QtGui, Literal, strict_getattr 33 | 34 | 35 | logger = logging.getLogger(__name__) 36 | DEBUG = logger.debug 37 | 38 | 39 | class _QtGuiWrapper(object): 40 | def search(clsname): 41 | try: 42 | return strict_getattr(QtGui, clsname) 43 | except AttributeError: 44 | return None 45 | 46 | search = staticmethod(search) 47 | 48 | 49 | class _ModuleWrapper(object): 50 | def __init__(self, name, classes): 51 | if "." in name: 52 | idx = name.rfind(".") 53 | self._package = name[:idx] 54 | self._module = name[idx + 1:] 55 | else: 56 | self._package = None 57 | self._module = name 58 | 59 | self._classes = set(classes) 60 | self._used = False 61 | 62 | def search(self, cls): 63 | if cls in self._classes: 64 | self._used = True 65 | return type(cls, (QtGui.QWidget,), {"module": self._module}) 66 | else: 67 | return None 68 | 69 | def _writeImportCode(self): 70 | if self._used: 71 | if self._package is None: 72 | write_code("import %s" % self._module) 73 | else: 74 | write_code("from %s import %s" % (self._package, self._module)) 75 | 76 | 77 | class _CustomWidgetLoader(object): 78 | def __init__(self): 79 | self._widgets = {} 80 | self._usedWidgets = set() 81 | 82 | def addCustomWidget(self, widgetClass, baseClass, module): 83 | assert widgetClass not in self._widgets 84 | self._widgets[widgetClass] = (baseClass, module) 85 | 86 | 87 | def _resolveBaseclass(self, baseClass): 88 | try: 89 | for x in range(0, 10): 90 | try: return strict_getattr(QtGui, baseClass) 91 | except AttributeError: pass 92 | 93 | baseClass = self._widgets[baseClass][0] 94 | else: 95 | raise ValueError("baseclass resolve took too long, check custom widgets") 96 | 97 | except KeyError: 98 | raise ValueError("unknown baseclass %s" % baseClass) 99 | 100 | 101 | def search(self, cls): 102 | try: 103 | self._usedWidgets.add(cls) 104 | baseClass = self._resolveBaseclass(self._widgets[cls][0]) 105 | DEBUG("resolved baseclass of %s: %s" % (cls, baseClass)) 106 | 107 | return type(cls, (baseClass,), 108 | {"module" : ""}) 109 | 110 | except KeyError: 111 | return None 112 | 113 | def _writeImportCode(self): 114 | imports = {} 115 | for widget in self._usedWidgets: 116 | _, module = self._widgets[widget] 117 | imports.setdefault(module, []).append(widget) 118 | 119 | for module, classes in imports.items(): 120 | write_code("from %s import %s" % (module, ", ".join(classes))) 121 | 122 | 123 | class CompilerCreatorPolicy(object): 124 | def __init__(self): 125 | self._modules = [] 126 | 127 | def createQtGuiWrapper(self): 128 | return _QtGuiWrapper 129 | 130 | def createModuleWrapper(self, name, classes): 131 | mw = _ModuleWrapper(name, classes) 132 | self._modules.append(mw) 133 | return mw 134 | 135 | def createCustomWidgetLoader(self): 136 | cw = _CustomWidgetLoader() 137 | self._modules.append(cw) 138 | return cw 139 | 140 | def instantiate(self, clsObject, objectname, ctor_args, is_attribute=True, no_instantiation=False): 141 | return clsObject(objectname, is_attribute, ctor_args, no_instantiation) 142 | 143 | def invoke(self, rname, method, args): 144 | return method(rname, *args) 145 | 146 | def getSlot(self, object, slotname): 147 | return Literal("%s.%s" % (object, slotname)) 148 | 149 | def _writeOutImports(self): 150 | for module in self._modules: 151 | module._writeImportCode() 152 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/qobjectcreator.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/qobjectcreator.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/qobjectcreator.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/qobjectcreator.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/qtproxies.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/qtproxies.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/Compiler/qtproxies.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/Compiler/qtproxies.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/__init__.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | __all__ = ("compileUi", "compileUiDir", "widgetPluginPath") 24 | 25 | __version__ = "0.2.15" 26 | 27 | from pysideuic.Compiler import indenter, compiler 28 | 29 | _header = """# -*- coding: utf-8 -*- 30 | 31 | # Form implementation generated from reading ui file '%s' 32 | # 33 | # Created: %s 34 | # by: pyside-uic %s running on PySide %s 35 | # 36 | # WARNING! All changes made in this file will be lost! 37 | 38 | """ 39 | 40 | _display_code = """ 41 | if __name__ == "__main__": 42 | \timport sys 43 | \tapp = QtGui.QApplication(sys.argv) 44 | \t%(widgetname)s = QtGui.%(baseclass)s() 45 | \tui = %(uiclass)s() 46 | \tui.setupUi(%(widgetname)s) 47 | \t%(widgetname)s.show() 48 | \tsys.exit(app.exec_()) 49 | """ 50 | 51 | 52 | def compileUiDir(dir, recurse=False, map=None, **compileUi_args): 53 | """compileUiDir(dir, recurse=False, map=None, **compileUi_args) 54 | 55 | Creates Python modules from Qt Designer .ui files in a directory or 56 | directory tree. 57 | 58 | dir is the name of the directory to scan for files whose name ends with 59 | '.ui'. By default the generated Python module is created in the same 60 | directory ending with '.py'. 61 | recurse is set if any sub-directories should be scanned. The default is 62 | False. 63 | map is an optional callable that is passed the name of the directory 64 | containing the '.ui' file and the name of the Python module that will be 65 | created. The callable should return a tuple of the name of the directory 66 | in which the Python module will be created and the (possibly modified) 67 | name of the module. The default is None. 68 | compileUi_args are any additional keyword arguments that are passed to 69 | the compileUi() function that is called to create each Python module. 70 | """ 71 | 72 | import os 73 | 74 | # Compile a single .ui file. 75 | def compile_ui(ui_dir, ui_file): 76 | # Ignore if it doesn't seem to be a .ui file. 77 | if ui_file.endswith('.ui'): 78 | py_dir = ui_dir 79 | py_file = ui_file[:-3] + '.py' 80 | 81 | # Allow the caller to change the name of the .py file or generate 82 | # it in a different directory. 83 | if map is not None: 84 | py_dir, py_file = map(py_dir, py_file) 85 | 86 | # Make sure the destination directory exists. 87 | try: 88 | os.makedirs(py_dir) 89 | except: 90 | pass 91 | 92 | ui_path = os.path.join(ui_dir, ui_file) 93 | py_path = os.path.join(py_dir, py_file) 94 | 95 | ui_file = open(ui_path, 'r') 96 | py_file = open(py_path, 'w') 97 | 98 | try: 99 | compileUi(ui_file, py_file, **compileUi_args) 100 | finally: 101 | ui_file.close() 102 | py_file.close() 103 | 104 | if recurse: 105 | for root, _, files in os.walk(dir): 106 | for ui in files: 107 | compile_ui(root, ui) 108 | else: 109 | for ui in os.listdir(dir): 110 | if os.path.isfile(os.path.join(dir, ui)): 111 | compile_ui(dir, ui) 112 | 113 | 114 | def compileUi(uifile, pyfile, execute=False, indent=4, from_imports=False): 115 | """compileUi(uifile, pyfile, execute=False, indent=4, from_imports=False) 116 | 117 | Creates a Python module from a Qt Designer .ui file. 118 | 119 | uifile is a file name or file-like object containing the .ui file. 120 | pyfile is the file-like object to which the Python code will be written to. 121 | execute is optionally set to generate extra Python code that allows the 122 | code to be run as a standalone application. The default is False. 123 | indent is the optional indentation width using spaces. If it is 0 then a 124 | tab is used. The default is 4. 125 | from_imports is optionally set to generate import statements that are 126 | relative to '.'. 127 | """ 128 | 129 | from time import ctime 130 | import PySide 131 | 132 | try: 133 | uifname = uifile.name 134 | except AttributeError: 135 | uifname = uifile 136 | 137 | indenter.indentwidth = indent 138 | 139 | global PySideToolsVersion 140 | pyfile.write(_header % (uifname, ctime(), __version__, PySide.__version__)) 141 | 142 | winfo = compiler.UICompiler().compileUi(uifile, pyfile, from_imports) 143 | 144 | if execute: 145 | indenter.write_code(_display_code % winfo) 146 | 147 | 148 | # The list of directories that are searched for widget plugins. 149 | from pysideuic.objcreator import widgetPluginPath 150 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/__init__.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/__init__.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/__init__.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/driver.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | 24 | import sys 25 | import logging 26 | 27 | from pysideuic import compileUi 28 | 29 | 30 | class Driver(object): 31 | """ This encapsulates access to the pyuic functionality so that it can be 32 | called by code that is Python v2/v3 specific. 33 | """ 34 | 35 | LOGGER_NAME = 'PySide.uic' 36 | 37 | def __init__(self, opts, ui_file): 38 | """ Initialise the object. opts is the parsed options. ui_file is the 39 | name of the .ui file. 40 | """ 41 | 42 | if opts.debug: 43 | logger = logging.getLogger(self.LOGGER_NAME) 44 | handler = logging.StreamHandler() 45 | handler.setFormatter(logging.Formatter("%(name)s: %(message)s")) 46 | logger.addHandler(handler) 47 | logger.setLevel(logging.DEBUG) 48 | 49 | self._opts = opts 50 | self._ui_file = ui_file 51 | 52 | def invoke(self): 53 | """ Invoke the action as specified by the parsed options. Returns 0 if 54 | there was no error. 55 | """ 56 | 57 | if self._opts.preview: 58 | return self._preview() 59 | 60 | self._generate() 61 | 62 | return 0 63 | 64 | def _preview(self): 65 | """ Preview the .ui file. Return the exit status to be passed back to 66 | the parent process. 67 | """ 68 | 69 | from PySide import QtUiTools 70 | from PySide import QtGui 71 | 72 | app = QtGui.QApplication([self._ui_file]) 73 | widget = QtUiTools.QUiLoader().load(self._ui_file) 74 | widget.show() 75 | 76 | return app.exec_() 77 | 78 | def _generate(self): 79 | """ Generate the Python code. """ 80 | 81 | if sys.hexversion >= 0x03000000: 82 | if self._opts.output == '-': 83 | from io import TextIOWrapper 84 | 85 | pyfile = TextIOWrapper(sys.stdout.buffer, encoding='utf8') 86 | else: 87 | pyfile = open(self._opts.output, 'wt', encoding='utf8') 88 | else: 89 | if self._opts.output == '-': 90 | pyfile = sys.stdout 91 | else: 92 | pyfile = open(self._opts.output, 'wt') 93 | 94 | compileUi(self._ui_file, pyfile, self._opts.execute, self._opts.indent, self._opts.from_imports) 95 | 96 | def on_IOError(self, e): 97 | """ Handle an IOError exception. """ 98 | 99 | sys.stderr.write("Error: %s: \"%s\"\n" % (e.strerror, e.filename)) 100 | 101 | def on_SyntaxError(self, e): 102 | """ Handle a SyntaxError exception. """ 103 | 104 | sys.stderr.write("Error in input file: %s\n" % e) 105 | 106 | def on_NoSuchWidgetError(self, e): 107 | """ Handle a NoSuchWidgetError exception. """ 108 | 109 | if e.args[0].startswith("Q3"): 110 | sys.stderr.write("Error: Q3Support widgets are not supported by PySide.\n") 111 | else: 112 | sys.stderr.write(str(e) + "\n") 113 | 114 | def on_Exception(self, e): 115 | """ Handle a generic exception. """ 116 | 117 | if logging.getLogger(self.LOGGER_NAME).level == logging.DEBUG: 118 | import traceback 119 | 120 | traceback.print_exception(*sys.exc_info()) 121 | else: 122 | from PySide import QtCore 123 | 124 | sys.stderr.write("""An unexpected error occurred. 125 | Check that you are using the latest version of PySide and report the error to 126 | http://bugs.openbossa.org, including the ui file used to trigger the error. 127 | """) 128 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/driver.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/driver.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/driver.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/driver.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/exceptions.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2009 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | class NoSuchWidgetError(Exception): 24 | def __str__(self): 25 | return "Unknown Qt widget: %s" % (self.args[0],) 26 | 27 | class UnsupportedPropertyError(Exception): 28 | pass 29 | 30 | class WidgetPluginError(Exception): 31 | pass 32 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/exceptions.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/exceptions.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/exceptions.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/exceptions.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/icon_cache.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This file is part of the PySide project. 3 | # 4 | # Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 5 | # Copyright (C) 2010 Riverbank Computing Limited. 6 | # Copyright (C) 2009 Torsten Marek 7 | # 8 | # Contact: PySide team 9 | # 10 | # This program is free software; you can redistribute it and/or 11 | # modify it under the terms of the GNU General Public License 12 | # version 2 as published by the Free Software Foundation. 13 | # 14 | # This program is distributed in the hope that it will be useful, but 15 | # WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 22 | # 02110-1301 USA 23 | 24 | 25 | import os.path 26 | 27 | 28 | class IconCache(object): 29 | """Maintain a cache of icons. If an icon is used more than once by a GUI 30 | then ensure that only one copy is created. 31 | """ 32 | 33 | def __init__(self, object_factory, qtgui_module): 34 | """Initialise the cache.""" 35 | 36 | self._object_factory = object_factory 37 | self._qtgui_module = qtgui_module 38 | self._base_dir = '' 39 | self._cache = [] 40 | 41 | def set_base_dir(self, base_dir): 42 | """ Set the base directory to be used for all relative filenames. """ 43 | 44 | self._base_dir = base_dir 45 | 46 | def get_icon(self, iconset): 47 | """Return an icon described by the given iconset tag.""" 48 | 49 | iset = _IconSet(iconset, self._base_dir) 50 | 51 | try: 52 | idx = self._cache.index(iset) 53 | except ValueError: 54 | idx = -1 55 | 56 | if idx >= 0: 57 | # Return the icon from the cache. 58 | iset = self._cache[idx] 59 | else: 60 | # Follow uic's naming convention. 61 | name = 'icon' 62 | idx = len(self._cache) 63 | 64 | if idx > 0: 65 | name += str(idx) 66 | 67 | icon = self._object_factory.createQObject("QIcon", name, (), 68 | is_attribute=False) 69 | iset.set_icon(icon, self._qtgui_module) 70 | self._cache.append(iset) 71 | 72 | return iset.icon 73 | 74 | 75 | class _IconSet(object): 76 | """An icon set, ie. the mode and state and the pixmap used for each.""" 77 | 78 | def __init__(self, iconset, base_dir): 79 | """Initialise the icon set from an XML tag.""" 80 | 81 | # Set the pre-Qt v4.4 fallback (ie. with no roles). 82 | self._fallback = self._file_name(iconset.text, base_dir) 83 | self._use_fallback = True 84 | 85 | # Parse the icon set. 86 | self._roles = {} 87 | 88 | for i in iconset: 89 | file_name = i.text 90 | if file_name is not None: 91 | file_name = self._file_name(file_name, base_dir) 92 | 93 | self._roles[i.tag] = file_name 94 | self._use_fallback = False 95 | 96 | # There is no real icon yet. 97 | self.icon = None 98 | 99 | @staticmethod 100 | def _file_name(fname, base_dir): 101 | """ Convert a relative filename if we have a base directory. """ 102 | 103 | fname = fname.replace("\\", "\\\\") 104 | 105 | if base_dir != '' and fname[0] != ':' and not os.path.isabs(fname): 106 | fname = os.path.join(base_dir, fname) 107 | 108 | return fname 109 | 110 | def set_icon(self, icon, qtgui_module): 111 | """Save the icon and set its attributes.""" 112 | 113 | if self._use_fallback: 114 | icon.addFile(self._fallback) 115 | else: 116 | for role, pixmap in self._roles.items(): 117 | if role.endswith("off"): 118 | mode = role[:-3] 119 | state = qtgui_module.QIcon.Off 120 | elif role.endswith("on"): 121 | mode = role[:-2] 122 | state = qtgui_module.QIcon.On 123 | else: 124 | continue 125 | 126 | mode = getattr(qtgui_module.QIcon, mode.title()) 127 | 128 | if pixmap: 129 | icon.addPixmap(qtgui_module.QPixmap(pixmap), mode, state) 130 | else: 131 | icon.addPixmap(qtgui_module.QPixmap(), mode, state) 132 | 133 | self.icon = icon 134 | 135 | def __eq__(self, other): 136 | """Compare two icon sets for equality.""" 137 | 138 | if not isinstance(other, type(self)): 139 | return NotImplemented 140 | 141 | if self._use_fallback: 142 | if other._use_fallback: 143 | return self._fallback == other._fallback 144 | 145 | return False 146 | 147 | if other._use_fallback: 148 | return False 149 | 150 | return self._roles == other._roles 151 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/icon_cache.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/icon_cache.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/icon_cache.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/icon_cache.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/objcreator.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | import sys 24 | import os.path 25 | 26 | from pysideuic.exceptions import NoSuchWidgetError, WidgetPluginError 27 | 28 | if sys.hexversion >= 0x03000000: 29 | from pysideuic.port_v3.load_plugin import load_plugin 30 | else: 31 | from pysideuic.port_v2.load_plugin import load_plugin 32 | 33 | 34 | # The list of directories that are searched for widget plugins. This is 35 | # exposed as part of the API. 36 | widgetPluginPath = [os.path.join(os.path.dirname(__file__), 'widget-plugins')] 37 | 38 | 39 | MATCH = True 40 | NO_MATCH = False 41 | MODULE = 0 42 | CW_FILTER = 1 43 | 44 | 45 | class QObjectCreator(object): 46 | def __init__(self, creatorPolicy): 47 | self._cpolicy = creatorPolicy 48 | 49 | self._cwFilters = [] 50 | self._modules = [self._cpolicy.createQtGuiWrapper()] 51 | 52 | # Get the optional plugins. 53 | for plugindir in widgetPluginPath: 54 | try: 55 | plugins = os.listdir(plugindir) 56 | except: 57 | plugins = [] 58 | 59 | for filename in plugins: 60 | if not filename.endswith('.py') or filename == '__init__.py': 61 | continue 62 | 63 | filename = os.path.join(plugindir, filename) 64 | 65 | plugin_globals = { 66 | "MODULE": MODULE, 67 | "CW_FILTER": CW_FILTER, 68 | "MATCH": MATCH, 69 | "NO_MATCH": NO_MATCH} 70 | 71 | plugin_locals = {} 72 | 73 | if load_plugin(open(filename), plugin_globals, plugin_locals): 74 | pluginType = plugin_locals["pluginType"] 75 | if pluginType == MODULE: 76 | modinfo = plugin_locals["moduleInformation"]() 77 | self._modules.append(self._cpolicy.createModuleWrapper(*modinfo)) 78 | elif pluginType == CW_FILTER: 79 | self._cwFilters.append(plugin_locals["getFilter"]()) 80 | else: 81 | raise WidgetPluginError("Unknown plugin type of %s" % filename) 82 | 83 | self._customWidgets = self._cpolicy.createCustomWidgetLoader() 84 | self._modules.append(self._customWidgets) 85 | 86 | def createQObject(self, classname, *args, **kwargs): 87 | classType = self.findQObjectType(classname) 88 | if classType: 89 | return self._cpolicy.instantiate(classType, *args, **kwargs) 90 | raise NoSuchWidgetError(classname) 91 | 92 | def invoke(self, rname, method, args=()): 93 | return self._cpolicy.invoke(rname, method, args) 94 | 95 | def findQObjectType(self, classname): 96 | for module in self._modules: 97 | w = module.search(classname) 98 | if w is not None: 99 | return w 100 | return None 101 | 102 | def getSlot(self, obj, slotname): 103 | return self._cpolicy.getSlot(obj, slotname) 104 | 105 | def addCustomWidget(self, widgetClass, baseClass, module): 106 | for cwFilter in self._cwFilters: 107 | match, result = cwFilter(widgetClass, baseClass, module) 108 | if match: 109 | widgetClass, baseClass, module = result 110 | break 111 | 112 | self._customWidgets.addCustomWidget(widgetClass, baseClass, module) 113 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/objcreator.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/objcreator.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/objcreator.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/objcreator.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/__init__.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # 6 | # Contact: PySide team 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # version 2 as published by the Free Software Foundation. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | # 02110-1301 USA 21 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/__init__.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/__init__.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/__init__.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/as_string.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # 6 | # Contact: PySide team 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # version 2 as published by the Free Software Foundation. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | # 02110-1301 USA 21 | 22 | import re 23 | 24 | 25 | def as_string(obj, encode=True): 26 | if isinstance(obj, basestring): 27 | s = '"' + _escape(obj.encode('UTF-8')) + '"' 28 | return s 29 | 30 | return str(obj) 31 | 32 | 33 | _esc_regex = re.compile(r"(\"|\'|\\)") 34 | 35 | def _escape(text): 36 | # This escapes any escaped single or double quote or backslash. 37 | x = _esc_regex.sub(r"\\\1", text) 38 | 39 | # This replaces any '\n' with an escaped version and a real line break. 40 | return re.sub(r'\n', r'\\n"\n"', x) 41 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/as_string.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/as_string.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/as_string.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/as_string.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/ascii_upper.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # 6 | # Contact: PySide team 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # version 2 as published by the Free Software Foundation. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | # 02110-1301 USA 21 | 22 | import string 23 | 24 | 25 | # A translation table for converting ASCII lower case to upper case. 26 | _ascii_trans_table = string.maketrans(string.ascii_lowercase, 27 | string.ascii_uppercase) 28 | 29 | 30 | # Convert a string to ASCII upper case irrespective of the current locale. 31 | def ascii_upper(s): 32 | return s.translate(_ascii_trans_table) 33 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/ascii_upper.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/ascii_upper.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/ascii_upper.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/ascii_upper.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/invoke.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | from pysideuic.exceptions import NoSuchWidgetError 24 | 25 | 26 | def invoke(driver): 27 | """ Invoke the given command line driver. Return the exit status to be 28 | passed back to the parent process. 29 | """ 30 | 31 | exit_status = 1 32 | 33 | try: 34 | exit_status = driver.invoke() 35 | 36 | except IOError, e: 37 | driver.on_IOError(e) 38 | 39 | except SyntaxError, e: 40 | driver.on_SyntaxError(e) 41 | 42 | except NoSuchWidgetError, e: 43 | driver.on_NoSuchWidgetError(e) 44 | 45 | except Exception, e: 46 | driver.on_Exception(e) 47 | 48 | return exit_status 49 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/invoke.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/invoke.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/invoke.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/invoke.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/load_plugin.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | from pysideuic.exceptions import WidgetPluginError 24 | 25 | 26 | def load_plugin(plugin, plugin_globals, plugin_locals): 27 | """ Load the given plugin (which is an open file). Return True if the 28 | plugin was loaded, or False if it wanted to be ignored. Raise an exception 29 | if there was an error. 30 | """ 31 | 32 | try: 33 | exec(plugin.read(), plugin_globals, plugin_locals) 34 | except ImportError: 35 | return False 36 | except Exception, e: 37 | raise WidgetPluginError("%s: %s" % (e.__class__, str(e))) 38 | 39 | return True 40 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/load_plugin.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/load_plugin.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/load_plugin.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/load_plugin.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/proxy_base.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | from pysideuic.Compiler.proxy_type import ProxyType 24 | 25 | 26 | class ProxyBase(object): 27 | __metaclass__ = ProxyType 28 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/proxy_base.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/proxy_base.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/proxy_base.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/proxy_base.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/string_io.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # 6 | # Contact: PySide team 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # version 2 as published by the Free Software Foundation. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | # 02110-1301 USA 21 | 22 | 23 | # Import the StringIO object. 24 | try: 25 | from cStringIO import StringIO 26 | except ImportError: 27 | from StringIO import StringIO 28 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/string_io.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/string_io.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/port_v2/string_io.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/port_v2/string_io.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/properties.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/properties.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/properties.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/properties.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/pyside-uic.1: -------------------------------------------------------------------------------- 1 | .TH PYSIDE-UIC "1" "December 2010" "pyside-uic" "User Commands" 2 | .SH NAME 3 | pyside\-uic \- DESCRIPTION... 4 | .SH DESCRIPTION 5 | .SS "Usage:" 6 | .IP 7 | pyside\-uic [options] 8 | .SS "Options:" 9 | .TP 10 | \fB\-\-version 11 | show program's version number and exit 12 | .TP 13 | .BI \-h\fB \fR,\fB \-\-help 14 | show this help message and exit 15 | .TP 16 | .BI \-o FILE \fR, \-\-output=\fIFILE 17 | write generated code to FILE instead of stdout 18 | .TP 19 | .BI \-x \fR, \-\-execute 20 | generate extra code to test and display the class 21 | .TP 22 | .BI \-d \fR, \-\-debug 23 | show debug output 24 | .TP 25 | .BI \-i N\fR, \-\-ident=N 26 | set indent width to N spaces, tab if N is 0 (default: 4) 27 | .SH COPYRIGHT 28 | Copyright \(co 2010 Nokia Corporation and/or its subsidiary(\fB\-ies\fR) 29 | .SH AUTHOR 30 | .PP 31 | This manpage was written by Marcelo Lira , on the 29. December 2010. 32 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/uiparser.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/uiparser.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/uiparser.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/uiparser.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/widget-plugins/__init__.py -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/phonon.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # 6 | # Contact: PySide team 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # version 2 as published by the Free Software Foundation. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | # 02110-1301 USA 21 | 22 | # If pluginType is MODULE, the plugin loader will call moduleInformation. The 23 | # variable MODULE is inserted into the local namespace by the plugin loader. 24 | pluginType = MODULE 25 | 26 | 27 | # moduleInformation() must return a tuple (module, widget_list). If "module" 28 | # is "A" and any widget from this module is used, the code generator will write 29 | # "import A". If "module" is "A[.B].C", the code generator will write 30 | # "from A[.B] import C". Each entry in "widget_list" must be unique. 31 | def moduleInformation(): 32 | return "PySide.phonon", ("Phonon.SeekSlider", "Phonon.VideoPlayer", "Phonon.VolumeSlider") 33 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/phonon.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/widget-plugins/phonon.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/phonon.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/widget-plugins/phonon.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/qtdeclarative.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2010 Riverbank Computing Limited. 5 | # 6 | # Contact: PySide team 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # version 2 as published by the Free Software Foundation. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | # 02110-1301 USA 21 | 22 | # If pluginType is MODULE, the plugin loader will call moduleInformation. The 23 | # variable MODULE is inserted into the local namespace by the plugin loader. 24 | pluginType = MODULE 25 | 26 | 27 | # moduleInformation() must return a tuple (module, widget_list). If "module" 28 | # is "A" and any widget from this module is used, the code generator will write 29 | # "import A". If "module" is "A[.B].C", the code generator will write 30 | # "from A[.B] import C". Each entry in "widget_list" must be unique. 31 | def moduleInformation(): 32 | return "PySide.QtDeclarative", ("QDeclarativeView", ) 33 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/qtdeclarative.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/widget-plugins/qtdeclarative.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/qtdeclarative.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/widget-plugins/qtdeclarative.pyo -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/qtwebkit.py: -------------------------------------------------------------------------------- 1 | # This file is part of the PySide project. 2 | # 3 | # Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies). 4 | # Copyright (C) 2009 Riverbank Computing Limited. 5 | # Copyright (C) 2009 Torsten Marek 6 | # 7 | # Contact: PySide team 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License 11 | # version 2 as published by the Free Software Foundation. 12 | # 13 | # This program is distributed in the hope that it will be useful, but 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | # 02110-1301 USA 22 | 23 | 24 | # If pluginType is MODULE, the plugin loader will call moduleInformation. The 25 | # variable MODULE is inserted into the local namespace by the plugin loader. 26 | pluginType = MODULE 27 | 28 | 29 | # moduleInformation() must return a tuple (module, widget_list). If "module" 30 | # is "A" and any widget from this module is used, the code generator will write 31 | # "import A". If "module" is "A[.B].C", the code generator will write 32 | # "from A[.B] import C". Each entry in "widget_list" must be unique. 33 | def moduleInformation(): 34 | return "PySide.QtWebKit", ("QWebView", ) 35 | -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/qtwebkit.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/widget-plugins/qtwebkit.pyc -------------------------------------------------------------------------------- /renderthreads/lib/third_party/pysideuic/widget-plugins/qtwebkit.pyo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/lib/third_party/pysideuic/widget-plugins/qtwebkit.pyo -------------------------------------------------------------------------------- /renderthreads/media/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/media/__init__.py -------------------------------------------------------------------------------- /renderthreads/media/fonts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/media/fonts/__init__.py -------------------------------------------------------------------------------- /renderthreads/media/fonts/futura-lt-light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/media/fonts/futura-lt-light.ttf -------------------------------------------------------------------------------- /renderthreads/media/icons/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/media/icons/__init__.py -------------------------------------------------------------------------------- /renderthreads/media/icons/icn_renderthreads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/media/icons/icn_renderthreads.png -------------------------------------------------------------------------------- /renderthreads/media/icons/renderthreads_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/media/icons/renderthreads_header.png -------------------------------------------------------------------------------- /renderthreads/media/ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmwagener/renderthreads/7acca7c4b1a056ea63b2abe54272917c61077d55/renderthreads/media/ui/__init__.py -------------------------------------------------------------------------------- /renderthreads/renderthreads.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | """ 4 | renderthreads 5 | ========================================== 6 | 7 | GUI to start threaded nuke rendering. 8 | 9 | To use it execute the following script in your Nuke 10 | Script Editor. 11 | 12 | .. code:: 13 | 14 | from renderthreads import renderthreads 15 | reload(renderthreads) 16 | 17 | #run 18 | renderthreads.run(dev = True, dock_it = True) 19 | 20 | ----------------------- 21 | Current Status: beta 22 | ----------------------- 23 | 24 | **Author:** `Timm Wagener `_ 25 | """ 26 | 27 | 28 | # Add tool root path 29 | # ------------------------------------------------------------------ 30 | # import 31 | import sys 32 | import os 33 | 34 | # tool_root_path 35 | tool_root_path = os.path.abspath(os.path.dirname(__file__)) 36 | sys.path.append(tool_root_path) 37 | 38 | 39 | # Import 40 | # ------------------------------------------------------------------ 41 | # python 42 | import functools 43 | import logging 44 | # PySide 45 | from PySide import QtGui 46 | from PySide import QtCore 47 | from PySide import QtUiTools 48 | 49 | 50 | # Import variable 51 | do_reload = True 52 | 53 | 54 | # renderthreads 55 | 56 | # lib 57 | 58 | # renderthreads_globals 59 | from lib import renderthreads_globals 60 | if(do_reload): 61 | reload(renderthreads_globals) 62 | 63 | # renderthreads_logging 64 | from lib import renderthreads_logging 65 | if(do_reload): 66 | reload(renderthreads_logging) 67 | 68 | # renderthreads_gui_setup 69 | from lib import renderthreads_gui_setup 70 | if(do_reload): 71 | reload(renderthreads_gui_setup) 72 | 73 | # renderthreads_mvc_setup 74 | from lib import renderthreads_mvc_setup 75 | if(do_reload): 76 | reload(renderthreads_mvc_setup) 77 | 78 | # renderthreads_services_setup 79 | from lib import renderthreads_services_setup 80 | if(do_reload): 81 | reload(renderthreads_services_setup) 82 | 83 | # renderthreads_threads 84 | from lib import renderthreads_threads 85 | if(do_reload): 86 | reload(renderthreads_threads) 87 | 88 | # lib.gui 89 | 90 | # renderthreads_gui_helper 91 | from lib.gui import renderthreads_gui_helper 92 | if(do_reload): 93 | reload(renderthreads_gui_helper) 94 | 95 | # renderthreads_dock_widget 96 | from lib.gui import renderthreads_dock_widget 97 | if(do_reload): 98 | reload(renderthreads_dock_widget) 99 | 100 | # lib.mvc 101 | 102 | # renderthreads_model_context_menu 103 | from lib.mvc import renderthreads_model_context_menu 104 | if(do_reload): 105 | reload(renderthreads_model_context_menu) 106 | 107 | 108 | # Globals 109 | # ------------------------------------------------------------------ 110 | TITLE = renderthreads_globals.TITLE 111 | # Pathes 112 | UI_PATH = renderthreads_globals.UI_PATH 113 | 114 | INITIAL_LOGGING_LEVEL = renderthreads_globals.INITIAL_LOGGING_LEVEL 115 | 116 | INITIAL_THREAD_INTERVAL = renderthreads_globals.INITIAL_THREAD_INTERVAL 117 | 118 | 119 | # form_class, base_class 120 | # ------------------------------------------------------------------ 121 | # ui_file 122 | ui_file_name = 'renderthreads.ui' 123 | ui_file = os.path.join(UI_PATH, ui_file_name) 124 | 125 | # form_class, base_class 126 | form_class, base_class = renderthreads_gui_helper.load_ui_type(ui_file) 127 | 128 | 129 | # RenderThreads class 130 | # ------------------------------------------------------------------ 131 | class RenderThreads(form_class, base_class): 132 | """ 133 | RenderThreads class. 134 | """ 135 | 136 | # Signals 137 | # ------------------------------------------------------------------ 138 | 139 | # command object signals to connect with RenderCommand instances 140 | # in the queue. The signals are defined here in the main wdgt 141 | # since a new context menu instance is created at each right 142 | # click in the nodes view. The instance signals here remain 143 | # the same self 144 | sgnl_command_set_enabled = QtCore.Signal(bool) 145 | sgnl_command_set_enabled_for_identifier = QtCore.Signal(str, bool) 146 | sgnl_command_set_timeout = QtCore.Signal(int) 147 | sgnl_command_set_display_shell = QtCore.Signal(int) 148 | sgnl_command_set_log_exitcode_errors_only = QtCore.Signal(int) 149 | sgnl_command_terminate_process = QtCore.Signal() 150 | sgnl_command_terminate_process_for_identifier = QtCore.Signal(str) 151 | 152 | # Create and initialize 153 | # ------------------------------------------------------------------ 154 | def __new__(cls, *args, **kwargs): 155 | """ 156 | RenderThreads instance factory. 157 | """ 158 | 159 | # delete and cleanup old instances 160 | renderthreads_gui_helper.check_and_delete_wdgt_instances_with_class_name(cls.__name__) 161 | renderthreads_gui_helper.check_and_delete_wdgt_instances_with_class_name(renderthreads_dock_widget.RenderThreadsDockWidget.__name__) 162 | 163 | # renderthreads_instance 164 | renderthreads_instance = super(RenderThreads, cls).__new__(cls, args, kwargs) 165 | 166 | return renderthreads_instance 167 | 168 | def __init__(self, 169 | dev=False, 170 | dock_it=True, 171 | parent=renderthreads_gui_helper.get_nuke_main_window()): 172 | """ 173 | Customize instance. 174 | """ 175 | 176 | # super and objectName 177 | # ------------------------------------------------------------------ 178 | # super 179 | self.parent_class = super(RenderThreads, self) 180 | self.parent_class.__init__(parent) 181 | 182 | # setObjectName 183 | self.setObjectName(self.__class__.__name__) 184 | 185 | # instance variables 186 | # ------------------------------------------------------------------ 187 | # dock_it 188 | self.dock_it = dock_it 189 | 190 | # dev 191 | self.dev = dev 192 | 193 | # thread_manager 194 | self.thread_manager = renderthreads_threads.ThreadManager() 195 | 196 | # Init procedure 197 | # ------------------------------------------------------------------ 198 | # setup_threads 199 | self.thread_manager.setup_threads(thread_interval=INITIAL_THREAD_INTERVAL) 200 | 201 | # setupUi 202 | self.setupUi(self) 203 | 204 | # setup_additional_ui 205 | renderthreads_gui_setup.setup_additional_ui(self) 206 | 207 | # setup_mvc 208 | renderthreads_mvc_setup.setup_mvc(self) 209 | 210 | # setup_services 211 | renderthreads_services_setup.setup_services(self) 212 | 213 | # connect_context_menus 214 | self.connect_context_menus() 215 | 216 | # logger 217 | self.logger = renderthreads_logging.get_logger(self.__class__.__name__) 218 | # te_log_handler 219 | self.te_log_handler = renderthreads_logging.get_handler(self.te_log) 220 | self.logger.addHandler(self.te_log_handler) 221 | 222 | # run_tests 223 | self.run_tests() 224 | 225 | # dock_it 226 | if (self.dock_it): 227 | renderthreads_gui_helper.make_dockable(self) 228 | 229 | # Context Menus 230 | # ------------------------------------------------------------------ 231 | def connect_context_menus(self): 232 | """ 233 | Connect context menus. This didnt fit in the 234 | renderthreads_mvc_setup module because of implicit 235 | first argument of pyside context menu signal. 236 | """ 237 | 238 | # nodes_view 239 | self.nodes_view.customContextMenuRequested.connect(self.display_nodes_context_menu) 240 | 241 | def display_nodes_context_menu(self, pos): 242 | """ 243 | Create and display nodes model context menu. 244 | """ 245 | 246 | # context_menu 247 | context_menu = renderthreads_model_context_menu.NodesContextMenu(dev=self.is_dev(), 248 | parent=self) 249 | context_menu.set_view_and_model(self.nodes_view) 250 | context_menu.set_main_widget(self) 251 | context_menu.popup(self.nodes_view.mapToGlobal(pos)) 252 | 253 | # Getter & Setter 254 | # ------------------------------------------------------------------ 255 | def is_dev(self): 256 | """ 257 | Return developer status of app. 258 | """ 259 | 260 | return self.dev 261 | 262 | # Slots 263 | # ------------------------------------------------------------------ 264 | @QtCore.Slot(str, int) 265 | def log(self, msg, logging_level): 266 | """ 267 | Log msg with self.logger. This is 268 | usefull because uncoupled classes 269 | can log on the main logger without 270 | being closely coupled using signals 271 | and slots. 272 | """ 273 | 274 | # log 275 | self.logger.log(logging_level, msg) 276 | 277 | @QtCore.Slot(list, int) 278 | def readd_job(self, command_object_list, exitcode): 279 | """ 280 | Check if job should be readded to the 281 | queue and if yes, do so. 282 | """ 283 | 284 | # command_object 285 | # Only wrapped in type list to avaoid sgnl error. 286 | # Always contains one RenderCommand item. 287 | command_object = command_object_list[0] 288 | 289 | # check exitcode 290 | if (exitcode != 0): 291 | 292 | # command_object enabled? 293 | if (command_object.get_enabled()): 294 | 295 | # do_readd 296 | do_readd = self.sldr_readd_broken_job_count.get_value() 297 | 298 | # check do_readd 299 | if (do_readd): 300 | 301 | # max_readd_count 302 | max_readd_count = self.sldr_readd_broken_job_count.get_value() 303 | 304 | # check readd_count 305 | if (command_object.get_readd_count() < max_readd_count): 306 | 307 | try: 308 | 309 | # increment_readd_count 310 | command_object.increment_readd_count() 311 | 312 | # increment progressbar range 313 | self.pbar_render.increment_range() 314 | command_object.renderthreads_node.progressbar.increment_range() 315 | 316 | # add 317 | self.thread_manager.add_to_queue(command_object) 318 | 319 | # log 320 | self.logger.critical('Readded {0} ({1})'.format(command_object.logger_name, 321 | exitcode)) 322 | except: 323 | 324 | # log 325 | self.logger.critical('Error readding command object to queue') 326 | 327 | # Misc 328 | # ------------------------------------------------------------------ 329 | def dummy_method(self, msg='dummy'): 330 | """ 331 | Dummy method. 332 | """ 333 | 334 | # log 335 | self.logger.debug('{0}'.format(msg)) 336 | 337 | def dummy_method_silent(self): 338 | """ 339 | Dummy method without output. 340 | """ 341 | 342 | pass 343 | 344 | # Test 345 | # ------------------------------------------------------------------ 346 | def run_tests(self): 347 | """ 348 | Suite of test methods. 349 | """ 350 | 351 | # log 352 | self.logger.debug('\n\nExecute test methods:\n-----------------------------') 353 | 354 | # test methods start here 355 | # ------------------------------------------------------------------ 356 | # ------------------------------------------------------------------ 357 | 358 | # dummy_method 359 | self.dummy_method() 360 | 361 | # ------------------------------------------------------------------ 362 | # ------------------------------------------------------------------ 363 | # test methods end here 364 | 365 | # log 366 | self.logger.debug('\n\n-----------------------------\nFinished test methods.') 367 | 368 | # Events 369 | # ------------------------------------------------------------------ 370 | def stop_all_threads_and_timer(self): 371 | """ 372 | Try to stop all threads and timers that RenderThreads started. 373 | This method is ment to be used in a closeEvent. 374 | """ 375 | 376 | try: 377 | # thread_manager threads 378 | self.thread_manager.stop_threads() 379 | 380 | # stop_services 381 | renderthreads_services_setup.stop_services(self) 382 | 383 | except: 384 | # log 385 | self.logger.debug('Error stopping threads for queue.') 386 | 387 | def closeEvent(self, event): 388 | """ 389 | Customized closeEvent. 390 | """ 391 | 392 | # log 393 | self.logger.debug('Close Event') 394 | 395 | # stop_all_threads_and_timer 396 | self.stop_all_threads_and_timer() 397 | 398 | # parent close event 399 | self.parent_class.closeEvent(event) 400 | 401 | 402 | # Run 403 | # ------------------------------------------------------------------ 404 | def run(dev=False, dock_it=True): 405 | """ 406 | Standardized run() method. 407 | """ 408 | 409 | # renderthreads_instance 410 | renderthreads_instance = RenderThreads(dev=dev, dock_it=dock_it) 411 | renderthreads_instance.show() 412 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | sphinx_rtd_theme 4 | sphinx_bootstrap_theme 5 | mock -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | renderthreads 4 | ========================================== 5 | 6 | Package that enables easy command-line 7 | multithreaded rendering for Nuke. 8 | """ 9 | 10 | # Import 11 | # ------------------------------------------------------------------ 12 | from setuptools import setup 13 | from setuptools import find_packages 14 | 15 | # Setup 16 | # ------------------------------------------------------------------ 17 | setup(name='renderthreads', 18 | version='0.3.5', 19 | description='Package that enables easy command-line multithreaded rendering for Nuke.', 20 | url='https://github.com/timmwagener/renderthreads', 21 | author='Timm Wagener', 22 | author_email='wagenertimm@gmail.com', 23 | license='MIT', 24 | keywords='Foundy TheFoundry Nuke Pipeline Compositing Filmakademie Timm Wagener Multithreading Commandline Rendering', 25 | packages=find_packages(), 26 | include_package_data=True, 27 | classifiers=['Development Status :: 4 - Beta', 28 | 'Intended Audience :: End Users/Desktop', 29 | 'Operating System :: Microsoft :: Windows', 30 | 'Programming Language :: Python', 31 | 'Topic :: Software Development', 32 | 'Topic :: Utilities', 33 | 'Topic :: Multimedia', 34 | 'Topic :: Multimedia :: Graphics', 35 | 'Topic :: Multimedia :: Graphics :: 3D Rendering', 36 | 'Topic :: Multimedia :: Graphics :: Graphics Conversion', 37 | 'Topic :: Multimedia :: Graphics :: Presentation', 38 | 'Topic :: Multimedia :: Video', 39 | 'Topic :: Multimedia :: Video :: Conversion', 40 | 'Topic :: Multimedia :: Video :: Display', 41 | 'Topic :: Multimedia :: Video :: Non-Linear Editor', 42 | 'Topic :: Documentation :: Sphinx',], 43 | zip_safe = False) 44 | --------------------------------------------------------------------------------