5

別のアプリケーションでプラグインとして使用され、Qtの機能を活用したいDLLを作成しています。
すべてのクラスをセットアップ、コンパイル、実行していますが、信号が出力されていません。したがって、QEventLoopがないように見えます。

試行1:
メインクラスをQObjectではなくサブクラスQThreadに変更し、run()でQEventLoopを作成し、すべてのシグナル/スロットを接続して、スレッドを実行します。
しかし、QApplicationなしではQEventLoopを使用できないとは言えません。

試行2:
メインクラスを変更して(まだQThraedをサブクラス化)、代わりにQCoreApplicationをインスタンス化し、すべてのシグナル/スロットを接続してから、アプリケーションを実行します。
QApplicationがmain()スレッドで作成されておらず、それでもシグナルを発行しないことを警告します。

ここで何をすべきかよくわかりません。プラグインを使用するアプリケーションでQCoreApplicationを作成することはできません。また、プラグインがないとシグナルを送信できません。

私の問題を説明する簡単な(そして恐ろしく書かれた)テストアプリケーションを含めました:

どんな助けでもいただければ幸いです!

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;
}

出力:

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
4

2 に答える 2

5

QCoreApplicationまたはQApplicationを作成する必要あり、メインスレッドで作成する必要があります。

これは、そのためのコードをプラグインに入れることができないという意味ではありません...アプリケーションが常に各プラグインを独自のスレッドで実行しない限り。

アプリケーションそれを実行している場合は、アプリが使用するネイティブイベントループにフックインして、メインスレッドのプラグインで関数を呼び出すように調整できます。

于 2009-11-23T22:38:11.863 に答える
1

QCoreApplicationを作成し、バックグラウンドスレッドで実行することに成功しました。これは標準の実装ではありませんが、単純な信号/スロット機能で機能します。これは、大規模なレガシーQtコードベースを備えたネイティブiOSアプリに対して行いました。

//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();

    });

それらが接続されたのと同じスレッドで発生した信号がキャッチされます。異なるスレッドでシグナルをキャッチするには、シグナルが作成されたスレッドでQEventLoopを作成してポーリングする必要があります。

//Fire me periodically on the thread the signals and slots were connected
QEventLoop loop;
loop.processEvents( QEventLoop::ExcludeUserInputEvents, 500 );
于 2013-01-07T20:26:30.737 に答える