0

How do I signals and slots implemented on Maya? I have been reading about Qt signals and slots and I am trying to get this to work on Maya API(OpenMaya), but until now without success. I wish someone can point me in the right direction. I would like to set the text information of TextEditA to TextEditB When the PushButton is clicked. I wish to ​to reproduce something like I wrote in Python(PySide2).

Whan I would like to do is to make the melPTextEdit setText to the pyPTextEdit the moment the convert Button is clicked.

This is what I am trying to do (The code has been rewritten a bit, so there may be some inconsistencies.):

serpensCmd.h

#ifndef _serpensCmd
#define _serpensCmd
#define slots Q_SLOTS

#include <stdio.h>

#include <maya/MPxCommand.h>
#include <maya/MArgList.h>
#include <maya/MQtUtil.h>

#include <QtWidgets/QLabel>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpinBox>
#include <QtCore/QObject>
#include <QtCore/QString>

#include <QtWidgets/QMainWindow>
#include <QtWidgets/QWidget>
#include <QtCore/Qt>
#include <QtWidgets/QTextEdit>
#include <QtCore/QPointer>
#include <QtWidgets/QWidget>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QSpinBox>
#include <QtCore/QObject>
#include <QtCore/QString>



class SerpensMainWindow : public QMainWindow {
    Q_OBJECT
public:
    SerpensMainWindow(
        QWidget* parent = MQtUtil::mainWindow(),
        Qt::WindowFlags flags = Qt::WindowFlags()
    );
    virtual ~SerpensMainWindow();

    QGridLayout* gridLayout;
    QWidget* cw;
    QLabel* melLabel;
    QLabel* pyLabel;
    QTextEdit* melPTextEdit;
    QTextEdit* pyPTextEdit;
    QPushButton* convertButton;
    QPushButton* debugButton;

public slots:
    void debug();
    void convert();
};


class serpens : public MPxCommand
{

public:
    serpens();
    virtual ~serpens();


    static void cleanup();
    static void createWindow();
    static void* creator() { return new serpens(); }

    MStatus doIt(const MArgList&);

    static QPointer<SerpensMainWindow> window;
    static const MString commandName;

private:
};

#endif

serpensCmd.cpp


#include "serpensCmd.h"
#include <maya/MGlobal.h>

SerpensMainWindow::SerpensMainWindow(QWidget* parent, Qt::WindowFlags flags)
    : QMainWindow(parent, flags)
{

    QGridLayout* gridLayout = new QGridLayout(this);
    QWidget* cw = new QWidget(this);
    cw->setLayout(gridLayout);
    setCentralWidget(cw);


    QLabel* melLabel = new QLabel("mel", centralWidget());
    QTextEdit* melPTextEdit = new QTextEdit(centralWidget());

    QLabel* pyLabel = new QLabel("python", centralWidget());
    QTextEdit* pyPTextEdit = new QTextEdit(centralWidget());

    QPushButton* convertButton = new QPushButton("convert", centralWidget());
    QPushButton* debugButton = new QPushButton("debug", centralWidget());

    gridLayout->addWidget(melLabel, 0, 0, 1, 1);
    gridLayout->addWidget(melPTextEdit, 1, 0, 1, 1);
    gridLayout->addWidget(pyLabel, 0, 1, 1, 1);
    gridLayout->addWidget(pyPTextEdit, 1, 1, 1, 1);
    gridLayout->addWidget(convertButton, 2, 0, 1, 2);
    gridLayout->addWidget(debugButton, 3, 0, 1, 2);

    debugButton->connect(
        debugButton, SIGNAL(clicked()),
        this, SLOT(debug())
    );

    convertButton->connect(
        convertButton, SIGNAL(clicked()),
        this, SLOT(convert())
    );

    setWindowTitle("Serpens");

}

SerpensMainWindow::~SerpensMainWindow() {}


QPointer<SerpensMainWindow> serpens::window;

const MString serpens::commandName("Serpens");


void serpens::cleanup()
{
    if (!window.isNull()) delete window;
}


void serpens::createWindow() {
    if (window.isNull()) {
        window = new SerpensMainWindow();
        window->show();
    }
    else {
        window->showNormal();
        window->raise();
    }
}





void SerpensMainWindow::convert() {
    pyPTextEdit->setText(melPTextEdit->toPlainText());
    MGlobal::displayInfo(
        MQtUtil::toMString(pyPTextEdit->toPlainText())
    );
}


void SerpensMainWindow::debug() {
    MGlobal::displayInfo(MString("debug = "));
}


MStatus serpens::doIt( const MArgList& )
{
    MStatus stat = MS::kSuccess;

    serpens::createWindow();

    return redoIt();
}



serpens::serpens()
{}

serpens::~serpens()
{
}

pluginMain.cpp


#include "serpensCmd.h"

