Pergunta

Estou escrevendo uma DLL usada como plugin por outro aplicativo e gostaria de aproveitar as habilidades do QT.
Eu tenho todas as classes configuradas, compilando e executando, mas nenhum sinal está sendo emitido. Então, parece que não há qeventloop.

Tentativa 1:
Modifiquei minha classe principal para subclasse qthread em vez de qobject e, no run () criar um qeventloop, conectar todos os sinais/slots e executar o thread.
Mas falha dizendo que você não pode ter um qeventloop sem uma qapplication.

Tentativa 2:
Modifiquei a classe principal (ainda subclassificando o QTHRAED) para instanciar uma qcoreAplicação, conectar todos os sinais/slots e executar o aplicativo.
Adverte que a qapplication não foi criada no encadeamento principal () e ainda não emitirá sinais.

Não tenho muita certeza do que fazer aqui. Obviamente, não posso criar uma opplicação QCOREAPLICAÇÃO no aplicativo que usará meu plug -in e não posso emitir sinais sem um.

Incluí um aplicativo de teste simples (e terrivelmente escrito) que deve ilustrar meu problema:

Qualquer ajuda seria apreciada!

main.cpp:

#include <iostream>
#include "ThreadThing.h"
using namespace std;
int main(int argc, char *argv[])
{
    cout << "Main: " << 1 << endl;
    ThreadThing thing1;
    cout << "Main: " << 2 << endl;
    thing1.testStart();
    cout << "Main: " << 3 << endl;
    thing1.testEnd();
    cout << "Main: " << 4 << endl;
    thing1.wait(-1);
    cout << "Main: " << 5 << endl;
    return 0;
}

Threadthing.h:

#ifndef THREADTHING_H
#define THREADTHING_H
#include <QThread>
class ThreadThing : public QThread
{
    Q_OBJECT
public:
    ThreadThing();
    virtual void run();
    void testStart();
    void testEnd();
public slots:
    void testSlot();
signals:
    void testSignal();
};
#endif//THREADTHING_H

Threadthing.cpp:

#include "ThreadThing.h"
#include <iostream>
#include <QCoreApplication>

using namespace std;

ThreadThing::ThreadThing()
{
    cout << "Constructor: " << 1 << endl;
    this->start();
    cout << "Constructor: " << 2 << endl;
}

void ThreadThing::run()
{
    cout << "Run: " << 1 << endl;
    int i = 0;
    cout << "Run: " << 2 << endl;
    QCoreApplication* t = new QCoreApplication(i, 0);
    cout << "Run: " << 3 << endl;
    connect(this, SIGNAL(testSignal()), this, SLOT(testSlot()), Qt::QueuedConnection);
    cout << "Run: " << 4 << endl;
    t->exec();
    cout << "Run: " << 5 << endl;
}

void ThreadThing::testStart()
{
    cout << "TestStart: " << 1 << endl;
    emit testSignal();
    cout << "TestStart: " << 2 << endl;
}

void ThreadThing::testEnd()
{
    cout << "TestEnd: " << 1 << endl;
    this->quit();
    cout << "TestEnd: " << 1 << endl;
}

void ThreadThing::testSlot()
{
    cout << "TEST WORKED" << endl;
}

Resultado:

Main: 1
Constructor: 1
Constructor: 2
Main: 2
TestStart: 1
TestStart: 2
Main: 3
TestEnd: 1
TestEnd: 1
Main: 4
Run: 1
Run: 2
WARNING: QApplication was not created in the main() thread.
Run: 3
Run: 4
Foi útil?

Solução

Você tenho Para criar uma qcoreAplicação ou qapplication e você tenho Para fazer isso no tópico principal.

Isso não significa que você não pode colocar o código para isso no seu plugin ... a menos que o aplicativo sempre execute cada plug -in em seu próprio thread.

Se o aplicativo é Fazendo isso, você pode tentar conectar -se a qualquer evento de evento nativo que o aplicativo use e providencie para chamar alguma função no seu plug -in no thread principal.

Outras dicas

Tive sucesso em criar um QCOREAPPLICAÇÃO e executá -lo em um thread em segundo plano. Isto é não Uma implementação padrão, mas pode funcionar para uma funcionalidade simples de sinal/slot. Fiz isso para um aplicativo iOS nativo com uma grande base de código QT Legacy.

//I really don't do anything but run on a background thread
class MyQtAppForBackgroundThread : public QCoreApplication 
{
    Q_OBJECT
    ...
}

 //iOS specific code here...
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(void){
        // This spawns a QCoreApplication on a background thread in an attempt to create something that can
        // queue signals across threads
        qtApp = new MyQtAppForBackgroundThread(smArgc, smArgv);
        qtApp->exec();

    });

Os sinais disparados no mesmo fio em que estavam conectados serão capturados. Para capturar sinais em diferentes threads, você deve criar e pesquisar um Qeventloop no thread onde os sinais foram criados.

//Fire me periodically on the thread the signals and slots were connected
QEventLoop loop;
loop.processEvents( QEventLoop::ExcludeUserInputEvents, 500 );
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top