python.tk_houdini.ui_generation
¶
Module Contents¶
Classes¶
Wraps around a single command that you get from engine.commands |
|
Base class for interface elements that trigger command actions. |
|
Creates panels and installs them into the session. |
|
Base class for interface elements that trigger command actions. |
|
Base class for interface elements that trigger command actions. |
Functions¶
|
Do any required formatting. Typically before writing to disk. |
|
Jump from context to Fs |
|
Jump from context to Sg |
Checks to see if the current file has changed. If it has, try to set the |
|
|
Write the full element tree to the supplied xml file. |
Ensures a timer is running to periodically check for current file change. |
|
|
Returns a list of AppCommands for the engine’s registered commands. |
|
Returns a list of AppCommands for the engine’s registered panels. |
|
Returns a wrapped widget for use in a houdini python panel. |
Show Value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
engine = None menu_items = [] try: import tank.platform.engine engine = tank.platform.engine.current_engine() if engine: # the commands to display in this menu cmds = engine._menu.%s() # build the list that houdini expects for cmd in cmds: menu_items.extend([cmd.get_id(), cmd.name]) else: menu_items.extend(["tk.houdini.menu.no.shotgun", "Toolkit is disabled - Click for details"]) except Exception as e: import traceback error = traceback.format_exc() if engine: # store the exception on the menu object for display in the callback engine._menu._menu_error = Exception(str(e) + ". " + error) # just give houdini a special error item for the menu menu_items.extend( ["tk.houdini.menu.error", "Menu Error. Click for Details..."]) else: if engine: engine._menu._menu_error = None finally: return menu_items
Show Value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
import hou engine = None try: import tank.platform.engine # get the selected menu id command_id = kwargs["selectedtoken"] engine = tank.platform.engine.current_engine() # special id if there is no shotgun context/engine if command_id == "tk.houdini.menu.no.shotgun": msg = ( "It appears as though you are not currently working in a Shotgun " "context. There is no Shotgun for Houdini Engine running so no " "menu or shelf items are available. In order to restart the Shotgun " "integration, please close and reopen Houdini or choose a file " "from your Shotgun project in the 'Recent Files' menu. If you " "believe this to be an error, please contact your support team." ) hou.ui.displayMessage(msg, severity=hou.severityType.Warning) # special id if errors occurred and they clicked for more info if command_id == "tk.houdini.menu.error": # try to locate the exception on the menu object and raise it if engine._menu._menu_error: raise engine._menu._menu_error # no stored exception, tell the user to look in the shell else: raise Exception("The error message should show up in your shell.") # the special context item. launch the context in browser if command_id == engine._menu._context_menu_item_id: from tank.platform.qt import QtCore, QtGui url = engine.context.shotgun_url QtGui.QDesktopServices.openUrl(QtCore.QUrl(url)) # should be a registered command. launch it else: engine.launch_command(command_id) except Exception as e: # handle any exceptions raised during menu building msg = "An error occurred building the Shotgun menu...\n\n%s" % (e,) if engine: hou.ui.displayMessage(msg, severity=hou.severityType.Error) else: print(msg)
-
_g_launch_script
= Multiline-String[source]¶ Show Value
1 2 3 4 5 6 7 8 9 10 11 12
import hou import tank.platform.engine engine = tank.platform.engine.current_engine() if engine is None or not hasattr(engine, 'launch_command'): msg = "Shotgun: Houdini engine is not loaded." if hou.isUIAvailable(): hou.ui.displayMessage(msg) else: print(msg) else: engine.launch_command('%s')
-
_g_panel_script
= Multiline-String[source]¶ Show Value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
from sgtk.platform.qt import QtCore, QtGui class NoPanelWidget(QtGui.QWidget): def __init__(self, msg, error=None): super(NoPanelWidget, self).__init__() sg_icon_path = '%s' sg_icon = QtGui.QLabel() try: sg_pixmap = QtGui.QPixmap(sg_icon_path).scaledToWidth(64, QtCore.Qt.SmoothTransformation) sg_icon.setPixmap(sg_pixmap) except: pass msg_lbl = QtGui.QLabel(msg) msg_lbl.setWordWrap(True) if error: error_txt = QtGui.QTextEdit(error) error_txt.setReadOnly(True) h_layout = QtGui.QHBoxLayout() h_layout.setSpacing(5) h_layout.addWidget(sg_icon) h_layout.addWidget(msg_lbl) h_layout.setStretchFactor(msg_lbl, 10) v_layout = QtGui.QVBoxLayout(self) v_layout.setContentsMargins(10, 10, 10, 10) v_layout.setSpacing(15) v_layout.addStretch() v_layout.addLayout(h_layout) if error: v_layout.addWidget(error_txt) v_layout.addStretch() def createInterface(): try: import tank.platform.engine except ImportError: return NoPanelWidget( "It looks like you're running Houdini outside of a Shotgun " "context. Next time you launch Houdini from within a Shotgun " "context, you will see the '%s' panel here." ) try: engine = tank.platform.engine.current_engine() panel_info = engine.get_panel_info('%s') panel_widget = engine.get_wrapped_panel_widget( engine, panel_info['widget_class'], panel_info['bundle'], panel_info['title'], ) panel_widget.apply_stylesheet() except Exception: import traceback return NoPanelWidget( "There was a problem loading this panel! The error message " "is provided below.", error=traceback.format_exc() ) pane_tab = kwargs["paneTab"] # it appears that sometimes the pane_tab available here is not the one # we're interested in. sometimes it is not set and sometimes it is a # different tab all together. so just check to make sure it is set and # make sure it has the 'setLabel' method available. that at least implies # that it is a python panel if pane_tab and hasattr(pane_tab, 'setLabel'): title = panel_info.get('title') if title: pane_tab.setLabel(title) # We're caching here based on title, because it's the # bit of information we have that's reliably available # from all of the various methods of showing this # pane tab. We cache the pane tab's name so that if a # second invokation of showing this particular panel is # triggered, we just show that panel rather than opening # a second instance. engine._pane_cache[title] = pane_tab.name() return panel_widget
-
class
AppCommand
(name, command_dict)[source]¶ Bases:
object
Wraps around a single command that you get from engine.commands
-
class
AppCommandsMenu
(engine, commands)[source]¶ Bases:
python.tk_houdini.ui_generation.AppCommandsUI
Base class for interface elements that trigger command actions.
Constructs a top-level “Shotgun” menu.
Same logic for both the static and dynamic menu.
- Returns
tuple containing the root element and the shotgun menu item
Construct the dynamic Shotgun menu for toolkit in Houdini 15+.
- Parameters
xml_path – The path to the xml file to store the menu definitions
Construct the static Shotgun menu for older versions of Houdini.
- Parameters
xml_path – The path to the xml file to store the menu definitions
-
_get_commands_by_app
(self)[source]¶ This method returns a flattened list of registered app commands.
This is called directly as a part of the dynamic menu generation code as houdini builds submenus when the user clicks on the top-level Shotgun menu. This should execute quickly.
-
_get_context_commands
(self)[source]¶ This method returns a modified list of context commands.
This is called directly as a part of the dynamic menu generation code as houdini builds submenus when the user clicks on the top-level Shotgun menu. This should execute quickly.
-
_itemNode
(self, parent, label, id)[source]¶ Constructs a static menu item for the supplied parent.
Adds the script path and args which houdini uses as the callback.
Constructs a submenu for the supplied parent.
Create the Shotgun Menu
-
class
AppCommandsPanelHandler
(engine, commands, panel_commands)[source]¶ Bases:
python.tk_houdini.ui_generation.AppCommandsUI
Creates panels and installs them into the session.
-
class
AppCommandsShelf
(engine, commands=None, name='Shotgun', label='Shotgun')[source]¶ Bases:
python.tk_houdini.ui_generation.AppCommandsUI
Base class for interface elements that trigger command actions.
-
create_shelf
(self, shelf_file)[source]¶ Creates a Shotgun shelf with a tool button for each command.
- shelf_file:
The xml file where the shelf definition will be written
-
-
class
AppCommandsUI
(engine, commands)[source]¶ Bases:
object
Base class for interface elements that trigger command actions.
-
_group_commands
(self)[source]¶ This method provides a consistent method for organizing commands.
Used by the menu and shelf classes to collect the registered commands into groups. The method returns a tuple with the first item being a list of context-specific commands, the second item is a dictionary of commands organized by the app name, and the third item is a list of favourite commands as defined in the settings.
-
-
_on_file_change_timeout
()[source]¶ Checks to see if the current file has changed. If it has, try to set the new context for the file.
-
_write_xml
(xml, xml_path)[source]¶ Write the full element tree to the supplied xml file.
- Parameters
xml (string) – The xml to write to disk
xml_path (string) – The path to write the xml.
Also ensures the directory exists before writing the file.
-
ensure_file_change_timer_running
()[source]¶ Ensures a timer is running to periodically check for current file change.
-
get_registered_commands
(engine)[source]¶ Returns a list of AppCommands for the engine’s registered commands.
- Parameters
engine – The engine to return registered commands for
NOTE: This method currently returns additional panel commands that are not registered, but always present in the shotgun menu and shelves. Those commands are:
“Jump to Shotgun” “Jump to File System”
-
get_registered_panels
(engine)[source]¶ Returns a list of AppCommands for the engine’s registered panels.
- Parameters
engine – The engine to return registered panel commands for
-
get_wrapped_panel_widget
(engine, widget_class, bundle, title)[source]¶ Returns a wrapped widget for use in a houdini python panel.
- Parameters
engine – The engine instance.
widget_class – The widget class to wrap.
bundle – The bundle associated with the panel being wrapped.
title – The title to display for this panel.
Here we subclass the panel widget in order to hijack the first paint event. There, we force clear the parent’s stylesheet and reset the widget with the bundled stylesheet if there is one. This prevents houdini’s parenting from cramping the panel’s style. We also filter for change events to detect when something else attempts to change the style so we can force it back to the bundled style. The first paint event isn’t sufficient for panels saved in desktops, but detecting style change seems to do the trick.