2009-11-23 54 views
4

我正在寫一個DLL作爲另一個應用程序的插件,並希望利用Qt的能力。
我有所有的類建立,編譯和運行,但沒有信號正在發射。 所以看起來好像沒有QEventLoop。Qt庫事件循環問題

嘗試1:
我修改我的主類爲子類QThread而不是QObject,並在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 

回答

5

來創建一個QCoreApplication或QApplication,而你在主線程中這樣做。

這並不意味着你不能將代碼放在你的插件中......除非應用程序總是在它自己的線程中運行每個插件。

如果應用程序這樣做,那麼您可以嘗試連接應用程序使用的任何本機事件循環,並安排它在主線程中調用插件中的某個函數。

+0

不幸的是,我不能觸摸目前正使用我的插件主要應用什麼,我只得到執行代碼時,它調用的函數的數量有限(DLL鉤子和一對夫婦的註冊功能)。最重要的是,我不知道我的DLL是被主線程還是插件管理的。 最糟糕的是,即使我在主線程空間中,當它傳遞給我控件時,我也無法調用阻塞exec()語句,因爲我必須返回主應用程序才能運行。 那麼是否絕對沒有辦法讓我有一個非Qt第三方應用程序的Qt庫? – Marc

+0

如果您找不到安全的方式來實例化QCoreApplication或QApplication,那麼您無法使用大部分Qt。不過,如果您找不到某種解決方案,我會感到驚訝 - 畢竟,您有一個C++插件,可以在應用程序過程中執行任意代碼。將有一種方法來使其工作。 – rohanpm

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