PDA

View Full Version : Problem with the Slot in QObject::connect(...)



d'Matthias
30th May 2011, 17:30
Hello everybody,
I tried to make a little Wrapper-Class for the QPushButton, where I need to gather the Signal clicked() from the Button and rout it to a new written slot called "DoCommand()".


But this slot is never called by the Button's clicked() signal.
The compiler, linker run well. The Application itself runs "well", so without this functionality I told^^ ;)

Here is the Headerfile:

#pragma once

#include <QtGui\qpushbutton.h>



class MenuButton : QObject
{
Q_OBJECT
public:
MenuButton(std::string &title);
~MenuButton()
{
//delete pButton;
}

std::string command;

QPushButton *pButton;

public slots:
void DoCommand(void);
};
And here the soure file:

#include "MenuButton.h"
#include "../Kernel/ActionHandler.h"


MenuButton::MenuButton(std::string &title) : QObject()
{
pButton = new QPushButton(title.c_str());
pButton->setFixedSize(80, 45);
//QAction *action = new QAction(title.c_str(), this);
//action->connect(action, SIGNAL(triggered), this, SLOT(Clicked()));
//pButton->addAction(action);
bool success = QObject::connect(pButton, SIGNAL(clicked()), this, SLOT(DoCommand()));
Q_UNUSED(success);
Q_ASSERT(success);
}


void MenuButton::DoCommand(void)
{
LocalActionHandler->DoScript(command);
LocalActionHandler->DoScript(QString("print \"DoCommand was called\""));
}

Ehm, I forgott to say: success is always true in this case.

When I used an other slot from an other class' instance, for testing, everything worked well.


Does someone know what could be wrong ?
Maybe I made an stupid mistake anywhere..

Thanks a lot,


Matthias

wysota
30th May 2011, 20:29
What if you put the following at the beginning of DoCommand():

qDebug() << Q_FUNC_INFO;

Does the message get printed to the console?

d'Matthias
30th May 2011, 22:02
What if you put the following at the beginning of DoCommand():

qDebug() << Q_FUNC_INFO;

Does the message get printed to the console?

No the methode "DoCommand()" is never ever called, I saw by the debugger.
And I would see it at the fuction:
LocalActionHandler->DoScript(QString("print \"DoCommand was called\""));

if this methode is called.

But I have also disabled the console.

wysota
30th May 2011, 22:10
Does the meta-object for your class get built by moc?

deepal_de
31st May 2011, 05:51
it should be like this know??


bool success = QObject::connect(&pButton, SIGNAL(clicked()), this, SLOT(DoCommand()));

Santosh Reddy
31st May 2011, 06:55
Your signal and slot signatures does not match, use released() instead of clicked()

connect(pButton, SIGNAL(released()), this, SLOT(DoCommand()));

Added after 6 minutes:


it should be like this know??


bool success = QObject::connect(&pButton, SIGNAL(clicked()), this, SLOT(DoCommand()));

pButton is a pointer to QPushButton, using &pButton will not work (It will not even compile), because you are supplying a QPushbutton** where as it expects QPushButton* (actually it expects anything which is acceptable in place of QObject*)

stampede
31st May 2011, 07:08
Your signal and slot signatures does not match, use released() instead of clicked()
What's wrong with clicked() ? It will work with SLOTs that don't expects any parameters ( declared as void method(), or void method(void), no difference ).
Have you tried clean rebuild ? (make clean, qmake, make)

d'Matthias
31st May 2011, 18:55
You could be right stampede.

The chnage to released() does not matter. I have tried it out.

I think there must be somiting wrong with the SLOT.
Yes of course does the meta-object for my class get built by moc.

Oh I have no Idea what could be wrong. Maybe have done one very stupid mistake...

I have also cleaned the projekts in visual studio and build them again.

stampede
31st May 2011, 19:10
Are you sure Visual Studio removes moc_* files when you "clean" the project ? I'd suggest using the cmd, this way you'll know for sure if project is cleaned properly. I can't see anything wrong in this code.
Btw. if you want to provide custom button class, consider subclassing the QPushButton, rather than QObject, and connect the "clicked()" signal in your derived class' constructor to some slot where you'll handle the command execution.
It is more sensible, IMHO, to call for example


MenuButton * button = ...
...
layout->addWidget( button );

than


MenuButton * button = ...
...
layout->addWidget( button->pButton );

Furthermore, you can use "promote to" feature of the designer this way.

d'Matthias
31st May 2011, 19:26
You are right stampede, but in later times only this wrapper-class will be used directly in this context, so it should be no matter if, it is a subclass or it has a QPushbutton as mamber. In my way it is easier to encapsulate the QPushButton class.

I forgot to mention- that this wrapperclass is only instanced by a running python-interpreter.

stampede
31st May 2011, 19:36
Yeah, should work no matter of composition or inheritance.
In that case, are you sure this is not some kind of python-related issue ? You should be able to use this class in "regular" Qt app without any problems.

d'Matthias
2nd June 2011, 19:20
Hm ... I can not see the difference between instancing a QObject by python or by the c++ programm itself ?
Is there an other nor to complex way of listing to events/signals of a QObject, like QPushButton ??

Thanks

stampede
2nd June 2011, 19:55
If you call QObject::dumpObjectInfo() in debug build, it will print a list of currently connected signals for an object.

d'Matthias
3rd June 2011, 22:19
It prints out:



OBJECT MenuButton::unnamed
SIGNALS OUT
<None>
SIGNALS IN
<-- QPushButton::unnamed DoCommand()

Do you know where the failing is ?

stampede
4th June 2011, 07:46
Here is small test app, try if you can use this class in python interpreter, and in regular build:


// Test.h
#include <QtGui>
#include <QDebug>

class Test : public QObject{
Q_OBJECT
public:
Test( QObject * parent = NULL ) : QObject(parent){
setObjectName("test");
btn = new QPushButton();
btn->setObjectName("button");
connect(btn,SIGNAL(clicked()), this, SLOT(test()));
this->dumpObjectInfo();
}
~Test(){
delete btn;
}

QPushButton * btn;
public slots:
void test(){
qDebug() << "clicked";
}
};



// main.cpp
#include <QApplication>
#include "Test.h"

int main( int argc, char ** argv ){
QApplication app(argc,argv);
Test t; t.btn->show();
return app.exec();
}



// Test.pro
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

SOURCES += main.cpp
HEADERS += Test.h

Here is the output for dumpObjectInfo for this class:


OBJECT Test::test

SIGNALS OUT
<None>

SIGNALS IN
<-- QPushButton::button clicked()

As you can see, the button is connected with "clicked()" signal.
Try it and post your results, from python-interpreter, and "normal" application.