Skip to content

Instantly share code, notes, and snippets.

@herronelou
Created April 7, 2024 22:32
Show Gist options
  • Save herronelou/083dd953ed922c6b7060d0e8b8740982 to your computer and use it in GitHub Desktop.
Save herronelou/083dd953ed922c6b7060d0e8b8740982 to your computer and use it in GitHub Desktop.
Nuke dockable panel example
"""
This script shows how to create a dockable widget in Nuke using PySide2 based on a technique
I used a long time ago in a project.
I think nowadays I would reimplement something akin to nukescripts.panels.registerWidgetAsPanel
that allows custom menu commands and single instances of the widget.
"""
import nuke
import nukescripts
from PySide2 import QtCore, QtGui, QtWidgets
def show_qt_pane(widget_class, title, pane_id):
"""
Show a Qt widget in a Nuke panel.
Parameters
----------
widget_class: str
Widget class to show in the panel. Needs to be the full path to the class, already imported.
Example: "my_module.MyWidget"
title: str
Title of the panel.
pane_id: str
Unique identifier of the panel. Should match what is used when using registerWidgetAsPanel.
"""
# Check if pane already exists.
widgets = find_qt_widgets(pane_id)
if widgets:
# We found at least one instance, show the first one.
widget = widgets[0]
parent_widget = widgets[0].parentWidget()
parent_widget.setCurrentWidget(widget)
parent_widget.activateWindow()
parent_widget.setFocus()
else:
# No instances were found, let's initialize a new one in a new Panel.
panel = nukescripts.PythonPanel(title, pane_id)
widget = nuke.PyCustom_Knob(title, "", "__import__('nukescripts').panels.WidgetKnob({})".format(widget_class))
panel.addKnob(widget)
panel.show()
def find_qt_widgets(widget_name):
"""
Find a Qt widget in Nuke by its name.
Parameters
----------
widget_name: str
Returns
-------
list[QtWidgets.QWidget]
"""
qwindow = get_nuke_main_window()
widgets = qwindow.findChildren(QtWidgets.QWidget, widget_name)
return widgets
def get_nuke_main_window():
"""Returns Nuke's main window"""
app = QtWidgets.QApplication.instance()
for obj in app.topLevelWidgets():
if obj.inherits('QMainWindow') and obj.metaObject().className() == 'Foundry::UI::DockMainWindow':
return obj
return None
# Make an example widget
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super(MyWidget, self).__init__()
layout = QtWidgets.QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0) # Nuke panels already have large margins, remove as much as possible
self.setLayout(layout)
self.label = QtWidgets.QLabel("Hello, World!")
self.text_area = QtWidgets.QTextEdit()
layout.addWidget(self.label)
layout.addWidget(self.text_area)
def show_my_widget():
show_qt_pane("MyWidget", "My Widget", "com.example.MyWidget")
if __name__ == '__main__':
nukescripts.panels.registerWidgetAsPanel('MyWidget', 'This is my Widget', 'com.example.MyWidget')
nuke.menu('Nuke').addCommand('Custom/Show My Widget', show_my_widget)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment