QThread



  • Abend,
    wie ist es zu bewerkstelligen in einer Thread klasse auf die .ui file zuzugreifen?
    //thread.h

    #ifndef THREAD_H
    #define THREAD_H
    #include <QThread>
    #include "ui_tpopt.h"
    #include <QtGui/QMainWindow>
    
    class Thread : public QThread {
       Q_OBJECT
    
    public:
    	Thread();
    protected:
       void run();
    private:	 
    Ui::tpoptClass u;  
    };
    

    //thread.cpp

    #include "thread.h"
    #include "tpopt.h"
    
    #include <QTextStream>
    #include <QFile> 
    
    Thread::Thread() {
    
    }
    void Thread::run() {
    ui. textEdit_5->setText(“test“);
    }
    

    //tpopt.h

    #ifndef TPOPT_H
    #define TPOPT_H
    
    #include <QtGui/QMainWindow>
    #include "ui_tpopt.h"
    #include "ui_projekt.h"
    #include "projekt.h"
    #include "thread.h"
    
    #define _WIN32_WINNT 0x0500
    #include <windows.h>
    #include <iostream>
    
    class tpopt : public QMainWindow
    {
    Q_OBJECT
    
    public:
    	tpopt(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~tpopt();
    
    private:
    	Thread thread1;
    	Ui::tpoptClass ui;
    public slots:
    };
    
    #endif // TPOPT_H
    

    Leider bricht das Programm mit der Fehlermeldung ab:
    Unbehandelte Ausnahme bei 0x652f42da (QtGuid4.dll) in tpopt.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xccccccd0.
    Class Q_GUI_EXPORT QTextEdit : public QAbstractScrollArea
    {

    Q_DECLARE_PRIVATE(QTextEdit)

    Bin für jeden Tip sehr dankbar.
    lg



  • Zwei Dinge solltest Du beachten:

    1. Um die Objekte Deiner ui Klasse zu instanzieren, solltest Du

    ui->setupUi(this);
    

    aufrufen. Damit sollte die Accessviolation weg sein...

    2. Es ist unter QT NICHT möglich von einem Thread aus auf Elemente des GUI
    zuzugreifen !!!!
    Also macht Dein Konstrukt nicht wirklich Sinn..

    Du könntest von Deiner Run Methode aus aber ein Signal an Deine UI Klasse schicken bei der Du den anzuzeigenden String übermittelst.

    Grüsse



  • Du weißt nicht vielleicht ob ich mit QProcess aus interne Funktionen asynchron starten kann. Wenn das geht brauche ich keine Threads mehr.
    lg



  • Ok, habe versucht einen Vorschlag umzusetzen, es scheitert glaube ich an einer Kleinigkeit.

    Edit::

    das progi wird ohne Fehler gestartet, aber wenn run gestartet wird bricht alles mit der Fehlermeldung ab:

    Run-Time Check Failure #3- The variable 'b' is being used without being initialized

    verweis auf connect(this, SIGNAL(lV(QString)), b, SLOT(setV(QString)));

    //thread.h

    #ifndef THREAD_H
    #define THREAD_H
    #include <QThread>
    #include "ui_tpopt.h"
    #include <QtGui/QMainWindow>
    #include <QProcess>
    
    class Thread : public QThread {
       Q_OBJECT
    
    public:
    Thread();
    protected:
       void run();
    signals:
         void lV(QString newValue);
    
    };
    
    #endif
    
    void Thread::run() {
    
    	tpopt *b;	
    	connect(this, SIGNAL(lV(QString)), b, SLOT(setV(QString))); 
    
    }
    

    //tpopt.h

    #ifndef TPOPT_H
    #define TPOPT_H
    
    #include <QtGui/QMainWindow>
    #include <QProcess>
    #include "ui_tpopt.h"
    #include "ui_projekt.h"
    #include "projekt.h"
    #include <thread.h>
    
    #define _WIN32_WINNT 0x0500
    #include <windows.h>
    #include <iostream>
    
    class tpopt : public QMainWindow
    {
    Q_OBJECT
    
    public:
    	tpopt(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~tpopt();
    
    private:
    	Thread thread1;
    	Ui::tpoptClass ui;
    public slots:
         void setV(QString value){
    	 ui.textEdit_6->setText(value);
         }
    
    };
    
    #endif // TPOPT_H
    

    //tpopt

    #include <QtGui>
    #include "tpopt.h"
    
    #include <QProcess>
    #include <QInputDialog>
    #include <QMessageBox>
    #include <signal.h>
    #include "thread.h"
    
    #include <QTextStream>
    #include <QFile>
    … ( hat sich nichts geändert )
    


  • Die Antwort hier, reicht Dir nicht?



  • Anscheinend nicht.

    Gegenfrage ? Was hätte Dich mehr Zeit gekostet, zu recherchieren an wen ich die Frage sonnst gestallt habe oder eine Antwort zu geben die weiterhilft ?

    Wie zum Beispiel.: schau dir Objekt Definition in und außerhalb der Klasse an.

    Ps.: läuft jetzt und habe es auch online gestellt, falls jemand ein ähnliches Problem hat.

    Schönen Abend noch 😉



  • Also hat die Antort im anderen Forum ja doch was gebracht, oder wo ist Initialisierung des Pointers "b" hin?



  • Jein,
    im Grunde nur das „worauf zeig b“, hat mich verstehen lassen das es so nur ein Zeiger ist.

    Es hätte so aussehen müssen.
    tpopt b;
    connect(this, SIGNAL(lV(QString)), &b, SLOT(setV(QString)));
    so wäre es glaube ich auch noch gegangen
    tpopt *b=new tpopt;
    connect(this, SIGNAL(lV(QString)), &b, SLOT(setV(QString)));

    Als ich das versucht habe kam die Fehlermeldung:
    SERT failure in QWidget: " Widgets must be created in the GUI thread. ".
    Also habe ich das connect aus der Thread::run() in den Konstruktor des Main Threads verschoben.



  • nun, nja
    lV(„text“) wird leider nicht in jeder Funktion angezeigt.

    Thread::Thread()
    : QThread()
    {
    	asy = new QProcess();
    	connect(asy, SIGNAL(started()), this, SLOT(readfrompp()));
    }
    Thread::run(){
    asy->start(blub);
    }
    void Thread::readfrompp(){
    	cout<<"bgb"<<endl;
    	lV("bbbbbb");
    …
    

    Cout geht aber lV nicht. ( jedoch geht LV in run() und allen anderen Funktionen.)

    Edit::
    Habe den Fehler gefunden:
    Rufe eine Funktion auf die nicht zur Thread Klasse gehört welche. Diese ruft eine externe Funktion auf. Connect erkennt das und startet eine in der Thread Deferierte Funktion.
    Würde ich soft diese Deferierte Funktion aufrufen würde alles richtig funktionieren.

    Kann man das Problem lösen ohne alles in eine Klasse zu stecken ?

    &Thread::lV("miau");

    Kein Zugriff auf protected Member, dessen Deklaration in der Thread-Klasse erfolgte.



  • Da fehlt ein emit

    void Thread::readfrompp(){
        cout<<"bgb"<<endl;
        emit lV("bbbbbb");
    


  • Bam es läuft, 😃 😃 😃 😃 😃 😃
    Im Mainthread wird ein Thread gestartet welcher, eine Asynchronen QProcess startet welcher auslesen wird.
    Es funktioniert jedoch taucht einer Fehlermeldung in der cmd auf die mich benuruigt.

    QObject: Cannot creat children for a parent that is in a different thread
    Parents thread is QThread, current thread is Thread.
    Dieser Fehler taucht erst nachdem ich einen QProcess im Thread starte.

    Edit: habe in den Thread Kons. asy->moveToThread(this); eingebaut 🙂 läuft

    thread.cpp

    Thread::Thread()
    : QThread()
    {
    	asy = new QProcess();
    	connect(asy, SIGNAL(readyRead()), this, SLOT(readfrompp()));
    }
    
    void Thread::readfrompp(){
    	 QByteArray line;
    	if( asy->state() != QProcess::Running ){
    		lV("Prozess läuft nicht!");
    		return;
    	}
    	while(! (line =asy->readLine()). isEmpty() ) {
    		QString output(QString::fromLatin1(line));
    		output.chop(2);
    		lV(output);
    	}
    }
    

Anmelden zum Antworten