Panel in QtPy

Custom Panel in QtPy in Nuke

Create your Panel with Python and QtPy in Nuke

In this quick tutorial you will learn how to create a Custom Panel with QtPy in Nuke. First of all, if you don't get it already, please download file Qt.py and we will see how to add it in Nuke.

You can download the Gizmo for Nuke here (special thanks to Ernest Dios):
Download Example Download file Qt.py

At this link you can find another example with QtPy, how to change Label and/or Autolabel of your selected node



Useful Links



Why QtPy?

Qt is a cross-platform application framework and widget toolkit for creating classic and embedded graphical user interfaces, and applications that run on various software and hardware platforms with little or no change in the underlying codebase, while still being a native application with native capabilities and speed. Qt is currently being developed both by The Qt Company, a publicly listed company, and the Qt Project under open-source governance, involving individual developers and firms working to advance Qt. Qt is available with both proprietary[4] and open source GPL 2.0, GPL 3.0, and LGPL 3.0 licenses.

PyQt provides two different APIs, the first of which provides QStrings, QVariants, etc as is in Python. The new API 2 provides automatic conversion between the Qt classes and respective native Python datatypes and is much more Pythonic in nature. PyQt on Python 2.x defaults to API 1, while PyQt on Python 3 defaults to API 2. PySide only supports PyQt's API 2 for details. Therefore Qt classes such as QStrings, QStringLists, and QVariants are not available on PySide. Instead, you should simply use native Python datatypes. If you're porting code from PyQt, you might want to first modify the PyQt code to use API 2 (using a sip.setapi(class,ver) call before importing PyQt4), and only after getting that change working, change the imports to use PySide instead.



How to Install Qt.py

The easiest way to install this file in Nuke is to place it manually:


Windows: C:\Program Files\Nuke10.0v1\lib\site-packages
Linux: /usr/local/Nuke10.0v1/lib/python2.7/site-packages
macOS: /Applications/Nuke10.0v2/Nuke10.0v2.app/Contents/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages

Now you can install Qt Creator from this link. And let's start!
Open Qt Creator, create a New Project and select the type Qt Designer Form (ui).


Now Choose the Template. In my case Widget.


This is the window that you will see. Now just drag and drop the elements that you want to add to your Panel. Modify the name, the size and the other attributes of the elements.


This is the result in my case. Just save the file as "form.ui".





In Nuke, open the Script Editor and copy and paste this code.
In the variable file_interface I'm loading the interface created before in Qt Creator. Please, modify the path /Users/path/Desktop/ with yours. In the Class it's declared the panel with the relative title.
At the end, it's showed the Panel.

import os
from Qt import QtWidgets
from Qt import QtCompat
from Qt import QtGui

file_interface = os.path.join("/Users/path/Desktop/", "form.ui")

#---------------------------------------------------------
class MyWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.main_widget = QtCompat.loadUi(file_interface)
        self.setCentralWidget(self.main_widget)
        self.setWindowTitle("WindowTitle")

#---------------------------------------------------------

my_window = MyWindow()
my_window.show()

This is the Panel created from the previous script.


Now, in this example we create some random nodes: Blur nodes, Merge, Transform, Grade...


With this code we print all the nodes in the Node Graph in Nuke, sorted by the name. If we execute the code in the Script Editor, result in my case will be: # Result: ['Blur1', 'Blur2', 'Grade1', 'Grade2', 'Merge1', 'Transform1', 'Viewer1']

nodes = []
def create_list_nodes():
    #populate the list nodes
    for n in nuke.allNodes():
        name = n.name()
        nodeclass = n.Class()
    
        nodes.append(name)
    
    #sort the list
    nodes.sort()

    #print
    print nodes
#---------------------------------------------------------

create_list_nodes()

Now let's select node named Grade1 and apply a zoom effect on it.

#SELECT node 'Grade1'
def select_node(name_node):
    n = nuke.toNode(name_node)
    n.knob('selected').setValue(True)
    #manipulate the Node Graph. Zoom on the  Selected Node
    nuke.zoom( 2, [ n.xpos(), n.ypos() ])


select_node("Grade1")

Integrating the three scripts, we will obtain this:

import os
#please, insert file Qt.py in this folder:
#Windows: C:\Program Files\Nuke10.0v1\lib\site-packages
#Linux: /usr/local/Nuke10.0v1/lib/python2.7/site-packages
#macOS:/Applications/Nuke10.0v2/Nuke10.0v2.app/Contents/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages

#Guide: 
#www.fredrikaverpil.github.io/2016/07/25/developing-with-qt-py/
#www.nukepedia.com/prepare-for-qt5

from Qt import QtWidgets
from Qt import QtCompat
from Qt import QtGui

#load the file for the interface
file_interface = os.path.join("/Users/path/Desktop/", "form.ui")

#---------------------------------------------------------
nodes = []
def create_list_nodes():
    #populate the list nodes
    for n in nuke.allNodes():
        name = n.name()
        nodeclass = n.Class()
    
        nodes.append(name)
    
    #sort the list
    nodes.sort()

create_list_nodes()

#---------------------------------------------------------
class MyWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.main_widget = QtCompat.loadUi(file_interface)
        self.setCentralWidget(self.main_widget)
        self.setWindowTitle("WindowTitle")

        self.load_ui()


    def load_ui(self):
        #self.name = self.main_widget.findChild(QtWidgets.TypeOfElement, "nameOfElement")
        self.menu = self.main_widget.findChild(QtWidgets.QComboBox, "nodes_ComboBox")
        self.menu.addItems(nodes)

        self.button = self.main_widget.findChild(QtWidgets.QPushButton, "select_Button")
        self.button.clicked.connect(self.select_node)


    def select_node(self):
        #Clear all the selected Nodes
        nukescripts.clear_selection_recursive()

        n = nuke.toNode(self.menu.currentText())
        n.knob('selected').setValue(True)
    
        #manipulate the Node Graph. Zoom on the  Selected Node
        nuke.zoom( 2, [ n.xpos(), n.ypos() ])


#---------------------------------------------------------

my_window = MyWindow()
my_window.show()

This code creates a Panel. Inside the panel we can see all the sorted nodes in the Node Graph by the Dropdown menu.


Let's select a node (Merge1) and press the button Select Node



So, we finished this example! It was a really easy exercise, but you can expand it more


Leave a comment