QT SLOT称为1,2,3 ......次

时间:2014-10-20 16:20:54

标签: c++ qt qt-creator

我正在连接一个信号/插槽但是每次触发选项时都会多次调用插槽(1,2,3 ...),这是我的类:

mainwindow.h:

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
    Dialog *dialog;

signals:
    void s1(QString s);

private slots:
    void on_actionTooo_triggered();
};

#endif // MAINWINDOW_H

mainwindow.cpp:

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

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

void MainWindow::on_actionTooo_triggered()
{
    dialog = new Dialog(this);
    QString s = "hello";
    qDebug() << "CONNECT: " << connect(this, SIGNAL(s1(QString)),
            dialog, SLOT(s1(QString)), Qt::UniqueConnection);
    emit s1(s);
    dialog->show();
}

dialog.h:

class Dialog : public QDialog
{
    Q_OBJECT

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

public slots:
    void s1(QString str);

private:
    Ui::Dialog *ui;
};

dialog.cpp:

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

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

void Dialog::s1(QString str)
{
    qDebug() << str << endl;
}

每次在主窗口中触发选项时,我将信号(仅一次)连接到新对话框,但是当我运行时,例如两次,它会打印两个“你好”。如果我在连接信号之前放了disconnect(this, 0, 0, 0);,那就可以了。

对我来说,即使对象被破坏,它仍然保持连接似乎很奇怪。它将连接绑定到之前创建的同一对象。这是预期的行为吗?

3 个答案:

答案 0 :(得分:4)

每次拨打Dialog时,您都会创建新的on_actionTooo_triggered()。在您的功能结束时,Dialog不会被删除。因此,在下次调用时,信号MainWindow::s1(QString)将发送到两个不同的Dialog,这会在qDebug中产生多个输出。

答案 1 :(得分:2)

void MainWindow::on_actionTooo_triggered()
{
    dialog = new Dialog(this);
    QString s = "hello";
    qDebug() << "CONNECT: " << connect(this, SIGNAL(s1(QString)),
            dialog, SLOT(s1(QString)), Qt::UniqueConnection);
    emit s1(s);
    dialog->show();
}

此代码每次触发时都会创建一个新对话框,并在新创建的对话框和MainWindow之间建立连接。虽然连接被指定为“唯一”,但每次都会创建一个新对话框,因此连接不是唯一的,因为对话框实例不同。

您的代码未显示该对话框正在被删除,即使您关闭其窗口,该实例仍保留在内存中,因此多个对象正在接收相同的信号。

答案 2 :(得分:0)

此代码中永远不会销毁您的Dialog。当你在this的构造函数中将Dialog作为父项传递时,它甚至都没有泄露,这使得MainWindow负责此Dialog内存。

因此,您将永久创建另外的Dialog将触发哪个插槽,从而解释为什么您会看到输出的重复递增。