1

前几天我在试验QThread,我想通过只使用信号而不是for、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 聊天室与人和开发人员聊天,但是没有人能告诉我原因。

4

1 回答 1

3

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

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

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

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

于 2013-05-21T18:11:47.077 回答