5

我正在编写一个 DLL,它被另一个应用程序用作插件,并希望利用 Qt 的功能。
我已经设置、编译和运行了所有类,但没有发出任何信号。所以看起来好像没有QEventLoop。

尝试1:
我将我的主类修改为子类QThread而不是QObject,并在run()中创建一个QEventLoop,连接所有信号/插槽,并执行线程。
但是它没有说没有 QApplication 就不能拥有 QEventLoop。

尝试 2:
我修改了主类(仍然是 QThraed 的子类)以实例化 QCoreApplication,连接所有信号/插槽,然后执行应用程序。
警告 QApplication 不是在 main() 线程中创建的,并且仍然不会发出信号。

我不确定在这里做什么。我显然无法在将使用我的插件的应用程序中创建一个 QCoreApplication,而且我不能在没有它的情况下发出信号。

我已经包含了一个简单的(并且写得很糟糕)测试应用程序,它应该可以说明我的问题:

任何帮助,将不胜感激!

主.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 回答