0

in my Qt program I need the dialog to send a signal to a slot in the mainwindow. I have set the connection up correctly to the best of my knowledge and it does not give me any errors during compile or run time but for some reason it just doesn't do anything when the button that is supposed to activate the signal is clicked. Why is this happening?

beastiary.h (mainwindow header)

namespace Ui {
class Beastiary;
}

class Beastiary : public QMainWindow
{
    Q_OBJECT

public:

    explicit Beastiary(QWidget *parent = 0);

    Ui::Beastiary *ui;

    QStringList MyList;

    ~Beastiary();

public slots:
    void refresh();

private slots:

    void on_pushButton_clicked();

    void on_listWidget_itemClicked(QListWidgetItem);

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

beastiary.cpp (mainwindow cpp file)

Beastiary::Beastiary(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Beastiary)
{
    ui->setupUi(this);
    Dialog  dialog;
    connect(&dialog, SIGNAL(gorefresh()),this, SLOT(refresh())) ;


    void Beastiary::refresh()
    {
      qDebug () << "recieved";
      ui->listWidget->clear();
      QString path = "C:/Program Files/Bargest/bin";
      QDir myPath(path);
      myPath.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
      MyList = myPath.entryList();
      ui->listWidget->addItems(MyList);
    }

dialog.h

namespace Ui {
class Dialog;

}

class Dialog : public QDialog
{
    Q_OBJECT


public:

    explicit Dialog(QWidget *parent = 0);
    ~Dialog();


signals:
    void gorefresh();

private slots:
    void on_pushButton_done_clicked();

    void on_pushButton_cancel_clicked();

    void on_pushButton_clicked();

private:
    Ui::Dialog *ui;

dialog.cpp

void Dialog::on_pushButton_done_clicked()
{    
  emit gorefresh();
}

I did leave out large parts of the code that just have nothing to do with the actual signals and slots mechanism at play here.

Louis Langholtz
  • 2,913
  • 3
  • 17
  • 40
Nick
  • 31
  • 1
  • 5

1 Answers1

2

You're only connecting the dialog instance you created locally in the Bestiary's constructor, which goes out of scope as the constructor finishes.

connect is connecting instances, not classes. That means you need to connect each created dialog:

void Beastiary::on_pushButton_clicked() {
    Dialog* ad = new Dialog(this);
    connect(ad, SIGNAL(gorefresh()), this, SLOT(refresh()));
    ad->show();
}

While at it, you should seriously consider using the type-safe connect syntax that came with Qt 5:

void Beastiary::on_pushButton_clicked() {
    Dialog* ad = new Dialog(this);
    connect(ad, &Dialog::gorefresh, this, &Bestiary::refresh));
    ad->show();
}
krzaq
  • 16,240
  • 4
  • 46
  • 61
  • And also while you're at it you should seriously consider using explicit connects for those UI signals, instead of relying on the brittle "connect by name" feature – Kevin Krammer Nov 20 '16 at 11:17
  • 1
    Slot names like `on_pushButton_clicked()` are a string hint that the program uses the "connect by name" features, i.e. that there is an UI element called `pushButton` which has a `clicked()` signal an some generic code in `ui->setupUi()` tries to find a matching slot name to connect to. This is very brittle as it relies on names of elements, e.g. if that button got renamed, the slot would stop working. Doing explicit `connect()` calls in code avoids that, as any change in widget name would result in a changed variable name and make the connect fail compilation – Kevin Krammer Nov 20 '16 at 16:22
  • 1
    Doing explicit connects is not only safer regarding future modification, it is also easier to discover (since the connects are clearly visible in your code) and allow you to have any slot name you'd like and not be bound to that weird syntax with underscores – Kevin Krammer Nov 20 '16 at 16:23