0

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()"

Eunice C
  • 9
  • 6
  • 1
    Possible duplicate of [Importing class from another file](https://stackoverflow.com/questions/41276067/importing-class-from-another-file) – Matho Jul 31 '17 at 08:22

1 Answers1

0

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

Graham
  • 7,431
  • 18
  • 59
  • 84
theodox
  • 12,028
  • 3
  • 23
  • 36
  • I tried doing this by putting my base class inside the `__init__.py` file. I have to import my init module in the `main.py` to call the class inside the `__init__.py` file. Is that how it should be? Because that defeats the purpose of putting my stuff inside the `__init__.py` since I will be initializing multiple times if I have to use the class from `__init__.py` in another .py file – Eunice C Aug 04 '17 at 10:27
  • You won't be initing multiple times: you'll be importing the class definitions in multiple places, but the will only be defined once and initied when you create instances. Python won't 'reload' the file if its already imported, so it's fine to import it more than once. You don't want to do anything complex on module load - save expensive stuff for functions you call deliberately. – theodox Aug 05 '17 at 02:25
  • I think I kind of get what you mean. To make things simple, I have 3 files. `__init__.py`, `function_test.py` and `loadUi_test.py` (I've edited the main question to show code examples). In my `__init__.py` I should only have the `from pipeline import function_test, loadUi_test`. In `function_test.py` and `loadUi_test.py`, I then do `import pipeline` to be able to access methods from each other without explicitly doing `pipeline.function_test.printFunc()` for example. is that right? I want to be able to link my `function_test.py` and `loadUi.py` so that I can access pyqt's objectnames. – Eunice C Aug 07 '17 at 06:37
  • Anything you import from another file -- class or function -- will behave the same as if you had defined in locally. So you can create or work with classes from another file just fine. – theodox Aug 07 '17 at 16:00