gpt4 book ai didi

c++ - 信号不会被另一个类捕获

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:02:42 24 4
gpt4 key购买 nike

我正在使用一个自定义类,它会在固定间隔后发出信号。该信号发射良好,因为我已将它与同一类中的插槽连接,并使用插槽中的 qdebug 语句进行了验证。问题是当我尝试在主窗口类中连接相同的信号时,槽没有被调用。
这是我的代码:

主窗口.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

主窗口.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() <<"__######_" ;
}

计数器.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

计数器.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

最佳答案

MainWindow 构造函数中,您实例化了一个 Counter* 并将其分配给 cobj 但在 MainWindow::on_pushButton_clicked 你创建了另一个 Counter* 并再次将它分配给 cobj 然后运行你的计数器,这会产生几个问题。

MainWindow::on_pushButton_clicked 中,当您创建新的 Counter* 时,您会发生内存泄漏,因为您从未删除 先前的实例,也您在新实例上调用了 run,但连接已与在 MainWindow 构造函数内创建的旧连接创建,因此永远不会调用连接的方法。

一个可能的解决方案是只使用在 MainWindow 构造函数中创建的实例。

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

cobj->run();
}

你也永远不要delete MainWindow 中的Counter*,这会导致另一个内存泄漏,所以添加delete cobj 在你的 MainWindow 析构函数中。

我建议还通过使用函数指针更改各种连接以使用新语法。

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

变成:

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

这更安全,因为一些检查是在编译时完成的,例如,如果您在函数名称中输入错误,它根本不会编译。

关于c++ - 信号不会被另一个类捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56748783/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com