Pymel and QT using Designer Noob Question

I guess we all have to start somewhere but I’m struggling to get my head round using QT Designer and Pymel.

I’ve created a simple .ui file using designer (see attached) and can load it in Maya using Nathan’s piece of code on his site. (great job btw!) I can see how this can be very useful to quickly get a GUI going. The problem is how do I access the various parts in Maya.

I’ve gone through the Pymel help and can see how I would create something similar like

window()
paneLayout()
textScrollList( numberOfRows=2, allowMultiSelection=False,
append=[‘Eyebrows’, ‘Eyes’, ‘Mouth’, ],
selectItem=‘Eyebrows’, showIndexedItem=1 )
showWindow()

But how would I say reference the textScrollList object if it’s come from the .ui. Or how would I set a script to run if the “Select” button was clicked.

Is there any help or tutorials on using QT in Maya a bit like there is for Pymel.

Thanks for any help on this.

Tim

This tutorial has some info on communicating with Qt created interfaces. It’s for MEL but the functionality is basically the same.

http://www.creativecrash.com/tutorials/using-qt-designer-for-mel-interfaces

I did some testing at work before summer vacation to see if we should start using QtDesigner as standard but right now we decided not to as there are still communication issues between the interface and the scripts in our opinion.

Here is a list of communication paths I compiled when looking at which maya.cmds python command could communicate with which interface object. It started of based on the one found in the tutorial above.

Window (window) -> mc.window(“TestWindow”, q=True, ex=True)
Menu Bar (menu) -> COULD NOT GET WORKING

  • Buttons
    Push Button (button) -> mc.button…
    Radio Button (radioButton) -> mc.radioButton…
    Check Box (checkBox) -> mc.checkBox(“checkBox”, q=True, v=True), mc.checkBox(“checkBox”, e=True, v=False)

  • Input Widgets
    Combo Box (optionMenu) -> COULD NOT GET WORKING
    Line Edit (textField) -> mc.textField(“lineEdit”, q=True, tx=True), mc.textField(“lineEdit”, e=True, tx=“New Text”)
    Spin Box (NONE)
    Double Spin Box (NONE)
    Dial (NONE)
    Horizontal Slider (intSlider) -> mc.intSlider(“horizontalSlider”, q=True, v=True), mc.intSlider(“horizontalSlider”, e=True, v=10)
    Vertical Slider (intSlider) -> mc.intSlider(“verticalSlider”, q=True, v=True), mc.intSlider(“verticalSlider”, e=True, v=10)

  • Item Widgets
    List Widget (textScrollList) -> mc.textScrollList(“listWidget”, q=True, si=True), mc.textScrollList(“listWidget”, e=True, append=[‘one’, ‘two’], selectItem=‘two’)

  • Display Widgets
    Label (text) -> mc.text(“label”, q=True, l=True), mc.text(“label”, e=True, l=“New”)
    Progress Bar (progressBar) -> mc.progressBar(“progressBar”, q=True, pr=True), mc.progressBar(“progressBar”, e=True, pr=50)

  • Containers
    Frame (NONE)
    Group Box (NONE)
    Tab Widget (tabLayout) -> COULD NOT GET WORKING

Most of the QT UI’s i have done have been dynamic to the point where designer is redundant, but i have done a little bit of stuff through designer. Generally ( out of habbit more than anything else ) i tend to hook up the signals through code after loading the ui file in, and have hit no issues using that approach.

If you want any examples of that just drop me a pm and i’ll send some over.

Mike.

maybe this will help a little, copy this into a .py file and place the .ui file in the same dir, then import it into the maya script editor and call the example() method.




from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.uic import *
import sip
import maya.OpenMayaUI as mui
import os

import pymel.core as pm

ui_file = os.path.dirname(__file__) +"\\demo.ui"

class MyWidget(QWidget):
    
    def __init__(self , parent=None):
        QWidget.__init__(self, parent=parent)
        
        ## Create main layout, and load the UI file
        self.primary_layout = QVBoxLayout()
        self.ui = loadUi(ui_file)
        
        ## Add the UI elements to the widget
        self.primary_layout.addWidget(self.ui)
        self.setLayout(self.primary_layout)
        
        ## Hook up the signals to the methods below
        self.connect(self.ui.SelectButton, SIGNAL('clicked()'), self.clickedSelect)
        self.connect(self.ui.SelectionBox, SIGNAL('itemSelectionChanged()'), self.selectionChanged)
    
    
    ## Method which is triggered on the button click
    def clickedSelect(self):
        print "I have just clicked select"
        pm.polySphere()
    
    ## Method which is triggered on list box selection change
    def selectionChanged(self):
        print "selection changed" 
        print self.ui.SelectionBox.currentItem().text()


##----------------------------------------------------------------------------------------------
def getMayaWindow():
    #Get the maya main window as a QMainWindow instance
    ptr = mui.MQtUtil.mainWindow()
    return sip.wrapinstance(long(ptr), QObject)


##----------------------------------------------------------------------------------------------
class MyWindow(QMainWindow):
    'My custom window, which i want to parent to the maya main window'
    def __init__(self, parent=getMayaWindow()):
        #Init my main window, and pass in the maya main window as it's parent
        QMainWindow.__init__(self, parent)
        
        self.widget = MyWidget()
        self.setCentralWidget(self.widget)
        self.setWindowTitle("MyWindow")
        
        self.resize(285,350)

def example():
    window = MyWindow()
    window.show()



Not sure if that helps at all, its been a long day so i hope i have not completely miss-read your question!

Mike Malinowski.

Hey Tim,

It depends on whether you want to use full-blown pyQt, or just use maya’s loadUi stuff.

I’ve got some info on using QT stuff without pyQt -

In that example, there’s a callback on a buttton - the same principle is similar for other types of controls.

the important thing is the name you give to your control in designer - that’s the name you must use to find a control inside maya.

hope this helps

cheers,
chrisg

edit: obviously this isn’t pymel, but might give you some hints.

[QUOTE=Wolfsong;11491]
Combo Box (optionMenu) -> COULD NOT GET WORKING
[/QUOTE]

Hey Erik,

I’ve been using qComboBoxes as optionMenus without any problems. I guess the only thing is to make sure you’re using the “list based” rather than the “model based” version of the combo box.

as for menubars, i’ve had to leave some room at the top of my layout with a spacer, and then add in a menubar with maya.cmds - pretty fugly, but it’s working.

cheers,
chrisg

[QUOTE=chrisg;11497]Hey Erik,

I’ve been using qComboBoxes as optionMenus without any problems. I guess the only thing is to make sure you’re using the “list based” rather than the “model based” version of the combo box.

as for menubars, i’ve had to leave some room at the top of my layout with a spacer, and then add in a menubar with maya.cmds - pretty fugly, but it’s working.

cheers,
chrisg[/QUOTE]
The only other Combo Box in Qt Designer I can see is Font Combo Box.

I’m running Maya 2012 and the Qt Designer that came with it btw.

[QUOTE=Wolfsong;11501]The only other Combo Box in Qt Designer I can see is Font Combo Box.

I’m running Maya 2012 and the Qt Designer that came with it btw.[/QUOTE]

aah, my bad. i was thinking of some other thing. you’re right, there is only one combo box. you can’t go wrong there.

i’ve downloaded the QT stuff (am on a mac at home, so i don’t think designer comes with maya mac), and am running 2012.

i’ve attached an example - see how it goes for you.

import sys
sys.path.append('/Users/chrisg/Desktop')

import comboBoxTestUi
comboBoxTestUi.comboBoxTestUi()

cheers,
chrisg

Thanks, I’ll take a look at it at work on Monday.

Thanks, it works fine. Don’t know what I did wrong when I tested, but didn’t put much time into it.

Still, like Mike said, most interfaces are dynamic so we can’t use Designer for it anyways. And as we only use what ships with Maya, so it’s easier and faster to build interfaces with PyMEL or maya.cmds.

Anyhow, updated for referense:

Window (window) -> mc.window(‘TestWindow’, q=True, ex=True)
Menu Bar (menu) -> COULD NOT GET WORKING

  • Buttons
    Push Button (button) -> mc.button(‘pushButton’, q=True, c=True), mc.button(‘pushButton’, e=True, c=‘print “FOO”’)
    Radio Button (radioButton) -> mc.mc.radioButton…
    Check Box (checkBox) -> mc.checkBox(‘checkBox’, q=True, v=True), mc.checkBox(‘checkBox’, e=True, v=False)

  • Input Widgets
    Combo Box (optionMenu) -> mc.optionMenu(‘comboBox’, q=True, v=True), mc.optionMenu(‘comboBox’, e=True, sl=1)
    Line Edit (textField) -> mc.textField(‘lineEdit’, q=True, tx=True), mc.textField(‘lineEdit’, e=True, tx=“New Text”)
    Spin Box (NONE)
    Double Spin Box (NONE)
    Dial (NONE)
    Horizontal Slider (intSlider) -> mc.intSlider(‘horizontalSlider’, q=True, v=True), mc.intSlider(‘horizontalSlider’, e=True, v=10)
    Vertical Slider (intSlider) -> mc.intSlider(‘verticalSlider’, q=True, v=True), mc.intSlider(‘verticalSlider’, e=True, v=10)

  • Item Widgets
    List Widget (textScrollList) -> mc.textScrollList(‘listWidget’, q=True, si=True), mc.textScrollList(‘listWidget’, e=True, append=[‘one’, ‘two’], selectItem=‘two’)

  • Display Widgets
    Label (text) -> mc.text(‘label’, q=True, l=True), mc.text(‘label’, e=True, l=‘New’)
    Progress Bar (progressBar) -> mc.progressBar(‘progressBar’, q=True, pr=True), mc.progressBar(‘progressBar’, e=True, pr=50)

  • Containers
    Frame (NONE)
    Group Box (NONE)
    Tab Widget (tabLayout) -> COULD NOT GET WORKING

Great stuff. Thanks Eric, Mike and Chris. Some great Monday morning reading for me to get into. When you say the UI id dynamic do you mean dynamic in the way it handles objects (nulls, cameras etc) or dynamic in the way it’s built (multiple floating windows etc)

I’m going to go through the tutorial and this should hopefully give me a clearer picture of what I want to do and how I go about achieving it.

I’ll let you know how I get on. Cheers Tim

Dynamic as in created by code on the fly depending on what data it is given or what options the user has made.

I guess we could do a lot of smaller parts in our interface with ui files, but when you’re used to creating them by code you get a template to follow and then it’s quite quick.

It probably great for new users though as it’s much easier to create more complexed layouts and such this way then when I tried to learn it back in Maya 7 with MEL.

You can also do a hybrid approach for dynamic UIs - you can create a basic layout in Designer for the things that don’t change, and leave blank (and named) layout elements that you can later populate on the fly. I’ve done this a few times, and it works reasonably well.

cheers,
chrisg