Есть ли какие-либо ограничения на скорость или количество сигналов, которые могут быть отправлены в Qt?

На днях я экспериментировал с 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, но никто не мог сказать мне причину.


person moki    schedule 21.05.2013    source источник


Ответы (1)


То, что вы делаете, является бесконечной рекурсией. emit okidid(); на самом деле является прямым вызовом worker::printing(). Это вызовет переполнение стека.

Вы можете исправить это, используя сигнальное соединение с очередью:

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

Теперь emit okidid(); больше не является прямым вызовом функции. Функция worker::printing() будет вызываться в цикле событий Qt.

person Community    schedule 21.05.2013
comment
Публиковать вопрос о переполнении стека на stackoverflow НЕ иронично :D - person moki; 21.05.2013