0

I am trying to write a UI with Pyside2 for maya, but for some reason I could not connect QPushButton with the function within the same class.

In this case I wrote a simple UI with 1 button to trigger template_btnCmd within the same class.

Thank you.

import pymel.core as pm ;
import maya.OpenMayaUI as mui ;
from PySide2 import QtCore , QtGui , QtWidgets ;
from shiboken2 import wrapInstance ;

class Gui ( object ) :

    def __init__ ( self ) :
        super ( Gui , self ).__init__() ;

        self.ui = 'template_uiE' ;
        self.w = 500.00 ;
        self.h = 300.00 ;

    def deleteUI ( self , ui ) :
        if pm.window ( ui , ex = True ) :
            pm.deleteUI ( ui ) ;
            self.deleteUI ( ui ) ;

    def show ( self ) :

        self.deleteUI ( self.ui ) ;

        # Pointer
        mayaMainWindow_ptr = mui.MQtUtil.mainWindow();
        mayaMainWindow = wrapInstance(long(mayaMainWindow_ptr), QtWidgets.QWidget);
        self.mayaMainWindow_ptr = mayaMainWindow_ptr;
        self.mayaMainWindow = mayaMainWindow;

        window = QtWidgets.QWidget(parent=mayaMainWindow);
        self.window = window;
        window.setObjectName(self.ui);
        window.resize(self.w, self.h);
        window.setWindowFlags(QtCore.Qt.Window);

        main_QHBoxLayout = QtWidgets.QHBoxLayout(window);
        main_QHBoxLayout.setObjectName('main_QHBoxLayout_uiE');
        self.main_QHBoxLayout = main_QHBoxLayout;

        ### Grid Layout
        button_QPushButton = QtWidgets.QPushButton() ;
        button_QPushButton.setObjectName ( 'button_QPushButton_uiE' ) ;
        button_QPushButton.setText ( 'Template Button' ) ;
        button_QPushButton.clicked.connect ( self.template_btnCmd ) ;
        # --> Insert
        main_QHBoxLayout.addWidget ( button_QPushButton ) ;

        window.show() ;

    def template_btnCmd ( self ) :
        print ( 'This is working...?' ) ;

def run ( *args ) :

    gui = Gui() ;
    gui.show() ;

run() ;
eyllanesc
  • 235,170
  • 19
  • 170
  • 241

2 Answers2

0

So I managed to run the command. Instead of directly connect the function to the QPushButton I used the nested function to connect QPushButton...

        button_QPushButton = QtWidgets.QPushButton() ;
        button_QPushButton.setObjectName ( 'button_QPushButton_uiE' ) ;
        button_QPushButton.setText ( 'Template Button' ) ;

        def template_btnCmd ( *args ) :
            self.template_btnCmd() ;

        button_QPushButton.pressed.connect ( template_btnCmd ) ;
        # --> Insert
        main_QHBoxLayout.addWidget ( button_QPushButton ) ;

I don't really know what's happening here. I don't feel like this is the way to go and this is more like a duck tape solution.

And if anyone can explain what's happening here it would be great.

Thanks!

0

The easiest solution would be to make your gui variable global:

def run ( *args ) :
    global gui
    gui = Gui() ;
    gui.show() ;

Usually Qt objects are deleted when no memory is holding onto it (like using self in a class), so I'm assuming it's removing some connections the way you're creating it.

This feels like a band-aid and might be masking some major issues, especially for more complex interfaces.

Typically your main class should actually inherit from a QObject, mainly one of the following: QDialog, QMainWindow, QWidget. It's also important to declare all objects inherited from a QObject with self so they become an instance variable and can be accessed throughout the class. You risk the object being deleted during garbage collection otherwise, because it doesn't belong to anything and Python thinks you're done with it.

In the end it would look like this:

import pymel.core as pm
import maya.OpenMayaUI as mui
from PySide2 import QtCore
from PySide2 import QtGui
from PySide2 import QtWidgets
from shiboken2 import wrapInstance


class Gui(QtWidgets.QWidget):

    def __init__(self):
        self.ui = 'template_uiE'
        self.w = 500.00
        self.h = 300.00

        self.deleteGui(self.ui)

        # Pointer
        mayaMainWindow_ptr = mui.MQtUtil.mainWindow()
        mayaMainWindow = wrapInstance(long(mayaMainWindow_ptr), QtWidgets.QWidget)

        super(Gui, self).__init__(mayaMainWindow)

        self.setObjectName(self.ui)
        self.resize(self.w, self.h)
        self.setWindowFlags(QtCore.Qt.Window)

        # Grid Layout
        self.button_QPushButton = QtWidgets.QPushButton()
        self.button_QPushButton.setObjectName('button_QPushButton_uiE')
        self.button_QPushButton.setText('Template Button')
        self.button_QPushButton.clicked.connect(self.template_btnCmd)

        # --> Insert
        self.main_QHBoxLayout = QtWidgets.QVBoxLayout()
        self.main_QHBoxLayout.addWidget(self.button_QPushButton)
        self.setLayout(self.main_QHBoxLayout)

    def deleteGui(self, ui):
        if pm.window(ui, ex=True):
            pm.deleteUI(ui)

    def template_btnCmd(self):
        print 'This is working...?'


def run(*args):
    gui = Gui()
    gui.show()


run()

Also a few words about coding standards: please stick with either PEP8 or Google's coding standards. Remove all semi-colons (;) as it's extremely non-Pythonic and looks like a colon (:), it's very confusing. Close the gap in your white-space as it takes up unnecessary space and makes it more unreadable. Don't mix camelCase with snake_case naming, pick one or the other. There's no point in developing your own style when others have a hard time reading it :D

Green Cell
  • 4,677
  • 2
  • 18
  • 49
  • It's start to make sense now! Thank you! Oh wow, I never know about these PEP8 or Google's coding standards! I am not from programming background and don't know much about the coding etiquette. Thank you for the resources! – birdiesama May 17 '19 at 16:42