QApplication nicht im Mainthread



  • Hallo ich versuche mich gerade am im Titel genannten Thema mit dem Folgendem Code.

    #ifndef APPTHREAD_H
    #define APPTHREAD_H
    
    #include <QApplication>
    #include <QMainWindow>
    #include <QLabel>
    #include <pthread.h>
    #include <iostream>
    
    class Thread {
        QApplication *app;
        QMainWindow *w;
        int argc = 1;
        QLabel *l;
        char *appName = "name";
      public:
    
        void setVal(const char *val) {
            std::cout << val << std::endl;
            l->setText(val);
        }
    
        static void*  callMemberFunction(void *arg) { return ((Thread*)arg)->memberFunction(); }
    
        void*         memberFunction(void);
        void          startThread(void);
    };
    
    #endif // APPTHREAD_H
    
    #include "appthread.h"
    
    void* Thread::memberFunction(void) {
        app = new QApplication(argc, &appName);
        w = new QMainWindow();
        l = new QLabel("test");
        w->setCentralWidget(l);
        w->show();
        app->exec();
      return 0;
    }
    
    void  Thread::startThread(void) {
      pthread_t tid;
      int       result;
      result = pthread_create(&tid, 0, Thread::callMemberFunction, this);
      if (result == 0)
         pthread_detach(tid);
    }
    
    #include "ApplicationThreading/appthread.h"
    
    int main(int argc, char* argv[])
    {
      Thead t;
      t.startThread();
      t.setVal("1111");
    
      while(true);
      return 0;
    }
    

    Die Grafische Oberfläche startet auch, wenn jedoch versucht wird aus de Mainfunktion heraus einen wert in der GUI zu setzten stürzt das programm ab.
    Ich freue mich über jede hilfe ...



  • Die GUI muss in Qt (wie in so ziemlich jedem anderen Framework auch) im Hauptthread leben. Auch alle Zugriffe aus QWidgets müssen in den Hauptthread gequeued werden. Alles andere funktioniert nicht.
    Und was du machst, macht irgendwie schon prinzipiell keinen Sinn. WARUM muss QApplication in einem Seitenthread erstellt werden?



  • Mainfunktion heraus einen wert in der GUI zu setzten stürzt das programm ab.

    Tolle Fehlerbeschreibung.

    muss in Qt (...) im Hauptthread leben

    Wie unterscheidet Qt zwischen Hauptthread und anderen? Ich denke, dass Qt durchaus in einem eigenen Thread leben darf, aber jeder Zugriff nur aus diesem erlaubt ist.



  • nun, der sinn hinter meinem vorhaben ist das im hauptthread schon eine anwendung läuft ... mit einer eigenen ausführungsumgebung ... systemc, falls das hier bekannt ist.
    Meine Qt anwendung soll nun werte anzeigen die aus der systemc simulation heraus an die gui gemeldet werden.

    die fehlermeldung ist leider wirklich nicht mehr als "das programm ist abgestürzt" ... es ist ein laufzeitfehler, die compilierung klappt.

    Mittlerweile bin ich soweit das nur noch eine möglichkeit brauche um aus einer statischen memberfunktion auf eine nichtstatische membervariable zuzugreiffen, das geht ja so ohne weiteres nicht in C++.

    bin immer noch dankbar über jeglichen denkanstoß ...



  • knivil schrieb:

    muss in Qt (...) im Hauptthread leben

    Wie unterscheidet Qt zwischen Hauptthread und anderen? Ich denke, dass Qt durchaus in einem eigenen Thread leben darf, aber jeder Zugriff nur aus diesem erlaubt ist.

    Naja, Qt prüft tatsächlich an vielen Stellen, ob die Thread ID passt. Der Hauptthread ist tatsächlich der, in dem die QApplication Instanz erstellt wurde. QApplication::instance()->thread(). Somit könnte man die ganze GUI wohl in einem Seitenthread betreiben... Ich kann jetzt nicht ausschließen, dass es funktioniert, aber ich wär sicher nicht überrascht, wenn das keine stabile Lösung wäre.

    c0d3x schrieb:

    die fehlermeldung ist leider wirklich nicht mehr als "das programm ist abgestürzt" ...

    Man kann auch debuggen.

    Ich versteh ehrlich gesagt deinen ganzen Code nicht. Was machst du da mit pthread? Du brauchst auch eine Event Loop und du solltest auf dem Application Objekt exec aufrufen. Und wenn du aus anderen Threads was auf QWidgets machen willst, musst du das wohl über QMetaObject::invoke und Qt::QueuedConnection machen.


  • Mod

    Denke das dies evtl. geht, du dann aber mit dem Qt Thread per Signal Slot kommunizieren müsstest.
    Das wäre dann Threadsafe.


Anmelden zum Antworten