#include <maya/MFnPlugin.h>

MStatus initializePlugin( MObject obj )
{
    MStatus   status;
    MFnPlugin plugin( obj, "test", "2019", "Any");
    status = plugin.registerCommand("serpens", serpens::creator);
    if (!status) {
        status.perror(
            MString("SerpensCmd - could not initialize plugin: ")
            + status.errorString()
        );
        return status;
    }

    return status;
}

MStatus uninitializePlugin( MObject obj )
{
    MStatus   status;
    MFnPlugin plugin( obj );

    serpens::cleanup();
    status = plugin.deregisterCommand( "serpens" );
    if (!status) {
        status.perror(
            MString("SerpensCmd - could not register '")
            + serpens::commandName + "' command: "
            + status.errorString()
        );
        return status;
    }

    return status;
}

PySide2 example:

from PySide2.QtWidgets import *
 
class window(QMainWindow):
    def __init__(self, parent=None):
        super(window, self).__init__(parent)
        gridLayout = QGridLayout(self);
        cw = QWidget(self);
        cw.setLayout(gridLayout);
        self.setCentralWidget(cw);

        self.PTextEditA = QTextEdit(self.centralWidget());
        self.PTextEditB = QTextEdit(self.centralWidget());
        self.button = QPushButton("ok", self.centralWidget());
    
        gridLayout.addWidget(self.PTextEditA, 0, 0, 1, 1);
        gridLayout.addWidget(self.PTextEditB, 1, 0, 1, 1);
        gridLayout.addWidget(self.button, 2, 0, 1, 2);
        self.button.clicked.connect(self.testA)
    
    def testA(self):
        self.PTextEditB.setText(self.PTextEditA.text())
    

def main():
    app = QApplication.instance()
    mainWin = window()
    mainWin.show()
    sys.exit()
    app.exec_()
main()

I tried the Qt5 syntax for connecting but it isn't works. enter image description here

debugButton->connect(
    debugButton, &QPushButton::clicked,
    this, &SerpensMainWindow::convert
);
  • Please provide code which at least *looks* like it would compile. The above does for sure not. Also you should not create local variables in your ctor and initialize your member vars instead. – chehrlic Sep 01 '22 at 14:31
  • Have you tried the Qt5 syntax for connecting? `connect(button, &QPushButton::clicked, this, &qtWindow::testA)`. I am not sure `connect` being called like that does what you think it does. – Refugnic Eternium Sep 02 '22 at 12:08
  • Thank you, I am going to try! but I can't try it for a while because my PC is broken...... It will be a few months before I can confirm this, but thank you very much! – user7340833 Sep 06 '22 at 01:19
  • Not sure which versions you use, but a `QTextEdit.text()` does not exist. And your code is not compilable at all so we cannot check what's wrong. Did you check in debug if the `TestA()` method is called at all? – haggi krey Sep 07 '22 at 11:23
  • @chehrlic I uploaded solution file and source code to the [github](https://github.com/UnzaiRyota/Serpens/tree/main/src/serpens). – user7340833 Sep 09 '22 at 12:50
  • @RefugnicEternium I tried this but,,it isn't works. – user7340833 Sep 09 '22 at 13:08
  • @haggikrey I've uploaded the correct one. Whan I would like to do is to make the melPTextEdit setText to the pyPTextEdit the moment the convert Button is clicked. – user7340833 Sep 09 '22 at 13:19

1 Answers1

0

I modified your code a little bit by replacing the non existing self.PTextEditA.text() by toPlainText().

from PySide2.QtWidgets import *
import sys
class window(QMainWindow):
    def __init__(self, parent=None):
        super(window, self).__init__(parent)
        gridLayout = QGridLayout(self);
        cw = QWidget(self);
        cw.setLayout(gridLayout);
        self.setCentralWidget(cw);

        self.PTextEditA = QTextEdit(self.centralWidget());
        self.PTextEditB = QTextEdit(self.centralWidget());
        self.button = QPushButton("ok", self.centralWidget());
    
        gridLayout.addWidget(self.PTextEditA, 0, 0, 1, 1);
        gridLayout.addWidget(self.PTextEditB, 1, 0, 1, 1);
        gridLayout.addWidget(self.button, 2, 0, 1, 2);
        self.button.clicked.connect(self.testA)
    
    def testA(self):
        self.PTextEditB.setText(self.PTextEditA.toPlainText())
    

mainWin = window()
mainWin.show()

And it works fine.

haggi krey
  • 1,885
  • 1
  • 7
  • 9
  • Thank you for your answer . Your answer has nothing to do with C++. The problem I am having is that I can't connect with C++! If you can figure out how to fix this with CPP, I'd really appreciate it! – user7340833 Sep 06 '22 at 01:26
  • Sorry, I didn't read your question carefully. – haggi krey Sep 06 '22 at 08:21