neue Tabellenzeilen werden nicht auf Anhieb gezeichnet



  • 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); 
     }
    

    Einer Tabelle werden haufen Zeilen hinzugefügt. Problem ist, dass erst nach den 100 Zeilen die Tabelle neu gezeichnet wird und erst dann die Zeilen zu sehen sind.



  • Welches Toolkit?



  • C++ falls du das meinst.
    QT Version 3.3.4



  • Qt meint er wohl.

    Hilft QApplication::processEvents(x); in der Zeile von usleep(x) ?



  • bzw.:
    #include <qapplication.h>
    qApp->processEvents(10);



  • Scheint auch zu funktionieren, ist aber glaube ich nicht ganz sauber.
    In der QT Hilfe steht irgendwas mit sendEvents usw. Kennt ihr euch damit aus?
    - welches Event brauch ich für die Tabelle damit alles gezeichnet wird?



  • #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.



  • Hallo,

    kA ob es direkt damit zusammenhaengt, kenne QT nicht. Aber deine run-Funktion
    erzeugt ein Speicherleck. Du gibst den Speicher von 'event' nicht mehr frei.

    mfg
    v R



  • Ich weiß, aber daran liegt es nicht (ich denke das weißt du sicher auch selber).



  • Mit sendEvent() scheint es zu funktionieren. Doch wenn ich das Fenster andauernd verkleicher/vergößere kommt folgendes:

    Xlib: unexpected async reply (sequence 0x6292)!



  • Schon mal in die QApplication::postEvent Dokumentation geschaut ? Oder den Teil Thread support in Qt ?

    Bei postEvent mußt du den Event mit new erzeugen, darfst ihn aber NICHT löschen.
    Bei sendEvent solltest du das Event-Objekt nachher löschen oder (empfohlen) die Form _app->postEvent(_tabelle, QEvent::Paint); verwenden

    Der XLib-Fehler kommt daher, daß sendEvent im Gegensatz zu postEvent nicht Thread-save ist.

    Mit anderen Worten:

    • Dein Beispiel erzeugt kein Speicherleck durch das event-Objekt
    • postEvent gegen sendEvent zu tauschen ist falsch

    (Da es immer genau ein QApplication Objekt gibt, das via qapplication.h als qApp bekannt ist, brauchst du es nicht als Argument übergeben. Erzeugt nur mehr Tipparbeit und mehr Daten auf dem Stack)

    Gegen Speicherschutzverletzungen gibt es Debugger ...


Anmelden zum Antworten