Need a little help with QPushButton & connect



  • I have just started working on a plugin for the program Daz Studio and I'm stuck on what I thought would be a simple process to get an event when a button is pressed. Alas that it does not work.

    So I have in my main .cpp :

    QPushButton* button1 = new QPushButton(tr("Button 1"));
    mainLyt->addWidget(button1);
    connect(button1, SIGNAL(clicked()), this, SLOT (doSomething()));
    

    Then a function :

    void DzSceneInfoPane::doSomething()
    {
    	QMessageBox* box = new QMessageBox();
    	box->setWindowTitle("Hello");
    	box->setText("You clicked !");
    	box->show();		
    }
    

    And in my header files :

    public slots:
    	void			doSomething();
    

    Apologies if my terminology is off, I'm new to C++.

    Could anyone help ?

    Also there does not seem to be a way to format code in this message.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    For Signals and Slots to work you need an event loop running, usually through the call of QApplication's exec function. Do you have that ?

    Yes there is, the forum uses Markdown, you can surround your code with three back ticks (three back ticks, new line(s) with code and again three back ticks after a new line after your last code line)



  • Hello there !

    Thanks for your reply.

    I edited my message, thanks for the tip.

    Currently I am just playing with some examples so I am inserting code to see what it does layout-wise. Then later I can start proper.

    I don't at this stage know how to get a loop running, but I will look into it.


  • Lifetime Qt Champion

    The shortest way to get started is to create a new widget project and you'll have everything you need.



  • Does my code above look right ?

    In this code I am playing with there are already SIGNALS and SLOTS being used.

    I'm just wondering if my code above is okay.

    After spending a few hours trying to get one button to work I'm losing the will to live ;)


  • Moderators

    @mrmorph said:

    Does my code above look right ?

    In this code I am playing with there are already SIGNALS and SLOTS being used.

    I'm just wondering if my code above is okay.

    Unfortunately, you haven't posted enough code for us to tell if your code is right or not.

    Without seeing your code, my advice is:

    • Make sure your DzSceneInfoPane header contains the Q_OBJECT macro. If you don't, you can't define your own signals or slots.
    • Always pay attention to error and warning messages that you get. They contain valuable information about what's wrong.

    After spending a few hours trying to get one button to work I'm losing the will to live ;)

    I suggest following these tutorials. They are extremely simple, and use QPushButton:

    At the botton of Tutorial 1, it says "If you have typed in the source code manually, you will need to follow these instructions"... ignore that part.



  • Yes thank you, I think you are both right. I will have to start from fresh and learn step by step.

    Thanks to you both for helping, I appreciate it :)


  • Moderators

    You have a memory leak in:

    void DzSceneInfoPane::doSomething()
    {
        QMessageBox* box = new QMessageBox();
        box->setWindowTitle("Hello");
        box->setText("You clicked !");
        box->show();        
    }
    

    You never delete box.



  • I started fresh and am getting there in other areas, but this darned button is still a problem.

    In the examples you kindly posted there is this :

    #include <QApplication>
     #include <QPushButton>
    
     int main(int argc, char *argv[])
     {
         QApplication app(argc, argv);
    
         QPushButton hello("Hello world!");
         hello.resize(100, 30);
    
         hello.show();
         return app.exec();
     }
    

    Which is fine, but the examples I am working from do not use main. Other wise I have set things up as suggested, but I get nada. Here's my code... edit the forum formatting does not seem to work today.

    CPP :

    #include "myfirstplugin.h"
    
    #include <QtCore/QObject>
    #include <QtGui/QPushButton>
    #include <QtGui/QVBoxLayout>
    
    #include "dzapp.h"
    #include "dzbone.h"
    #include "dzfacetmesh.h"
    #include "dzhelpmgr.h"
    #include "dzobject.h"
    #include "dzscene.h"
    #include "dzshape.h"
    #include "dzskeleton.h"
    #include "dzstyle.h"
    
    #include "dzplugin.h"
    
    
    
    myFirstPlugin::myFirstPlugin() : DzPane("Hello there") {
    
    	QGroupBox *groupBox = new QGroupBox(tr("Exclusive Radio Buttons"));
    
    	QRadioButton *radio1 = new QRadioButton(tr("&Radio button 1"));
    	QRadioButton *radio2 = new QRadioButton(tr("R&adio button 2"));
    	QRadioButton *radio3 = new QRadioButton(tr("Ra&dio button 3"));
    
    	radio1->setChecked(true);
    
    	QGridLayout *gLay = new QGridLayout(groupBox);
    
    	gLay->addWidget(radio1);
    	gLay->addWidget(radio2);
    	gLay->addWidget(radio3);
    
        //Create QPushButton
    	QPushButton *button1 = new QPushButton(tr("Button 1"));
    	button1->setObjectName("button1");
    
        QMetaObject::connectSlotsByName(this);
    
    	// Define the layout for the pane
    	QVBoxLayout *mainLyt = new QVBoxLayout();
    	mainLyt->addWidget(groupBox);
    	mainLyt->addWidget(button1);
    	mainLyt->addStretch(1);
    
    	// Set the layout for the pane
    	setLayout(mainLyt);
    
        showPane();
    
    	connect(button1, SIGNAL(pressed()), this, SLOT(doThis()));
    }
    
    
    myFirstPlugin::~myFirstPlugin(){
    
    }
    
    
    void myFirstPlugin::doThis() {
    
    	QMessageBox* box = new QMessageBox();
    	box->setWindowTitle("Hello");
    	box->setText("You clicked !");
    	box->show();
    }
    

    And my header :

    #ifndef MYFIRSTPLUGIN_H
    #define MYFIRSTPLUGIN_H
    
    #include "dzpane.h"
    #include "dzaction.h"
    #include <QtGui/QPushButton>
    
    class myFirstPluginAction : public DzPaneAction {
        Q_OBJECT
    public:
        myFirstPluginAction() : DzPaneAction("myFirstPlugin") {
        }
    };
    
    class myFirstPlugin : public DzPane {
        Q_OBJECT
    public:
        myFirstPlugin();
        ~myFirstPlugin();
    
    public slots:
    	void			doThis();
    
    private:
    	QPushButton		*button1;
    
    };
    
    
    
    #endif // MYFIRSTPLUGIN_H
    

    [edit: fixed coding tags, three back-ticks SGaist]


  • Qt Champions 2016

    hi
    If you don't have a main then you most likely don't have

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    return app.exec();
    }

    the app.exec() is an event loop and it makes signals and slot works.
    So if its not running then no "click" will
    ever work.

    So it seem you are trying to make plugin for another program.
    Does this program expect it to be a DLL ?
    Are the samples you are using, for building a plugin with qt?

    when there is no main, then no much will happen when you run it.



  • No I don't have that.

    But the samples I was working from are using SLOTS and SIGNALS without it.

    It's a plugin yes - it's for Daz Studio, a graphics program.

    It uses DLLs yes. I can successfully build the DLL and it loads and will show my widgets within the main program.

    But whatever I try I can't get it to detect when I click on the button.

    Maybe there is a library I am missing, but as far as I can tell I'm using all the same includes as the examples that have the working events.


  • Qt Champions 2016

    @mrmorph
    Ok so the examples are for Qt ?
    And all loads in Daz Studio and you can see the button etc?
    I assume this
    connect(button1, SIGNAL(pressed()), this, SLOT(doThis()));
    is the button in question ?
    try output if connect is ok.
    bool status = connect(button1, SIGNAL(pressed()), this, SLOT(doThis()));
    if (!status)
    QMessageBox...

    to see if the actual connect that fails

    Do you have a link for the examples ?
    Must be something simple missing.



  • Hi, thanks for trying to help.

    And sorry yes, the samples are for Daz Studio yes and they work fine.

    Everything loads yes and I can see the radio buttons and button - they are in a window... as in this snip...

    Image to show it working in the main program...

    button1 is the one I am trying to get to work yes.

    I inserted this as suggested.

    bool status = connect(button1, SIGNAL(pressed()), this, SLOT(doThis()));
    
    	if (status) {
    		QMessageBox* box = new QMessageBox();
    		box->setWindowTitle("Hello");
    		box->setText("Works");
    		box->show();
    	}
    	else {
    		QMessageBox* box = new QMessageBox();
    		box->setWindowTitle("Hello");
    		box->setText("Does not work");
    		box->show();
    	}
    

    The connect appears to fail as I get 'Does not work'.

    Thanks for formatting my previous code properly, I got the wrong key.

    EDIT Opps, you wanted the samples. They are free here, but you would need to register. I don't think I can distribute the files myself.

    http://www.daz3d.com/daz-studio-4-5-sdk


  • Qt Champions 2016

    @mrmorph said:
    Hmm, one note

    QPushButton *button1 = new QPushButton(tr("Button 1"));
    you make new one but in .h you have one in class myFirstPlugin

    so should it be
    button1 = new QPushButton(tr("Button 1")); ?

    also, since it fails, (the connect) we need to find out why

    could you try the new syntax as it catch stuff compile time

    connect(button1, &QPushButton::released, this, &myFirstPlugin::doThis);



  • Tried

    button1 = new QPushButton(tr("Button 1"));

    But still the same, does not work.


  • Qt Champions 2016

    @mrmorph
    well was just a note. the real issues is why connect fails.
    can you try the new syntax
    connect(button1, &QPushButton::released, this, &myFirstPlugin::doThis);



  • Visual Studio does not like that.

    For connect there is a 'no instance of overload function "myFirstPlugin::connect" matches the argument list......'

    And &QPushButton::released is inaccessible...

    BTW, I am using Qt 4.8.1 as that's what Daz Studio is using.

    Sorry about the slow replies, it's not letting me post as I am a noob. Some 500 second limit.


  • Qt Champions 2016

    @mrmorph
    oh. sorry. thought it was 5.0+
    forget new syntax then.

    since connect fails , there must be something wrong.
    but all seems fine.
    doThis is public slot. buttons1 is allocated.
    just so I 100% sure , can u try the released signal instead?
    connect(button1, SIGNAL(released()), this, SLOT(doThis()));
    and see if still say "not works"

    np. its spam protection but is indeed annoying sometimes.
    ps. QMessageBox* box = new QMessageBox();
    need a delete box; else its a leak but ok for now.



  • No problem, I should have mentioned I was on an older Qt.

    Same thing with released().

    Thanks for the tip about the MessagBox delete, someone else did mention it, but it was always just a temporary thing.

    I wonder if I have to hook into something else that's in Daz Studio.

    Just as an example, the sample I am working from as reference uses connect like this :

    connect( dzScene, SIGNAL(sceneLoadStarting()), this, SLOT(blockRefresh()) );
    

    Now it also has this include :

    #include "dzscene.h"
    

    The scene would be the main graphics window and other things. Perhaps there is some loop being started in there because it uses dzScene in the connect, not a widget or anything like I am using.

    Maybe I need to include another library to get the loop for the widgets.

    Just grabbing at straws.


  • Qt Champions 2016

    @mrmorph said:

    connect( dzScene, SIGNAL(sceneLoadStarting()), this, SLOT(blockRefresh()) );

    On the signal sceneLoadStarting call blockRefresh
    so that is very like button.
    Do you have access to a dzScene instance? Like the default scene ?
    you could try to hook it up with your doThis and then load new scene or what ever
    that signal means.

    Whole SDK seems to be build with Qt so might have global event loop for plugins.
    So I doubt you need anything else since it loads DLL.

    But I don't like that connect fails. as even no event loop, the connect should not fail
    as far as I know .
    But syntax seems fine. so I wonder.

    When you click on button, it does animate ? Meaning show being pressed ?

    Also the default examples do work? I assume they use some gui too?

    also, could you move connect over "showpane"
    I assume pane shows then it says "not work" while pane is shown?



  • Not sure about that signal, I had a look through what's in dzscene.h and it all seems to be to do with loading models, cameras and the general interface.

    I wondered if it might have a global loop too, that makes some sense to me.

    The button animates yes and the radio boxes work too.

    "also, could you move connect over "showpane"" - Nope, still does not work....

    http://i799.photobucket.com/albums/yy275/Rogad/hmmm_zpseuusbmw5.png

    The samples given in the SDK work yes. There's only one that really does what I am trying to do. Basically it just shows details about what's in the scene, like polygon count and things like that. There's a sort of tree structure that you can use to select models in the scene. Unfortunately it does not have any buttons or similar for me to work by.

    The sample that works with connect uses QTextBrowser and it clearly seems to connect okay as it works - when you click on something in the scene you get the details updated.


  • Qt Champions 2016

    @mrmorph
    Ok,i'm 99.9% sure that event loop is running as
    MessageBox can be clicked and button animate etc.

    Also, if you make a normal qt project, it just works? Im asking if you setup Visual Studio so it runs the
    extra moc tool. etc. As moc.exe makes slot / signals work.
    But if normale example works, I guess all fine in setup.

    QMetaObject::connectSlotsByName(this);
    Is that from sample?
    Not that is should do anything bad.

    have you tried to hook up anything else? like the radio buttons?
    I am out of ideas why button wont work. seems perfectly fine.
    Normally one can see a warning in Creator, application output when connect fails.
    but with DLL, im not sure as it is not run in creator.



  • I can't run this as a normal Qt project, it just own't work standalone. But I will make a new project in Qt Creator and make a form to see how the buttons work and what code it makes. Maybe I can use that.

    I did use QtCreator a bit though to start it off. There is a moc file, but I don't know what to do with it, not sure how to add the moc file to Visual Studio Express. Maybe that's it.

    QMetaObject::connectSlotsByName(this); - no sorry that should not be there, that was from an earlier attempt, I have removed it now, but it had no effect anyway.

    I tried to get radio buttons to work too, but they would not either.

    I think you might be onto something with the moc file - I wasn't sure if I even needed that. I am using Visual Studio Express, so I'll have to find out how to use moc files then and try that.


  • Qt Champions 2016

    @mrmorph
    aha, studio express. so you are not using the qt plugins.
    Im not so deep into using visual studio but I know sometimes its need to manually add compile step to run
    moc.exe tool that generate meta info for qt signal system etc.
    .
    Test by 1:delete all moc files. and clean build folder.
    then rebuild all. if moc files comes back, all ok. if not
    then its using the moc file from long time ago and might not know about your slot. (dothis)

    http://stackoverflow.com/questions/15465932/using-qt-with-visual-studio-without-add-in

    Note: Im not 100% in what cases moc are run as using creator its automatic.

    its just a tool so you can run it by hand
    http://doc.qt.io/qt-5.5/moc.html

    if its not running moc.exe, it would explain the strangeness :)



  • Ok thanks I'll give that a go then.

    I need to get some sleep, so I will do it tomorrow.

    Many thanks for taking the time to help me, it's much appreciated :)

    Take care,

    Rog.


  • Qt Champions 2016

    @mrmorph
    well same here.
    My money is on moc files :)
    you are welcome.
    Take care too

    Just for test i used your code as QDialog and button just worked
    http://postimg.org/image/7rjevwz15/


  • Moderators

    @mrmorph said:

    I think you might be onto something with the moc file - I wasn't sure if I even needed that. I am using Visual Studio Express, so I'll have to find out how to use moc files then and try that.

    You definitely need moc. All of the features listed at http://doc.qt.io/qt-5/metaobjects.html (including signals and slots) require moc to work.

    VS Express is rather limiting. What version of VS are you using? Are you able to switch to Visual Studio Community Edition instead? If so, you'll be able to use the Qt Visual Studio Add-In, which makes your life much much easier. See http://doc.qt.io/vs-addin/

    Or, even better, could you use Qt Creator to develop your plug-in? Qt Creator can use the Visual Studio compiler.



  • I thought what the heck I will spend a minute seeing what was going on.

    Like I said I started building it in Qt Creator, then moved it over to Visual Studio, but kept it all in one folder.

    So I remembered I could load it all up in Qt Creator still. So I re-built it in Qt to get the C++ source files and then I built those in Visual Studio.

    Anyway, Qt Creator rebuilt the moc and it worked :)

    http://i799.photobucket.com/albums/yy275/Rogad/misc/yay_zpsabp2qac2.png

    So big thanks to you for narrowing it down to this. I have to remember to get Creator to rebuild the moc file when I add slots.

    Very happy, thank you very much :)

    EDIT : Ahh and I see you got it to work right too.

    Hi JKSH,

    Thanks for that. Yes I am using Community, sorry I've been using the name Express for so long, I just auto-typed it.

    And I am using Qt Creator as mentioned above. I'll take a look at the Qt Visual Studio Add-In tomorrow, thanks.

    Cheers both, so nice to nail that one.


  • Qt Champions 2016

    \o/
    it was a sneaky one :)



  • @JKSH said:

    Qt Visual Studio Add-In

    HI again, just tried this but it says it did not find anything compatible. I tried the Qt4 version because I am using Qt 4.8.1 and I tried the Qt5 version but neither install. Perhaps I downloaded the wrong ones.

    Also, I can't figure out how to make this topic solved.

    Many thanks.


  • Qt Champions 2016

    @mrmorph
    hi
    use the Topic Tools button to mark as Solved.
    its sort of below topic (first one) and to the right.




  • Qt Champions 2016

    @mrmorph
    hi its not the gear
    its near reply button and sort by.



  • Got it, sorry I was looking in the wrong place, thanks.


  • Qt Champions 2016

    @mrmorph
    well you are NOT the first to not see it.


Log in to reply
 

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