在Qt中发出信号的速度有多快或有多少?

时间:2013-05-21 17:59:32

标签: qt signals-slots qthread

我前几天正在尝试使用QThread,我想通过仅使用信号来创建一个无限循环,而不是为了foreach或while,但是在发出信号并执行插槽多次后,我的代码会崩溃我的代码:

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "worker.h"
#include <QThread>
#include <QDebug>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
    QThread thread;
    worker *work;

};

#endif // MAINWINDOW_H

//worker.h
#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QDebug>
#include <QMutex>
#include "insiderobject.h"

class worker : public QObject
{
    Q_OBJECT
public:
    explicit worker(QObject *parent = 0);

signals:
    void doagain();
    void okidid();
    void finished();

public slots:
    void printing();
};

#endif // WORKER_H

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

MainWindow::~MainWindow()
{
    thread.wait();
    delete ui;
    delete work;
}

void MainWindow::startthreads()
{
    work = new worker;
    work->moveToThread(&thread);
    connect(&thread, SIGNAL(started()), work, SLOT(printing()));
    connect(work, SIGNAL(finished()), &thread, SLOT(quit()));
    thread.start();
}

//worker.cpp
#include "worker.h"

worker::worker(QObject *parent) :
    QObject(parent)
{
    connect(this, SIGNAL(okidid()), this, SLOT(printing()));
}

void worker::printing()
{
    qDebug() << "printing";
    emit okidid();
}

//main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

我已经阅读了信号/插槽和线程以及排队连接的完整文档或者我可以得到的任何东西,但我无法理解这次崩溃的原因...我也试过在Qt irc与人和开发人员聊天聊天室,但没有人能告诉我原因。

1 个答案:

答案 0 :(得分:3)

您正在做的是无限递归。 emit okidid();实际上是对worker::printing()的直接调用。这将导致堆栈溢出。

您可以使用排队信号连接解决此问题:

connect(this, SIGNAL(okidid()), this, SLOT(printing()), Qt::QueuedConnection);

现在emit okidid();不再是直接函数调用了。将在Qt的事件循环中调用worker::printing()函数。