Funktion über QPushButton beenden



  • fr33g schrieb:

    Heißt dass ich darf zum beispiel lineEdit->getText() benutzen, aber zum Beispiel nicht über die run() des anderen Threads ein Objekt meinem listWidget auf dem MainWindow hinzufügen, sprich die Objekte verändern?

    So hab ich das in Erinnerung. Und ich hab dir sogar nen kleinen Test geschrieben, und bin total aus den Wolken gefallen!

    test.h

    #include <QThread>
    #include <QLineEdit>
    #include <QDebug>
    #include <QMetaObject>
    
    class Thread : public QThread
    {
        Q_OBJECT
        QLineEdit* edit;
        void run() {
            while(true) {
                qDebug() << "Text:" << edit->text();
                qDebug() << edit->thread() << thread();
                QThread::sleep(1);
                edit->setText("BÖÖÖÖHSE!");
                QMetaObject::invokeMethod(edit, "setText", Qt::QueuedConnection, Q_ARG(QString, "Wunderbar!"));
            }
        }
    public:
        Thread(QLineEdit* e)
         : edit(e)
        {
        }
    };
    

    main.cpp

    #include <QLineEdit>
    #include <QApplication>
    #include "test.h"
    
    int main(int argc, char** argv) {
        QApplication app(argc, argv);
        QLineEdit e;
        Thread t(&e);
        e.show();
        t.start();
        return app.exec();
    }
    

    Der direkte Aufruf sollte scheitern, mit QMetaObject::invokeMethod + QueuedConnection sollte der Zugriff save sein.
    Die böse Überraschung hier (Linux, Qt-4.6.3): setText() hat auch funktioniert 😮
    Ich konnte sogar vom anderen Thread aus die geometry des lineEdit ändern (resize()), ebenso das lineEdit in den anderen Thread verschieben!
    Ich weiß aus früheren Tests, dass hier immer eine Meldung seitens Qt zur Laufzeit auftauchte, dass dies nicht möglich ist, und basta. Ich schau mal, das hört sich verdammt nach Bug an...



  • Ja, ich hab bei mir mal gedebugt und da is er immer an der Stelle rausgeflogen, wo ich zum Beispiel nen Button sichtbar machen wollte, sprich ein Objekt vom Hauptthread verändern wollte.

    Ich probier das ganze jetzt mal mit SIGNAL und SLOTS hinzubekommen, müsste ja funktionieren wenn ich dann an der Stelle nen selbst erstelltes Signal von meinem Thread auslöse, und im Hauptthread dadrauf reagiere.
    Denk ich mal oder nicht?

    Ich probiers jetzt auf jeden Fall mal.

    Gruß freeG und vielen Dank nochmals für Eure Mühe schon bis hier hin=)



  • fr33g schrieb:

    Ich probier das ganze jetzt mal mit SIGNAL und SLOTS hinzubekommen, müsste ja funktionieren wenn ich dann an der Stelle nen selbst erstelltes Signal von meinem Thread auslöse, und im Hauptthread dadrauf reagiere.
    Denk ich mal oder nicht?

    Probiers mal erst mit QMetaObject::invokeMethod (wie oben gezeigt). Geht aber nicht mit "normalen" Methoden.



  • Oh sorry, habs zu spät gelesen.
    Hab es schon probiert, und siehe da, er stürzt net ab, es läuft, das mit dem Thread klappt auch, da jetzt der start-Button nicht dauerhaft makiert ist, und ich auch den anhalte-Button betätigen kann.

    Das Problem ist blos, den Thread stoppen tut er trotzdem nicht=(

    Hat jemand ne Idee wo dran das noch liegen könnte?

    Gruß freeG

    EDIT:

    Es funtkionieeert endlich=)
    Ich habe ausversehen die Funktion die die boolean Variable ändert so implementiert, dass sie stop auf false setzt anstatt true 😃

    Jetzt funktioniert alles einwandfrei.

    Vielen Lieben Dank für Eure Hilfe.

    Gruß freeG



  • l'abra d'or schrieb:

    @padreigh
    Dir ist klar, dass in deinem mainWidget.cpp:13 "setSearchParams" im Context des main-thread ausgeführt wird. Deshalb wird damit auch deine GUI blockieren, solange der Thread läuft!

    Mhh .. das das im MainThread läuft ist mir klar, das es [länger] blockiert nicht. Ich habe bewußt auf jegliche SLOTs im QThread verzichtet da allein das QThread dem Fragesteller schon Schwierigkeiten machte ;). Aber deine Lösung wäre performanter in Hinsicht auf GUI-Interaktion und das GUI-Erleben des Anwenders. Ich vermute mal du meinst den Teil hier der blockiert:

    if ( isRunning() )
        {
            stop = true;
            while (isRunning())
            {  /* do nothing  */ }  
        }
    

    Du hast recht, es ist unsauber und blockiert ... bei suffizient kleinen Sucheinzelschritten ist das kaum merkbar da die run() nach diesem Suchschritt beendet wird (stop == true). Im heutigen Zeitalter sind die Computer fix, daher könnte es unbemerkt gehen - muss aber nicht. Ich würde der Methode mit lokalen Kopien in der run() dann wohl den Vorzug geben und die eventuell noch mutex'n damit nicht jemand ganz fix auf "Start" drückt, einen Parameter ändert und wieder auf "Start" drückt und somit privates ändert wärend run() sie gerade in lokale Kopien steckt 😉


Anmelden zum Antworten