Seite 1 von 2

Thread und die Aktualisierung der Tabelle

Verfasst: 27. Juli 2005 17:23
von rulzmaker
Ich habe eine Thread Funktion die aller 1er Sekunde eine Row einer Tabelle hinzufügt und das 100 mal. Leider werden die einzelnen Rows erst nach den einhundert erstellten angezeigt. Woran liegt das?

Verfasst: 27. Juli 2005 17:37
von Goos
Ich vermute, dass du etwas mit deinem thread falsch gemacht hast und er dein GUI blockiert.

Goos

PS: eine etwas ausfuehrlichere Beschreibung waer gut. Das was du hier sagst ist wie "Ich steige ins Auto, trete aufs Gas und es faehrt nicht. Woran liegt das?" ;)

Verfasst: 27. Juli 2005 17:54
von FlorianBecker
Na ist doch logisch, das Gaspedal drückt nicht genügend Sprit in den Motor.

Verfasst: 27. Juli 2005 18:06
von rulzmaker

Code: Alles auswählen

 MyThread bla(this);
 bla.start();
 bla.wait();

void MyThread::run()
{
    for(int i=0; i<100;++i)
    {
    _toni->_form4->addRow(i);
    usleep(1000000);
    }
}

void Form4::addRow(int row)
{
  Tabelle->insertRows(row);  
  Tabelle->showRow(row);
}
Nix mit Gaspedal....der main Thread hat genug Zeit um alles zu zeichnen!

Verfasst: 27. Juli 2005 23:35
von rulzmaker
Hat keiner eine Ahnung was ich tun müsste?

Verfasst: 28. Juli 2005 00:13
von FlorianBecker
Schonmal mit update des ListViews probiert?

Verfasst: 28. Juli 2005 06:47
von Goos
FlorianBecker hat geschrieben: Na ist doch logisch, das Gaspedal drückt nicht genügend Sprit in den Motor.
...jetzt wo du das sagst :D
rulzmaker hat geschrieben: Nix mit Gaspedal....der main Thread hat genug Zeit um alles zu zeichnen!
Zeit vielleicht schon, aber du willst das doch nicht ;)
Mit deinem bla.wait() sagst du deinem Main Thread doch, dass er warten soll, bis die 100 Zeilen eingefuegt sind.

Goos

Verfasst: 28. Juli 2005 12:12
von lepsai
So geht es nicht. Man kann nicht aus einem Thread in der GUI was ändern.
Dafür gibt es QApplication::postEvent() und QCustomEvent. Wir haben das aber schon mal besprochen in diesem Forum....

Verfasst: 28. Juli 2005 13:46
von rulzmaker
Hab nun neues Projekt mit qt designer erstellt:

Code: Alles auswählen

#include <qapplication.h>
#include "fenster.h"

#include <qtable.h>
#include <qthread.h>

QTable *tab;

class MyThread : public QThread 
{
    public:
     virtual void run();
};

void MyThread::run()
{
    for(int i=0; i<20; ++i)
    {
	tab->insertRows(i);
	tab->showRow(i);
	sleep(1);
    }
}

int main( int argc, char ** argv )
{
    QApplication a( argc, argv );
    Form1 w;
    w.show();
    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
   
    tab=w.getTable();
    MyThread t;
    t.start();
    
    return a.exec();
}
Und siehe an es funktioniert...ihr scheint nicht wirklich viel Erfahrung mit thread zu haben.

PS: mit den send events hatte ich schon herumexperimentiert, kam aber nichts gescheites außer Speicherschutzverletzungen heraus (ich nahm das update event).

Verfasst: 28. Juli 2005 13:53
von Goos
rulzmaker hat geschrieben:Und siehe an es funktioniert...ihr scheint nicht wirklich viel Erfahrung mit thread zu haben.
Wie kommst darauf?

Verfasst: 28. Juli 2005 14:04
von rulzmaker
Ach verdammt. Es funxt doch nicht...ich Trottel ;-(

Ich probiers nun doch nochmal mit den Events...Könnt ihr mir dabei Helfen - hab es gestern vergeblich versucht.

Code: Alles auswählen

#include <qapplication.h>
#include "fenster.h"

#include <qtable.h>
#include <qthread.h>
#include <qevent.h>

class MyThread : public QThread 
{
    public:
     MyThread(QTable *tabelle,QApplication *app);	
     virtual void run();
    private:
    QTable *_tabelle;
    QApplication *_app;
};

MyThread::MyThread(QTable *tabelle,QApplication *app)
    :QThread()
{
    _tabelle=tabelle;
    _app=app;
}
void MyThread::run()
{
    QEvent *event=new QEvent(QEvent::Paint);
    for(int i=0; i<10; ++i)
    {
	_tabelle->insertRows(i);
	_tabelle->showRow(i);
	_app->postEvent(_tabelle, event);
	sleep(1);
    }
}

int main( int argc, char ** argv )
{
    QApplication a( argc, argv );
    Form1 w;
    w.show();
    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );

    MyThread t(w.getTable(), &a);
    t.start();
    
    return a.exec();
}
Seitdem ich das mit dem Event drin habe, kommt kurz nach dem Aufruf des Programmes eine Speicherschutzverletzung.

Verfasst: 28. Juli 2005 14:33
von rulzmaker
Mit sendEvent() scheint es zu funktionieren. Doch wenn ich das Fenster andauernd verkleicher/vergößere kommt folgendes:

Xlib: unexpected async reply (sequence 0x6292)!

Verfasst: 28. Juli 2005 14:40
von rulzmaker
Habs gelöst (jippie aufschrei). Das lag warscheinlich daran das auch noch andere Threads auf das Tabellen widget zugreifen und mein Thread mit den anderen ins Gehege kam. QMutex löst das Problem:

Code: Alles auswählen

#include <qapplication.h>
#include "fenster.h"

#include <qtable.h>
#include <qthread.h>
#include <qevent.h>
#include <qmutex.h>

QTable *tab;

class MyThread : public QThread 
{
    public:
     MyThread(QTable *tabelle,QApplication *app, Form1 *fenster);	
     virtual void run();
    private:
    QTable *_tabelle;
    QApplication *_app;
    Form1 *_fenster;
};

MyThread::MyThread(QTable *tabelle,QApplication *app,Form1 *fenster)
    :QThread()
{
    _tabelle=tabelle;
    _app=app;
    _fenster=fenster;
}
void MyThread::run()
{
    QMutex mutex;
    QEvent *event=new QEvent(QEvent::Paint);
    for(int i=0; i<100; ++i)
    {
	_tabelle->insertRows(i);
	mutex.lock();
	_tabelle->showRow(i);
	_app->sendEvent(_fenster, event);
	mutex.unlock();
	sleep(1);
    }
    _app->sendEvent(_fenster, event);
}

int main( int argc, char ** argv )
{
    QApplication a( argc, argv );
    Form1 w;
    w.show();
    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );

    MyThread t(w.getTable(), &a, &w);
    t.start();
    
    return a.exec();
}
EDIT: lol...shit happens. Wennich das Fenster ganz ganz schnell verkleinere/vergrößere kommt folgendes:
Xlib: unexpected async reply (sequence 0x58a2)!

Verfasst: 28. Juli 2005 14:53
von Goos
Du hast das mit dem Mutex nicht begriffen, scheint mir :)

Verfasst: 28. Juli 2005 15:10
von rulzmaker
ölö...ICh hatte es aus einem anderen Forum aufgeschnappt. Derjenige schrieb das er mutex überall dort eingesetzt hat wo irgednwas mit den widgets getan wurde (gezeichnet)...