Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You need to start QApplication in a separate QThread. This is shown in the code below. I haven't gotten it working on OS X yet, but I believe it should be doable. I need first to get a debug build made for OS X, then I'll see what's up. It's tested to work on Windows, and will probably work on X11 too. The Objective C code is for mac only, it's probably required but not sufficient yet.</p> <p>It is an entire runnable application, for a library you'd remove the <code>main()</code> function and call init, changePos and finish directly as appropriate.</p> <pre><code>#applib.pro QT += core gui TARGET = applib TEMPLATE = app !x11:!embedded:!qpa:mac { LIBS_PRIVATE += -framework Cocoa -lz OBJECTIVE_SOURCES += thread.mm } SOURCES += main.cpp </code></pre> <pre><code>//main.cpp #include &lt;cstdlib&gt; #include &lt;QtCore/QThread&gt; #include &lt;QtCore/QMutex&gt; #include &lt;QtCore/QMutexLocker&gt; #include &lt;QtCore/QWaitCondition&gt; #include &lt;QtCore/QEvent&gt; #include &lt;QtGui/QLabel&gt; #include &lt;QtGui/QApplication&gt; // // API // extern "C" { void init(int argc, char ** argv); void changePos(int x, int y); void finish(); } // demonstration code, remove from the library int main(int argc, char ** argv) { class Helper : private QThread { public: static void msleep(unsigned long ms) { QThread::msleep(ms); } }; init(argc, argv); Helper::msleep(2000); changePos(0, 0); Helper::msleep(2000); finish(); } // // IMPLEMENTATION // struct PosEvent : public QEvent { PosEvent(int x_, int y_) : QEvent(t()), x(x_), y(y_) {} const int x, y; static QEvent::Type t() { return (QEvent::Type)(QEvent::User + 0); } }; class Widget : public QLabel { public: Widget() : QLabel("Hello!") {} protected: void customEvent(QEvent * ev) { if (ev-&gt;type() == PosEvent::t()) { PosEvent * pev = static_cast&lt;PosEvent*&gt;(ev); move(pev-&gt;x, pev-&gt;y); } } }; class QCoreApplicationPrivate { public: static QThread * theMainThread; }; extern "C++" { Qt::HANDLE qt_application_thread_id; } class AppThread : public QThread { public: AppThread(int&amp; argc_, char ** argv_) { Q_ASSERT(!instance); instance = this; QMutexLocker lock(&amp;argMutex); argc = &amp;argc_; argv = argv_; start(); wc.wait(&amp;argMutex); } static void changePos(int x, int y) { QCoreApplication::postEvent(instance-&gt;widget, new PosEvent(x,y)); } static void finish() { instance-&gt;app-&gt;exit(); instance-&gt;wait(); delete instance; } protected: void run() { int i = 0; #ifdef Q_OS_UNIX //qDebug("%p", qt_application_thread_id); QCoreApplicationPrivate::theMainThread = QThread::currentThread(); #endif QApplication a(i, 0); app = &amp;a; wc.wakeAll(); Widget w; widget = &amp;w; w.show(); rc = a.exec(); } private: static AppThread * instance; QCoreApplication * app; QObject * widget; QMutex argMutex; QWaitCondition wc; int* argc; char** argv; int rc; }; AppThread * AppThread::instance = 0; bool multiThreader(); #ifndef Q_OS_MAC bool multiThreader() { return true; } #endif extern "C" void init(int argc, char ** argv) { multiThreader(); #ifdef Q_OS_MAC qDebug("DYLD_IMAGE_SUFFIX=%s", getenv("DYLD_IMAGE_SUFFIX")); #endif new AppThread(argc, argv); } extern "C" void changePos(int x, int y) { AppThread::changePos(x, y); } extern "C" void finish() { AppThread::finish(); } </code></pre> <pre><code>//thread.mm #import &lt;Foundation/Foundation.h&gt; @interface DeadThread : NSObject { ;; } + (void)enterMultiThreadedMode; + (void)emptyThreadMethod:(id)obj; @end @implementation DeadThread + (void)enterMultiThreadedMode { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [NSThread detachNewThreadSelector:@selector(emptyThreadMethod:) toTarget:[DeadThread class] withObject:nil]; [pool release]; } + (void)emptyThreadMethod:(id)obj { (void)obj; } @end bool multiThreader() { [DeadThread enterMultiThreadedMode]; return [NSThread isMultiThreaded]; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload