2010
11.08

Some PyQt for the day

Here’s a way to add popup tool tips to the 3d view ports in Maya (Based on inspiration from this post)

import sip
import maya.cmds as cmds
import maya.OpenMayaUI as apiUI
from PyQt4 import QtGui, QtCore

class ToolTipFilter(QtCore.QObject):
	'''A simple event filter to catch tooltip events'''
	def eventFilter(self, obj, event):
		if event.type() == QtCore.QEvent.ToolTip:
			QtGui.QToolTip.hideText() #Hide the old tooltip, so that it can move
			QtGui.QToolTip.showText(event.globalPos(), '%04f, %04f'%(event.globalX(), event.globalY()), obj)
			return False
		return True

#Install the event filter into all the model panels
global filter #Have to make the filter object global so it doesnt get garbage collected
filter = ToolTipFilter()

for editor in cmds.lsUI(panels=True): #For soem reason type='modelEditor' won't work...
	if cmds.objectTypeUI(editor)=='modelEditor':
		ptr = apiUI.MQtUtil.findControl(editor)
		viewWidget = sip.wrapinstance(long(ptr), QtCore.QObject)
		viewWidget.installEventFilter(filter)

Here’s some simple code to get the widget with focus, under the cursor, and the main Maya window:

import sip
import maya.cmds as cmds
import maya.OpenMayaUI as apiUI
from PyQt4 import QtGui, QtCore

def getMayaWindow():
	'Get the maya main window as a QMainWindow instance'
	ptr = apiUI.MQtUtil.mainWindow()
	return sip.wrapinstance(long(ptr), QtCore.QObject)
	
def getFocusWidget():
	'Get the currently focused widget'
	return QtGui.qApp.focusWidget()

def getWidgetAtMouse():
	'Get the widget under the mouse'
	currentPos = QtGui.QCursor().pos()
	widget = QtGui.qApp.widgetAt(currentPos)
	return widget

Here’s some handy debug code, this changes the tooltips for all the QWidgets in Maya to display their path, and QObject instance:

import sip
import maya.cmds as cmds
import maya.OpenMayaUI as apiUI
from PyQt4 import QtGui, QtCore

def toQtObject(mayaName):
	'''
    Given the name of a Maya UI element of any type, return the corresponding QWidget or QAction. 
    If the object does not exist, returns None
    '''
	ptr = apiUI.MQtUtil.findControl(mayaName)
	if ptr is None:
		ptr = apiUI.MQtUtil.findLayout(mayaName)
		if ptr is None:
			ptr = apiUI.MQtUtil.findMenuItem(mayaName)
	if ptr is not None:
		return sip.wrapinstance(long(ptr), QtCore.QObject)

#Set the tooltip for all widgets (This takes a little bit)
for widget in cmds.lsUI(dumpWidgets=True):
	try:
		qWidget = toQtObject(widget)
		qWidget.setToolTip('(%s) %s'%(widget, qWidget))
	except:
		pass

Convert a wrapped pyqt object back to a Maya UI path:

apiUI.MQtUtil.fullName( sip.unwrapinstance(widget) )
  1. Hi!
    I just came across your post and wondered if you have any idea if something similar work also with Pyside. They don’t use sip to wrap the QObjects but there own library shiboken. But I could not figure out how I can convert my PySwig object that the MQtUtil class returns to a valid QObject for Pyside. Thanks for any hints or help!

    Greets,
    Carlo

  2. I haven’t looked into it yet, but I’ll let you know if I find anything!

You must be logged in to post a comment.