Сигналы и слоты не работают в qt

в моей программе Qt мне нужен диалог для отправки сигнала в слот в главном окне. Я правильно настроил соединение, насколько мне известно, и оно не дает мне никаких ошибок во время компиляции или выполнения, но по какой-то причине оно просто ничего не делает, когда нажимается кнопка, которая должна активировать сигнал. Почему это происходит?

beastiary.h (заголовок главного окна)

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
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);
    }
clicked(); void on_pushButton
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;
clicked();

beastiary.cpp (файл cpp главного окна)

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();
}

Я пропустил большие части кода, которые просто не имеют ничего общего с реальными сигналами и механизмом слотов.


person Nick    schedule 19.11.2016    source источник
comment
Где вы выполняете диалог?   -  person krzaq    schedule 20.11.2016
comment
void Beastiary::on_pushButton_clicked() { Dialog* ad = new Dialog(this); ad->show(); } В главном окне это кнопка, которая вызывает диалоговое окно   -  person Nick    schedule 20.11.2016
comment
См. stackoverflow.com/q/26422154/1421332.   -  person Silicomancer    schedule 20.11.2016


Ответы (1)


Вы только подключаете экземпляр диалога, который вы создали локально в конструкторе Bestiary, который выходит за рамки, когда конструктор завершает работу.

connect подключает экземпляры, а не классы. Это означает, что вам нужно connect каждый созданный диалог:

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

При этом вы должны серьезно подумать об использовании безопасного синтаксиса подключения, который появился в Qt 5:

void Beastiary::on_pushButton_clicked() {
    Dialog* ad = new Dialog(this);
    connect(ad, &Dialog::gorefresh, this, &Bestiary::refresh));
    ad->show();
}
person krzaq    schedule 19.11.2016
comment
А также, пока вы этим занимаетесь, вы должны серьезно подумать об использовании явных подключений для этих сигналов пользовательского интерфейса, вместо того, чтобы полагаться на функцию хрупкого подключения по имени. - person Kevin Krammer; 20.11.2016
comment
Имена слотов, такие как on_pushButton_clicked(), представляют собой строковую подсказку о том, что программа использует функции подключения по имени, то есть что существует элемент пользовательского интерфейса с именем pushButton, который имеет сигнал clicked(), а некоторый общий код в ui->setupUi() пытается найти подходящее имя слота для подключения. Это очень хрупко, так как зависит от имен элементов, например. если бы эта кнопка была переименована, слот перестал бы работать. Выполнение явных вызовов connect() в коде позволяет избежать этого, поскольку любое изменение имени виджета приведет к изменению имени переменной и приведет к сбою компиляции подключения. - person Kevin Krammer; 20.11.2016
comment
Выполнение явных подключений не только безопаснее в отношении будущих изменений, но также их легче обнаружить (поскольку подключения четко видны в вашем коде) и позволяет вам иметь любое имя слота, которое вы хотите, и не привязываться к этому странному синтаксису с символами подчеркивания. - person Kevin Krammer; 20.11.2016