Search code examples
pythonqtpyqtpysidemainwindow

How to call a function in pyside MainWindow from another python script


This is my main.py I have a function called loadShot that I want to call from another

class MainWindow(QMainWindow):
    # Main Window UI
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        loadUi(os.path.join(SCRIPT_DIRECTORY, 'mainwindow.ui'), self)

        self.connectInterface()

    # Connect signals
    def connectInterface(self):
        self.scene_Line.textChanged.connect(self.shotName)
        self.activeProjcet_Line.textChanged.connect(self.shotName)
        self.character_Line.textChanged.connect(self.shotName)
        self.take_Line.valueChanged.connect(self.shotName)
        self.load_Button.setShortcut(QKeySequence("Alt+B"))

    ####################################################
    #   Shot Loader Functions
    ####################################################


    def browse(self, dir):
        root = Tkinter.Tk()
        root.withdraw() #use to hide tkinter window

        tempdir = tkFileDialog.askdirectory(parent=root, initialdir=dir, title='Please select a directory')

        if tempdir.startswith('D:/Capture data/'):
            self.activeProjcet_Line.setText(tempdir)
        elif tempdir.startswith('R:/Project Files/'):
            self.uploadProjcet_Line.setText(tempdir)
            self.uploadFolder()
        else:
            pass

    def uploadFolder(self):
        project = self.activeProjcet_Line.text()
        uploadDir = self.uploadProjcet_Line.text()
        f = open('C:/_Mocap/output/folderName.txt', 'w')
        f.write(' \n' + project.replace('D:/Capture data/', '') + '\n' + uploadDir.replace('R:/Project Files/', ''))
        f.close()

    def loadShot(self):
        shot = self.shotName_Line.text()
        f = open('C:/_Mocap/output/ShotLoader.txt', 'w')
        f.write('\n' + '[name]\n' + '\n' + 'take Name=' + shot)
        f.close()
        self.uploadFolder()
        if self.incrementTake.isChecked():
            self.takeIncrement()
        else:
            pass

This is my other python file that is a key listener and I want to loadShot function. The problem is I keep loading the MainWindow as an instance. Which I cannot do. I need to just be able to call the function in my MainWindow class without loading another instance.

def handle_Ctrl_L ():
    m = MainWindow()
    m.loadShot()
    hk = HotKeys()
    w = WindowMgr()
    pid = w.GetProcessID('Blade')
    w.focusWindow(pid)
    time.sleep(.2)
    hk.F8()

Solution

  • In one project i had to enable one module to do a callback to my Mainwindow module. The Controller of the Mainwindow view starts a new subprocess and retrieves the stdout out as well as the callback as soon as the program is terminated. I managed this in the following way: (Maybe it helps with your problem, which i not totally understand)

    MainWindow Module:

    def run_program():
        # consoleprocess is the second module that 
        # has to be able to do a callback. 
        # A new Instance of the ProcessRunner class is created.
    
        self.progrunner = consoleprocess.ConsoleProcessRunner()
        self.progrunner.cout.connect(self.cb_update_prog_output)
        self.progrunner.quit.connect(self.cb_prog_terminated)
    
    @QtCore.Slot(int)
    @QtCore.Slot(str)
    def cb_update_tv(self, data):
        # your code goes here
        pass
    

    Second Module (consoleprocess):

    # The Class has to inherit QtCore.Object
    
    class ConsoleProcessRunner(QtCore.QObject):
        # The Signals that allow the callback are declared
    
        cout = QtCore.Signal(str)
        quit = QtCore.Signal(int)
    
        # Constructor
        def __init__(self, parent = None):
            super(ConsoleProcessRunner, self).__init__(parent)
    
    
        def your_function_here():
            # now you can use our previously defined signals to do the callback
            # your code goes here
            self.cout.emit(stdoutdata)
            self.quit.emit(ret)