Search code examples
pythonuser-interfacepyqtmaya

Calling UI objects from a file into another


I am currently writing a UI script for Maya in Python.

So, I have UI that has different tabs at the top and I do not want to put every single piece of code in the MainClass because that would be too messy and long. For every tab, I want to write its script in a different .py file. I want to create the connections under the __init__ function, at the same time, load functions from another script into this MainClass to be used.

Question is, how should I go about calling objectName from the UI in a new file? I tried to import the MainClass code but that didn't work and I don't want the initialize the UI window in the new .py file. What's a good way to go about this?

EDIT

Example:

test.ui file has one button labelled "Print" and a list Widget. Every time 'Print' button is pressed, the words "Hello World" will appear on the list widget.

In loadUi_test.py file

def loadUi(uiFile):
    #code that loads ui

def getMayaWindow():
    #gets main Maya Window

    ptr = apiUI.MQtUtil.mainWindow()
    if ptr is not None:
        return shiboken.wrapInstance(long(ptr), QtGui.QMainWindow)

class mainClass():
    def __init__(self, parent = getMayaWindow()):

        super(pipeWindow,self).__init__(parent)
        self.setupUi(self)

    def closeEvent(self,event):
        super(mainClass, self).closeEvent(event)

In function_test.py

def printFunc():
    listWidget.clear()
    listWidget.addItem("Hello World!")

In init.py

from pipeline import loadUi_test
from pipeline import function_test

uiFile = "test.ui"
b = loadUi_test.loadUi(uiFile)
a = loadUi_test.mainClass()
a.pushButton.clicked.connect(function_test.printFunc(b))

This does not work, I get an error " tuple object has no attribute listWidget "

If I do this instead: a.pushButton.clicked.connect(function_test.printFunc(a)), I get the error "Failed to connect signal clicked()"


Solution

  • In general, you can load classes from other files as long as all of the files are available on your python path. You can load a class using the import statement.

    A basic example of the typical pattern looks like this on disk

    mytool
    |
    +---  __init__.py
    +--- model_tab.py
    +--- texture_tab.py
    +--- tool_tab.py
    

    where the main tool is mytool, defined in the __init__.py and the component pieces live in the other files. You can import a class using the from SomeModule import SomeClass pattern. That makes it easy to keep your pieces in separate files. You'd structure the imports like this in __init__.py

    from mytool.model_tab import ModelTab
    from mytoool.texture_tab import TextureTab
    from mytool.tool_tab import ToolTab
    

    With that in place you can assemble your actual gui using the classes you have defined in your other files. You could put you master class in the __init__.py or in a separate file as seems convenient