Hooking up Python commands to a QT Pushbutton

EDIT: Forgot to mention that I’m working with Maya :slight_smile:

Is there an easy way to have a button, made in QT Designer, execute a function?

For example:
I have a window with just one button. When the button is clicked, I would like the PiratePrint function to be called.



from maya import OpenMayaUI as omui
from PySide.QtCore import * 
from PySide.QtGui import * 
from PySide.QtUiTools import *
from shiboken import wrapInstance

import maya.cmds as cmds

def CreateUI():
	mayaMainWindowPtr = omui.MQtUtil.mainWindow()
	mayaMainWindow = wrapInstance(long(mayaMainWindowPtr), QWidget)

	loader = QUiLoader()
	file = QFile("D:/myAwesomeButton.ui")
	file.open(QFile.ReadOnly)

	ui = loader.load(file, parentWidget = mayaMainWindow)
	file.close()

	ui.setWindowFlags(Qt.Window)
	ui.show()

def PiratePrint():
	print "Haarrrrrr, this button be clicked!"

CreateUI()


The window shows up just fine. But what exactly do I need to do in QT Designer so that when the button is clicked, PiratePrint is called? From what I’ve found online, adding a Dynamic Property with “-command PiratePrint” to the button should work. But it doesn’t :slight_smile:

Is there something else I need to do in the script to connect the button to the function?

Any help is appreciated, because so far I’ve found that manually coding my interfaces offers way more flexibility than using QT Designer UIs. But then again if I can get it working once, building UIs in QT Designer would definitely speed up my workflow.

After some more searching and some help from a friend, I found a way to make it work. So just adding the solution here in case anyone else has the same problem.

Qt works with a signal & slot system. A QPushButton has several signals it sends out, i.e. when it is clicked, pressed or released. It is then up to you to connect such a signal to a slot (one of your functions). So in my case, with the script I have here, it would be:

ui.btnMyAwesomeButton.clicked.connect(PiratePrint)

I added that line to my CreateUI function and that seemed to work fine.

If you ever need to connect a function that requires a pre-determined input value, you can also use lambda.

For instance, if you had a pirate button AND a ninja button:

def whoAmI( inName ):
    print "I am a {0}.".format( inName )

 ui.btnMyPirateButton.clicked.connect( lambda a: whoAmI( "Pirate" ) )
 ui.btnMyNinjaButton.clicked.connect( lambda a: whoAmI( "Ninja" ) )

Might be useful in the future :wink:

G

Personally I prefer functools.partial over lambda for readability.

from functools import partial
funcA = partial(whoAmI, "Pirate")
funcB = partial(whoAmI, inName="Ninja")

ui.btnA.clicked.connect(funcA)
ui.btnB.clicked.connect(funcB)

Yes, I forgot about that. Thanks for the tip!