0

I'm programming in QT 4.8.4 with C++. I want to have a drop-down menu, where I can select an option, and then it will run an exe with the selected item on the menu as the option for the exe.

Here's my code:

#ifndef GUI_H
#define GUI_H

#include <QDialog>
#include <QtGui>

class QLabel;
class QLineEdit;
class QPushButton;

class gui : public QDialog
{
    Q_OBJECT

public:
    gui(QWidget *parent = 0);

public slots:
    void gui::on_go_clicked();

private:
    QLabel *label1;
    QLabel *label2;
    QLineEdit *lineEdit;
    QPushButton *goButton;
    QComboBox cb;
};

#endif

And the .cpp file:

#include <QtGui>
#include <QApplication>
#include <QComboBox>

#include "gui.h"

#include <vector>

gui::gui(QWidget *parent) : QDialog(parent)
{
    label1 = new QLabel(tr("Insert Name (Optional):"));
    label2 = new QLabel(tr("Class Name (Required):"));
    lineEdit = new QLineEdit;

    goButton = new QPushButton(tr("&Go"));
    goButton->setDefault(true);
    connect(goButton, SIGNAL(clicked()), this, SLOT(on_go_clicked()));

    QComboBox *cb = new QComboBox();
    cb->addItem("Hello", "1");
    cb->addItem("Test", "2");

    QHBoxLayout *hLayout1 = new QHBoxLayout;
    hLayout1->addWidget(label1);
    hLayout1->addWidget(lineEdit);

    QHBoxLayout *hLayout2 = new QHBoxLayout;
    hLayout2->addWidget(label2);
    hLayout2->addWidget(cb);

    QHBoxLayout *hLayout3 = new QHBoxLayout;
    hLayout3->addWidget(goButton);
    hLayout3->addStretch();

    QVBoxLayout *vLayout = new QVBoxLayout;
    vLayout->addLayout(hLayout1);
    vLayout->addLayout(hLayout2);
    vLayout->addWidget(cb);
    vLayout->addLayout(hLayout3);

    setLayout(vLayout);
    setWindowTitle(tr("TEST"));
    setFixedHeight(sizeHint().height());
}

void gui::on_go_clicked()
{
    QMessageBox::information(this, "ASDF", cb.currentText());
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    gui *stuff = new gui;
    stuff->show();
    return app.exec();
}

Right now I'm just trying to figure out how to use QComboBox, which isn't working. My code compiles, but when I run it I get "Object::connect: No such slot gui::on_go_clicked()"

I'm doing exactly what a tutorial says to do. I can't figure out why this isn't working.

p.i.g.
  • 2,815
  • 2
  • 24
  • 41
Steve The Squid
  • 63
  • 1
  • 1
  • 5

3 Answers3

4

Remove gui:: :

class gui : public QDialog{
    Q_OBJECT

...

public slots:
    void gui::on_go_clicked();
         ^^^^^
         Remove it
masoud
  • 55,379
  • 16
  • 141
  • 208
1

I wonder why you code even compiles. No 'extra qualification on member on_go_clicked'. Remove gui:: from on_go_clicked in your header.

Greenflow
  • 3,935
  • 2
  • 17
  • 28
  • Having that extra gui:: part is not an error in c++, it has to do with Qt's signal and slot system, it simply doesn't understand that they are the same. – Lochemage Aug 15 '13 at 20:27
  • AFAIK, In some compilers such as MSVC++ it's possible to write code like that (using extra qualification). However it's not standard. – masoud Aug 15 '13 at 20:28
  • The code compiles because QObject::connect takes in char* argument. There is no check at compile time. Documentation can be found here http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#connect – segfault Aug 15 '13 at 20:28
  • Lochemage, segfault, the reason why the signal/slot connection did not work, is clear. But with the gcc you won't get this code compiled. Nice behaviour I'd say. Such error is easily made by copy paste, but not so easily spottet. – Greenflow Aug 15 '13 at 20:32
  • If I get rid of gui::, I can't use the QComboBox in the slot. – Steve The Squid Aug 15 '13 at 20:47
  • Why not? Sure you can. Just the gui:: in the .h file. See MM.'s answer. – Greenflow Aug 15 '13 at 20:55
  • You're creating two separate QComboBox objects, the class-level one (not a pointer), and a function-level one (pointer) inside the gui constructor. Change the class-level one to a pointer-to-QComboBox and change the declaration-initialisation inside gui::gui to just an assignment. – RobbieE Aug 16 '13 at 08:16
  • @RobbieE, this is definitely worth an answer. Not just a comment. Good catch. – Greenflow Aug 16 '13 at 09:40
  • Oh, I didn't notice that I was supposed to only remove the ::gui from the header. I removed that, and fixed my object declarations like Robbie said, and it works now! Thanks M.M., RobbieE and Greenflow! – Steve The Squid Aug 16 '13 at 13:34
1

You have two QComboBox objects that you reference.

The first is at the class level:

class gui : public QDialog{
    Q_OBJECT

public:
    gui(QWidget *parent = 0);

public slots:
    void gui::on_go_clicked();

private:
    QLabel *label1;
    QLabel *label2;
    QLineEdit *lineEdit;
    QPushButton *goButton;
    QComboBox cb;           // <<<=== class-level automatic object
};

The second is a local pointer-to-QComboBox object that exists in the constructor

gui::gui(QWidget *parent) : QDialog(parent){

  ...

  QComboBox *cb = new QComboBox();  // <<<=== function-level pointer using the same name 
                                    //        as the class-level automatic object

To correct the problem, you can change the class-level object to be a pointer and then change the object creation to be a simple assignment instead of a declaration-and-initialisation.

cb = new QComboBox();

Also, once you've done this, you'll need to modify the slot so that the pointer dereference operator is used to access the text() function

void gui::on_go_clicked(){
  QMessageBox::information(this, "ASDF", cb->currentText());
}
RobbieE
  • 4,280
  • 3
  • 22
  • 36
  • Also, in the constructor, you're assigning your `QComboBox` to `hLayout2` and then later re-assigning it to `vLayout`. You need to decide which layout you want it to be in. – RobbieE Aug 16 '13 at 11:14
  • Oh that wasn't on purpose. I guess I just left that in while I was rearranging things trying to get it to work. – Steve The Squid Aug 16 '13 at 13:30