Сигналы не попадают в другой класс - PullRequest
2 голосов
/ 25 июня 2019

Я работаю с пользовательским классом, который излучает сигнал через фиксированный интервал.Этот сигнал излучает нормально, так как я связал его со слотом того же класса и проверил с помощью операторов qdebug в слотах.Проблема в том, что когда я пытаюсь подключить те же сигналы в классе mainwindow, слоты не вызываются.
Вот мой код:

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "counter.h"
#include <QTextEdit>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void on_pushButton_clicked();
    void updateText(int);
    void test(int);
    void anotherSlot();

private:
    Ui::MainWindow *ui;
    Counter *cobj;
    int v;
    QTextEdit *te;
};
#endif // MAINWINDOW_H

Mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QThread>
#include "counter.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    cobj = new Counter(this);

    v = 0;
    te = ui->textEdit;
    bool success1 = connect(cobj, SIGNAL (mileStoneReached(int)), this, SLOT(updateText(int)),Qt::AutoConnection);
    bool success2 = connect(cobj,SIGNAL (mileStoneReached(int)), this,SLOT(test(int)),Qt::AutoConnection);
    bool success3 = connect(cobj,SIGNAL (anotherSignal()), this,SLOT (anotherSlot()),Qt::AutoConnection);
    qDebug() << success1 << "   " << success2 << "  " << success3;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    cobj = new Counter();

    te->setText("0");
    qDebug() <<QThread::currentThreadId();
    cobj->run();
}

void MainWindow::updateText(int x)
{
    qDebug() << Q_FUNC_INFO;
    v = (v+1) * 13;
    te->setText(QString("%1").arg(v));
}

void MainWindow::test( int x)
{
    qDebug() << Q_FUNC_INFO;
    qDebug() <<"___" ;
}

void MainWindow::anotherSlot()
{
    qDebug() << Q_FUNC_INFO;
    qDebug() <<"__######_" ;
}

Counter.h

#ifndef COUNTER_H
#define COUNTER_H
#include <QTimer>

class Counter : public QObject
{
    Q_OBJECT
public:
    Counter(QObject *parent= nullptr);

    void run();
    void reset();
    void init();

signals:
    void mileStoneReached(int x);
    void anotherSignal();

public slots:
    void increment();
    void test();

private:
    int cValue;
    QTimer *timer;
};
#endif // COUNTER_H

Counter.cpp

#include "counter.h"
#include<QDebug>

Counter::Counter(QObject*parent):QObject(parent)
{
    cValue= 0;
    init();
}

void Counter:: init()
{
    timer=new QTimer;
    connect(timer, SIGNAL(timeout()), this, SLOT(increment()),Qt::AutoConnection);
    connect(this,SIGNAL(mileStoneReached(int)), this,SLOT(test()),Qt::AutoConnection);
}

void Counter::reset()
{
    cValue=0;
}

void Counter::run()
{
    timer->start(100);
}

void Counter::increment()
{
    cValue++;
    if(cValue % 13 ==0)
    {
        qDebug() << cValue;
        emit mileStoneReached( cValue);
    }
    else
    {
        emit (anotherSignal());
    }
}

void Counter::test()
{
    qDebug() << "Signal caught";
}

Выход:

true     true    true // all connections are fine
0x21ac // Main thread Id  irrelevant to problem
13 // counter value
Signal caught //qdebug  print
26
Signal caught
39
Signal caught
52
Signal caught
65
Signal caught
78
Signal caught
91
Signal caught
104
Signal caught
117
Signal caught

1 Ответ

1 голос
/ 25 июня 2019

Внутри вашего MainWindow конструктора вы создаете экземпляр Counter* и присваиваете ему cobj, но в MainWindow::on_pushButton_clicked вы создаете еще один Counter* и снова назначаете его cobj, а затем запускаете свой счетчик, это создает несколько проблем.

В MainWindow::on_pushButton_clicked при создании нового Counter* возникает утечка памяти, поскольку вы никогда не delete предыдущего экземпляра, также вы вызываете run в новом экземпляре, но соединения были созданы со старым он был создан внутри конструктора MainWindow, поэтому связанные методы никогда не будут вызываться.

Возможным решением было бы просто использовать экземпляр create внутри конструктора MainWindow.

void MainWindow::on_pushButton_clicked()
{
    te->setText("0");
    qDebug() <<QThread::currentThreadId();

    cobj->run();
}

Вы также никогда не delete Counter* внутри MainWindow, это вызывает еще одну утечку памяти, поэтому добавьте delete cobj в свой MainWindow деструктор.

Я предлагаю также изменить различные соединения, чтобы использовать новый синтаксис с помощью указателей функций.

connect(cobj, SIGNAL (mileStoneReached(int)), this, SLOT(updateText(int)),Qt::AutoConnection);

становится:

connect(cobj, &Counter::mileStoneReached, this, &MainWindow::updateText,Qt::AutoConnection);

Это безопаснее, поскольку некоторые проверки выполняются во время компиляции, например, если вы сделаете опечатку в имени функции, она не будет компилироваться вообще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...