Qtのライブラリイベントループの問題
-
21-09-2019 - |
質問
私は別のアプリケーションでプラグインとして使用されているDLLを書いていると、レバレッジQtの能力にしたいと思います。
私は、コンパイルおよび実行、設定のすべてのクラスを持っていますが、何の信号が放出されないされています。
何QEventLoopはありませんかのようにそれはそう思えるます。
1試みます。
私は、QEventLoopを作成し、すべての信号/スロットを接続し、スレッドをexecしQThreadの代わりに、QObjectのサブクラスで、私のメインクラスを変更し、実行中に()。
しかし、それはあなたがはQApplicationなしQEventLoopを持つことができないと言って失敗します。
2試みます。
私はQCoreApplication代わりにインスタンス化する(まだQThraedをサブクラス)メインクラスを変更し、すべての信号/スロットを接続し、アプリケーションをEXEC。
QApplicationメイン()スレッドで作成されていない、まだ信号を放出しないであろう。
私はここで何をすべきか本当にわかりません。私は明らかに私のプラグインを使用するアプリケーションでQCoreApplicationを作成することはできません、と私は1つずに信号を発信することはできません。
私の問題を説明する必要があります。私はシンプルを含め(と恐ろしく書かれた)しているテストアプリケーション:
すべてのヘルプをいただければ幸いです!
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
解決
あなたのHAVE のQCoreApplicationかはQApplicationを作成するために、あなたのHAVE のメインスレッドでそれを行うには。
それは、アプリケーションが常に独自のスレッドで各プラグインを実行しない限り、あなたは...あなたのプラグインにはそのためのコードを置くことができないという意味ではありません。
もしアプリケーションののあることをやって、あなたはどんなネイティブのイベントループにして、アプリの使用をフックしてみてください、そして、それはメインスレッドでプラグインにいくつかの関数を呼び出すために手配することができます。
他のヒント
私は成功が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 );