Connect process finished() and error signal to set pushButton enabled?



  • Hi with the following source codes I try to connect a process`s finished() and error signal to enable a pushButton.

    first try:

    @void Processmethod()
    {

    QDialog *ProcessMessage = new QDialog;      
    Ui::DialogProcessMessage Dialog;        //polymorphy      
    Dialog.setupUi(ProcessMessage);              
    ProcessMessage->setModal(true);
    ProcessMessage->setAttribute(Qt::WA_DeleteOnClose);
    connect(Dialog.pushButtonAbort, SIGNAL(clicked()), &Prozess, SLOT(kill()));  
    connect(&Prozess, SIGNAL(finished(int, QProcess::ExitStatus)),  MessgitterDialog.pushButtonClose, SLOT(setEnabled(bool)));
    connect(&Prozess, SIGNAL(error(QProcess::ProcessError)),  MessgitterDialog.pushButtonClose, SLOT(setEnabled(bool)));_
    ProcessMessage->show();
    
    processmethodONE();
    

    }@

    Result:

    @QObject::connect: Incompatible sender/receiver arguments
    QProcess::finished(int,QProcess::ExitStatus) --> QPushButton::setEnabled(bool)
    QObject::connect: Incompatible sender/receiver arguments
    QProcess::error(QProcess::ProcessError) --> QPushButton::setEnabled(bool)@

    second try:

    @void Processmethod()
    {

    QDialog *ProcessMessage = new QDialog;      
    Ui::DialogProcessMessage Dialog;        //polymorphy      
    Dialog.setupUi(ProcessMessage);              
    ProcessMessage->setModal(true);
    ProcessMessage->setAttribute(Qt::WA_DeleteOnClose);
    connect(Dialog.pushButtonAbort, SIGNAL(clicked()), &Prozess, SLOT(kill()));  
    connect(&Prozess, SIGNAL(finished(int, QProcess::ExitStatus)),  MessgitterDialog.pushButtonClose, SLOT(setEnabled(true)));
    connect(&Prozess, SIGNAL(error(QProcess::ProcessError)),  MessgitterDialog.pushButtonClose, SLOT(setEnabled(true)));_
    ProcessMessage->show();
    
    processmethodONE();
    

    }
    @

    Result:

    @Object::connect: No such slot QPushButton::setEnabled(true) in Form.cpp:5156
    Object::connect: (receiver name: 'pushButtonClose')
    Object::connect: No such slot QPushButton::setEnabled(true) in Form.cpp:5157
    Object::connect: (receiver name: 'pushButtonClose')@

    Where am I wrong? greetings



  • Yes, as the warning message told you, you are wrong.

    Read the manual carefully http://qt-project.org/doc/qt-4.8/signalsandslots.html

    bq. The signature of a signal must match the signature of the receiving slot. (In fact a slot may have a shorter signature than the signal it receives because it can ignore extra arguments.)


  • Moderators

    Create a helper slot in your application that gets called when the process is finished. Then have the body of that slot just set the state of your button for you.



  • Hmmm, i am still not sure. I `ve read the following

    bq. All classes that contain signals or slots must mention Q_OBJECT at the top of their declaration. They must also derive (directly or indirectly) from QObject.

    So, my class "Ui::DialogProcessMessage" did not mention Q_OBJECT at the top of their declaration I added it and got:

    @Form.o: In function Ui::DialogProcessMessage ': / home / .. / ui_ProcessMessage.h. 28: undefined reference tovtable for Ui::DialogProcessMessage '
    make: Leaving directory / home / ... Form.o: (. Rodata._ZTVN2Ui31DialogProcessMessageE [vtable for Ui::DialogProcessMessage] +0 x10): undefined reference toUi::DialogProcessMessage :: metaObject () const '
    Form.o: (. Rodata._ZTVN2Ui31DialogProcessMessageE [vtable for Ui::DialogProcessMessage] +0 x18): undefined reference to Ui::DialogProcessMessage :: qt_metacast (char const *) ' Form.o: (. Rodata._ZTVN2Ui31DialogProcessMessageE [vtable for Ui :: DialogMessgitterProzessMeldung2] +0 x20): undefined reference toUi::DialogProcessMessage :: qt_metacall (QMetaObject :: Call, int, void **) '
    Form.o: (. Rodata._ZTIN2Ui31DialogProcessMessageE [typeinfo for Ui :: DialogProcessMessage] +0 x10): undefined reference to `typeinfo for Ui::DialogProcessMessage'
    collect2: ld returned 1 exit status
    make: *** [GUI] Error 1@

    Futhermore I dont know how to translate the following right into german and therefore dont get the meaning.

    bq. The signature of a signal must match the signature of the receiving slot. (In fact a slot may have a shorter signature than the signal it receives because it can ignore extra arguments.)

    What exactly means signature?

    (at)mlong: Problem is if I create a helper method and use it as a slot like

    @connect(&Prozess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(helper()));

    helper()
    {
    Dialog.pushButtonClose -> setEnable(true);
    }@

    I won`t have acces on the pushButtonAbort since Dialog is created locally or am I wrong?


  • Moderators

    The signature refers to the number and types of arguments in the signal or slot.

    For instance

    if you have
    @
    signals:
    void foo(int, int, int);
    @
    it could connect to
    @
    public slots:
    void bar(int, int, int);
    // or
    void bar(int, int); // last int ignored
    // or
    void bar(int); // last two ints ignored
    // or even
    void bar(); // all arguments ignored
    @
    but could NOT connect to
    @
    // Different signature:
    public slots:
    void bar(QString, int, int); // (QString != int)
    // or
    void bar(int,int,int,int); // Too many ints in slot. (What would it send for the last argument? It can't create data for parameters.)
    @



  • Thx for the information, now I have understood that. I tried:

    @connect(&Prozess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(helper()));

    helper()
    {
    Dialog.pushButtonClose -> setEnabled(true);
    }@

    But like I thought I have no access to "Dialog.pushButtonAbort" within method helper() since "Dialog" is locally created in "Processmethod()" . Have I missunderstood what you wanted me to do?

    Furthermore after the previous attempt I tried to already create the dialog`s objects in my class definition with

    @QDialog *ProcessMessage;
    Ui::DialogProcessMessage Dialog;@

    and then used the code above. It is compiling fine then, but still the button does not become enabled?


  • Moderators

    Have helper emit a signal which is compatible with what you want to accomplish. Then connect that signal to your QPushButton.

    @
    MyClass : public QObject {
    Q_OBJECT
    ...
    signals:
    void enablePushButton(bool);

    protected slots:
    void helper();
    @
    And the implementation:
    @
    void MyClass::helper() {
    emit enablePushButton(true); // Emit your own signal
    }
    @

    somewhere that has access to both your class + the pushbutton:
    @
    connect(myClassInstance, SIGNAL(enablePushButton(bool)),
    thePushButton, SLOT(setEnabled(bool)));
    @



  • Hi, I tried now:

    @"MyClass" : public QObject {
    Q_OBJECT
    ...

    signals:
    void enablePushButton(bool);

    protected slots:
    void helper();

    void Processmethod()
    {
    QDialog *ProcessMessage = new QDialog;
    Ui::DialogProcessMessage Dialog; //polymorphy
    Dialog.setupUi(ProcessMessage);
    ProcessMessage->setModal(true);
    ProcessMessage->setAttribute(Qt::WA_DeleteOnClose);
    connect(Dialog.pushButtonAbort, SIGNAL(clicked()), &Prozess, SLOT(kill()));
    connect(&Prozess6, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(helper()));
    connect(&Prozess6, SIGNAL(error(QProcess::ProcessError)), this, SLOT(helper()));
    connect(this,SIGNAL(enablePushButton(bool)),Dialog.pushButtonClose, SLOT(setEnabled(bool)));
    Prozessmeldung->setModal(true);
    ProcessMessage->show();

    processmethodONE();
    

    }

    void "MyClass"::helper() {
    emit enablePushButton(true); // Emit your own signal
    }@

    But still, if I abort the process the pushButtonClose does not become enabled.

    Note that I changed your:

    @connect(this,SIGNAL(enablePushButton(bool)),Dialog.pushButtonClose, SIGNAL(setEnabled(bool)));@

    into

    @connect(this,SIGNAL(enablePushButton(bool)),Dialog.pushButtonClose, SLOT(setEnabled(bool)));@



  • Of course it is not called. Your Dialog object is destroyed once you leave method Processmethod(), as it is created on the stack. The connection is disconnected as soon as the object ist destroyed.

    You will have to create it on the heap (using new) to survive the method.

    Second, you're running into memory leaks. Your QDialog class cannot be accessed outside of that method, and having no parent, it therefore will never be destroyed.



  • hi,

    I used now

    @"MyClass" : public QObject {
    Q_OBJECT
    ...

    signals:
    void enablePushButton(bool);

    protected slots:
    void helper();

    void Processmethod()
    {
    QDialog *ProcessMessage = new QDialog;
    Ui::DialogProcessMessage *Dialog; //polymorphy
    Dialog->setupUi(ProcessMessage);
    ProcessMessage->setModal(true);
    ProcessMessage->setAttribute(Qt::WA_DeleteOnClose);
    connect(Dialog->pushButtonAbort, SIGNAL(clicked()), &Prozess, SLOT(kill()));
    connect(&Prozess6, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(helper()));
    connect(&Prozess6, SIGNAL(error(QProcess::ProcessError)), this, SLOT(helper()));
    connect(this,SIGNAL(enablePushButton(bool)),Dialog->pushButtonClose, SLOT(setEnabled(bool)));
    Prozessmeldung->setModal(true);
    ProcessMessage->show();

    processmethodONE();
    

    }

    void "MyClass"::helper() {
    emit enablePushButton(true); // Emit your own signal
    }@

    So I created the Ui::DialogProcessMessage object "Dialog" on the Heap, but it still does not work.

    Could the problem be that in my Ui::DialogProcessMessage class Q_OBJECT is missing? See:

    bq. All classes that contain signals or slots must mention Q_OBJECT at the top of their declaration. They must also derive (directly or indirectly) from QObject.

    Furthermore:

    bq. Second, you’re running into memory leaks. Your QDialog class cannot be accessed outside of that method, and having no parent, it therefore will never be destroyed.

    Don`t you mean the QDialog class object will never be destroyed? And could you tell me how I should delete the Ui::DialogProcessMessage object "Dialog" best?



  • You haven't created the object you only created a pointer thats pointing to NULL
    @
    Ui::DialogProcessMessage *Dialog; // points to nothing
    Ui::DialogProcessMessage *Dialog = new Ui::DialogProcessMessage(); //points to an object
    @

    also since your QDialog object has no parent set when you create it it will not be automatically destroyed by Qt, that results in the memory leak Volker mentioned.
    @
    QDialog ProcessMessage = new QDialog; // default constructor QDialog(QWidget parent = 0) is called
    QDialog *ProcessMessage = new QDialog(yourMainWindowPointerOrSomeOtherParentWidget); // the dialog has a parent and is destroyed properly
    @



  • Oh sorry, my fault. For sure I already did:

    @Ui::DialogProcessMessage *Dialog = new Ui::DialogProcessMessage();@

    Just forgot it in my post, but have done it in my source code. Still does not work :(.

    Furthermore:

    @QDialog ProcessMessage = new QDialog; // default constructor QDialog(QWidget parent = 0) is called
    QDialog *ProcessMessage = new QDialog(yourMainWindowPointerOrSomeOtherParentWidget); // the dialog has a parent and is destroyed properly@

    --> My object ProcessMessage is deleted when I close the Dialog

    @ProcessMessage->setAttribute(Qt::WA_DeleteOnClose);@

    So I guess what you mean is:

    @Ui::DialogProcessMessage *Dialog = new Ui::DialogProcessMessage("MyClass");@

    Or am I wrong?



  • Ok, got it now, was my fault, just had the wrong QProcess "Prozess" in my connection method. THX for the help.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.