Информация об изменениях

Сообщение MainEventsLoop в Qt библиотеке для не Qt приложения от 03.06.2020 16:57

Изменено 03.06.2020 20:57 qtprogger

MainEventsLoop в Qt библиотеке для не Qt приложения
Имеется класс Controller, который управляет некоторыми воркерами A и B с логикой взаимодействия на сигналах и слотах.
Насколько я понимаю, для того, чтобы это работало требуется QEventsLoop, который предоставляется QCoreApplication.

Controller нужно обернуть в свой класс и свою библиотеку. Как это правильно сделать?


Вот такое наивное решение попытался сделать: сунуть QAppliсation в std::tread и отделаться предупреждением, что " QApplication was not created in the main() thread.". Но не проканало. Сигналы и слоты не работают в библиотеке.
class Controller : public QObject
{
    Q_OBJECT
public:
    explicit Controller(QObject *parent = nullptr);
    int getNumber() {return mNumber;}

private:
    int mNumber {0};
    A mA;
    B mB;
    QThread *mAThread;
    QThread *mBThread;
};

void MainEventLoopStart()
{
    int j = 0;
    char *c = nullptr;
    QCoreApplication app(j,&c);
    app.exec();
}

Controller::Controller(QObject *parent) : QObject(parent)
{
    std::thread th(MainEventLoopStart);
    th.detach();

    mAThread = new QThread;
    mA.moveToThread(mAThread);
    connect(mAThread, &QThread::finished, &mA, &QObject::deleteLater);

    mBThread = new QThread;
    mB.moveToThread(mBThread);
    connect(mBThread, &QThread::finished, &mB, &QObject::deleteLater);

    connect(&mA, &A::ping, &mB, &B::setPing);
    connect(&mB, &B::pong, &mA, &A::setPong);
    mA.start();
}


Класс библиотеки
class Qlibrary
{
public:
    Qlibrary();
    int getNumber();
private:
    Controller *mController;
};

Qlibrary::Qlibrary()
{
    mController = new Controller;
}


int Qlibrary::getNumber()
{
    return mController->getNumber();
}


Воркеры
class A : public QObject
{
    Q_OBJECT
public:
    explicit A(QObject *parent = nullptr);
    int getNumber() {return mANumber;}
    void start() {emit ping();}
signals:
    void ping();

public slots:
    void setPong(int);

private:
    int mANumber {0};
};

A::A(QObject *parent) : QObject(parent) {}


void A::setPong(int n)
{
    //qDebug() << "setPong(" << n << ")";
    mANumber = n;
    if(mANumber<100) emit ping();
}

и
class B : public QObject
{
    Q_OBJECT
public:
    explicit B(QObject *parent = nullptr);

signals:
    void pong(int);

public slots:
    void setPing();

private:
    int mBNumber {0};
};

void B::setPing()
{
    //qDebug() << "setPing";
    QThread::usleep(100);
    mBNumber += 1;
    emit pong(mBNumber);
}
MainEventsLoop в Qt библиотеке для не Qt приложения
Имеется класс Controller, который управляет некоторым воркерам Worker и используем логику взаимодействия на сигналах и слотах.
Насколько я понимаю, для того, чтобы это работало требуется QEventsLoop, который предоставляется QCoreApplication.

Controller нужно обернуть в свой класс и свою библиотеку. Как это правильно сделать?


Вот такое наивное решение попытался сделать: сунуть QAppliсation в std::tread. Возникло предупреждение " QApplication was not created in the main() thread.". При запуске сигналы и слоты не работают в библиотеке.
class Controller : public QObject
{
    Q_OBJECT
public:
    explicit Controller(QObject *parent = nullptr);
    int getNumber() {return mNumber;}
    void setPong(int n);

signals:
    void ping();

private:
    std::atomic<int> mNumber {0};
    Worker mWorker;
    QThread *mWorkerThread;
};

void MainEventLoopStart()
{
    int j = 0;
    char *c = nullptr;
    QCoreApplication app(j, &c);
    app.exec();
}

Controller::Controller(QObject *parent) : QObject(parent)
{
    std::thread th(MainEventLoopStart);
    th.detach();

    mWorkerThread = new QThread;
    mWorker.moveToThread(mWorkerThread);
    connect(mWorkerThread, &QThread::finished, &mWorker, &QObject::deleteLater);

    connect(this, &Controller::ping, &mWorker, &Worker::setPing);
    connect(&mWorker, &Worker::pong, this, &Controller::setPong);
    mWorkerThread->start();

    emit ping();
}


void Controller::setPong(int n)
{
    qDebug() << "setPong(" << n << ")";
    mNumber = n;
    if(mNumber<100) emit ping();
}


Класс библиотеки
class Qlibrary
{
public:
    Qlibrary();
    int getNumber();
private:
    Controller *mController;
};

Qlibrary::Qlibrary()
{
    mController = new Controller;
}


int Qlibrary::getNumber()
{
    return mController->getNumber();
}


Воркер
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);

signals:
    void pong(int);

public slots:
    void setPing();

private:
    int mBNumber {0};
};

Worker::Worker(QObject *parent) : QObject(parent) {}


void Worker::setPing()
{
    qDebug() << "setPing";
    QThread::usleep(100);
    mBNumber += 1;
    emit pong(mBNumber);
}