Seite 1 von 1

viele Bilder schnell hintereinander zeigen. (wie Diashow)

Verfasst: 11. Mai 2005 15:27
von december_soul
Ich habe folgendes Problem.
Ich übergebe von einem anderen Programm einzelne Frames an meine GUI.
Die GUI soll dann die Frames (und vieles mehr) anzeigen.

Nur leider ist mir noch keine Element bekannt das sich wirklich dazu eignet Bild in schneller folge dazustellen.

Ich habe nun ein QLabel auf dem ich PixMaps dastelle.

Nur leider flimmer das sehr stark.
Das eigentliche Problem dabei ist jedoch das ich nach einer gewissen Zeit folgende Fehlermeldung bekomme.

Code: Alles auswählen

...........
X Error: BadRequest (invalid request code or no such operation) 1
  Major opcode:  136
  Minor opcode:  136
  Resource id:  0xff595959
X Error: BadRequest (invalid request code or no such operation) 1
  Major opcode:  134
  Minor opcode:  134
  Resource id:  0xff595959
X Error: BadLength (poly request too large or internal Xlib length error) 16
  Major opcode:  57
  Minor opcode:  0
  Resource id:  0xff595959
X Error: BadLength (poly request too large or internal Xlib length error) 16
  Major opcode:  104
  Minor opcode:  0
  Resource id:  0xff595959
Warte ...
... fertig.
X Error: BadRequest (invalid request code or no such operation) 1
  Major opcode:  173
  Minor opcode:  0
  Resource id:  0xff595959
...........
Ab dem Moment zeigt mir mein QLabel nicht mehr an.
Ich kann zwar mit usleep das ganze etwas ausbremsen aber das kann es ja nicht sein oder?

Vielleicht habe ich auch nur einfach das falsche Element.

//EDIT

Code: Alles auswählen

./gui5
Der Server laeuft nun als eingener Thread....GUI läuft mit Shared Memory ID 24674304
Warte ...
... fertig.
Warte ...
... fertig.
Warte ...
... fertig.
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff94 > 0x6b5) in reply type 0x94!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff96 > 0x6b5) in reply type 0x96!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9c > 0x6b5) in reply type 0x9c!
Xlib: sequence lost (0x1ff9c > 0x6b5) in reply type 0x9c!
Xlib: sequence lost (0x1ffa0 > 0x6b5) in reply type 0xa0!
Xlib: sequence lost (0x1ff00 > 0x6b5) in reply type 0x0!
X Error: 0 0
  Major opcode:  3
  Minor opcode:  3
  Resource id:  0xff020202
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff97 > 0x6b5) in reply type 0x97!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9c > 0x6b5) in reply type 0x9c!
Xlib: sequence lost (0x1ff98 > 0x6b5) in reply type 0x98!
Xlib: sequence lost (0x1ff96 > 0x6b5) in reply type 0x96!
Xlib: sequence lost (0x1ff9f > 0x6b5) in reply type 0x9f!
Xlib: sequence lost (0x1ff04 > 0x6b5) in reply type 0x4!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff96 > 0x6b5) in reply type 0x96!
Xlib: sequence lost (0x1ff9c > 0x6b5) in reply type 0x9c!
Xlib: sequence lost (0x1ff9d > 0x6b5) in reply type 0x9d!
Xlib: sequence lost (0x1ff00 > 0x6b5) in reply type 0x0!
X Error: 0 0
  Major opcode:  0
  Minor opcode:  0
  Resource id:  0xff010101
Xlib: sequence lost (0x1ff9b > 0x6b5) in reply type 0x9b!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff9b > 0x6b5) in reply type 0x9b!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff97 > 0x6b5) in reply type 0x97!
Xlib: sequence lost (0x1ff9a > 0x6b5) in reply type 0x9a!
Xlib: sequence lost (0x1ff94 > 0x6b5) in reply type 0x94!
Xlib: sequence lost (0x1ff9c > 0x6b5) in reply type 0x9c!
Xlib: sequence lost (0x1ff9d > 0x6b5) in reply type 0x9d!
Xlib: sequence lost (0x1ff00 > 0x6b5) in reply type 0x0!
X Error: 0 0
  Major opcode:  0
  Minor opcode:  0
  Resource id:  0xff000000
Xlib: sequence lost (0x1ff96 > 0x6b5) in reply type 0x96!
Xlib: sequence lost (0x1ff98 > 0x6b5) in reply type 0x98!
Xlib: sequence lost (0x1ff97 > 0x6b5) in reply type 0x97!
Xlib: sequence lost (0x1ff96 > 0x6b5) in reply type 0x96!
Xlib: sequence lost (0x1ff9c > 0x6b5) in reply type 0x9c!
Xlib: sequence lost (0x1ff9f > 0x6b5) in reply type 0x9f!
Xlib: sequence lost (0x1ff01 > 0x6b5) in reply type 0x1!
gui5: Fatal IO error: client killed

Server wird beendet - Lösche Semaphor 2752547.

Verfasst: 17. Mai 2005 08:54
von FlorianBecker
Ich hatte auch schon viele xlib Fehler allerdings immer im Zusammenhang mit Datenbanken und irgendeinem Speicherüberlauf von wegen in eine Tabelle schreiben. Hast du mal geschaut, was diese ganzen Fehler bedeuten? Es gibt dafür Liste, die die vielleicht helfen können das zu lösen, weiter würde ich empfehlen soviel DEBUG wie nur irgendwie möglich zu machen. Also jede 2. Zeile mit qDebug raus, alle Logs simultan abgreifen und und und.

Von diesem Standpunkt allerdings aus ist es relativ schwer zu sagen, womit man dir helfen könnte.

Verfasst: 17. Mai 2005 09:08
von december_soul
soweit ich es bis jetzt gelesen habe, ist mein Problem das ich mit qt und Threads arbeite.
Das führt zu sync Problemen bei der Oberfläche.

Ich habe bis jetzt nur etwas mehr in der Richtung gelesen.
Eine Lösung habe ich jedoch noch nicht.

Allerdings nervt es echt wenn meine gui alle paar min einfach abstürzt......
Ich werde morgen mal etwas mehr debug erzeugen.

Verfasst: 17. Mai 2005 09:26
von FlorianBecker
Das kenne ich, aber ich bin zuversichtlich, dass wir da schon noch eine Lösung finden werden. Könntest uns ja auch ein wenig Code Schnipsel schicken, vielleicht sieht man ja Fehler direkt.

Verfasst: 30. Mai 2005 12:01
von december_soul
sorry das ich jetzt erst wieder antworte.
Hatte mich mit dem problem abgefunden.
Nun nervt es mich jedoch sehr stark.

Das ganze läuft so:
Aus main wird ein Thread gestartet.
Dieser Thread horcht auf eine Semaphor.
Wenn die Semaphor frei ist, dann ließt der Thread aus einem Shared Memory ein Image aus und stellt dieses da.

Ein anderes Programm füttert den SharedMemory und setzt die Semaphor.

Problem dabei ist, das der Thread sync Probleme mit der Oberfläche bekommt und dann die Oberfläche abstürzt.


Ich poste nun mal etwas Code.

Code: Alles auswählen

int main(int argc, char **argv)
{
    KAboutData about("gui5", I18N_NOOP("gui5"), version, description,
                     KAboutData::License_GPL, "(C) %{YEAR} patrick", 0, 0, "patrick@laptop");
    about.addAuthor( "patrick", 0, "patrick@laptop" );
    KCmdLineArgs::init(argc, argv, &about);
    KCmdLineArgs::addCmdLineOptions( options );
    KApplication app;
    gui5 *mainWin = 0;

    mainWin = new gui5();
    app.setMainWidget( mainWin );
    mainWin->show();

    pthread_t th[3];
    int i;
    char buf[255];
    sprintf (buf, "Thread %d", 1);
    
    if(pthread_create(&th[0], NULL, &server, (void*)mainWin) != 0) {
        fprintf (stderr, "Fehler bei Thread...\n");      
    }
      
    // mainWin has WDestructiveClose flag by default, so it will delete itself.
    return app.exec();
}
Nun der Thread:

Code: Alles auswählen

static void *server (void* window) {
    printf("Der Server laeuft nun als eingener Thread....");

    union semun sunion;
    int semid, shmid;
    int res;
    void *shmdata;
    tFrame *buffer;
    tFrame localbuffer;

    /* Ein Semaphor erstellen */
    semid = safesemget (IPC_PRIVATE, 2, SHM_R | SHM_W);
    DeleteSemid = semid;
    /* Semaphor beim Beenden entfernen */
    atexit (&mydelete);
    /* Signalhandler einrichten */
    my_signal (SIGINT, &sigdelete);

    /* Semaphor initialisieren */
    sunion.val = 1;
    safesemctl (semid, SN_EMPTY, SETVAL, sunion);
    sunion.val = 0;
    safesemctl (semid, SN_FULL, SETVAL, sunion);

    /* Ein Shared Memory Segment einrichten */
    shmid = shmget (100, SHMDATASIZE,
                    IPC_CREAT | SHM_R | SHM_W);
    if (shmid == -1)
        printf ("Fehler bei key %d, mit der Größe %d\n",
                IPC_PRIVATE, SHMDATASIZE);

    DeleteShmid = shmid;

    /* Shared Memory Segment anbinden */
    shmdata = shmat (shmid, NULL, 0);
    if (shmdata == (void *) -1)
        printf ("Fehler bei shmat(): shmid %d\n", shmid);

    /* Kennung am Anfang der Segments schreiben */
    *(int *) shmdata = semid;
    buffer = (tFrame*) ((int *) shmdata+1);    
    

    printf ("GUI läuft mit Shared Memory ID %d\n", shmid);

    while (1) {

        printf ("Warte ...");
        fflush (stdout);
        /* Sperren und Warten */
        locksem (semid, SN_FULL);
        printf ("\n... fertig.\n");
        /* Ein Client hat etwas geschrieben */

     
        
        localbuffer.number = buffer->number;
        localbuffer.width = buffer->width;
        localbuffer.height = buffer->height;
        int mem =  buffer->height*buffer->width*sizeof(buffer->data[0]);
        for (int i =0;i<mem;i++){
            localbuffer.data[i] = buffer->data[i];
        }
            
        //memcpy((void*)localbuffer.data,(void*)buffer->data[0],mem);
        localbuffer.type = buffer->type;
           
     
        ((gui5*)window)->showPic(&localbuffer,semid);
        
        //sleep(1);

        /* Sperre aufheben */
//        unlocksem (semid, SN_EMPTY); // habe ich iin die GUI Fkt verlegt.
    }

    return NULL;
}
Und zum Schluss noch die GUI Funktion:

Code: Alles auswählen

void gui5::showPic(tFrame* frame, int semid)
{
    
    

    QBuffer *pImageBuffer = new QBuffer();
    pImageBuffer->open(IO_WriteOnly);
    QDataStream *pDataStream = new QDataStream(pImageBuffer);
    QPixmap *pixmap = new QPixmap();

    
        char buffer[128];


        //header for png
        sprintf(buffer,"P5 %d %d 255\n",frame->width, frame->height);
        pDataStream->writeRawBytes(buffer,strlen(buffer));

        pDataStream->writeRawBytes((char*) frame->data,frame->width*frame->height*sizeof(frame->data[0]));

        pImageBuffer->close();
        pImageBuffer->open(IO_ReadOnly);


        if(pixmap->loadFromData(pImageBuffer->buffer()))
        {
            switch(frame->type){
                case 0:
                    pixMap->setPixmap(*pixmap);
                    pixMap->update();
                    break;
                case 1:
                    pixMap2->setPixmap(*pixmap);
                    pixMap2->update();
                    break;
                case 2:
                    pixMap3->setPixmap(*pixmap);
                    pixMap3->update();
                    break;
                case 3:
                    pixMap4->setPixmap(*pixmap);
                    pixMap4->update();
                    break;
            }


        }
        else
        {
            printf("failed to construct pixmap\n");
        }


    progressBar->setProgress(frame->number);


    pImageBuffer->close();
    delete pImageBuffer;
    delete pDataStream;

    
    /* Sperre aufheben */
    unlocksem (semid, SN_EMPTY);
}

Verfasst: 30. Mai 2005 22:11
von lepsai
Warum muss man alles so kompliziert machen! Was du brauchst, ist die Kommunikation zwischen zwei Processen. Um das zu realisieren, brauchste bei jedem Process jeweils ein Socket (QSocket). Dann schreibst du von deinem bildgebenden Process das Bild in das andere Socket rein und zeigst es auf der anderen Seite an. Um das Flimmern loszuwerden, must das Double Buffering umsetzten. Siehe dazu bitBlt().
Keine Threads, kein Shared Memory... keine Abstürze :)

Verfasst: 30. Mai 2005 22:25
von december_soul
läßt sich so leider nicht realisieren.
In dem Bildgebenden Programm kann ich nicht QT verwenden.

Ansonsten hast Du recht.
Habe zum anfang auch gedacht das ich es über sockets machen könnte.

Bin aber auch schon etwas weiter.
Man darf nicht von einem anderen Thread aus functionen der Oberfläche aufrufen.
Ich habe in einem anderen Forum ein paar Tips bekommen.
Leider verstehe ich die noch nicht.
Werde morgen mal den ganzen Tag dafür einplanen...

Verfasst: 30. Mai 2005 23:23
von lepsai
Aus einem anderen Thread läuft die Kommunikation mit dem GUI-Thread über QCustomEvent und QApplication::postEvent(). Mehr dazu findest und der Doku...

Zurück zu Sockets: Du könntest in deinem Nicht-Qt-Programm auf die Standard Socket API der C++ Bibliothek zurückgreifen. Die ist letztendlich sehr smart und leicht zu verstehen....

Verfasst: 31. Mai 2005 10:52
von FlorianBecker
Wo gibts die Standard Socket C++ API? Das hat mit STL nix zu tun, oder? Und damit ist es nicht Standard, oder doch?

Denn ich arbeite bisher mit socket.h unter Linux und winsock2.h unter Windows, evtl geht das ja auch besser. Danke für deine Antwort, lepsai.

Verfasst: 31. Mai 2005 11:08
von december_soul
Ich werde nun nicht mehr auf Sockets umsteigen.
Funzt super mit SharedMemory.
Nur das mit dem QT Thread habe ich noch nicht hin bekommen.
Bin aber gerade am lesen.

Im Grunde ist das Problem nun ja das ich einen Teil brauche der mir die Daten von einer Quelle (ob nun SM oder Datei ist ja egal) einließt und dann an die GUI schickt.

Das einlesen muß ich ja in einem Thread machen. Soll ja in einer Endlosschleife passieren.
Die GUI ist nun mal auch ein Thread.
Ich muß also zwischend diesen beiden Thread eine sichere Verbindung herstellen.
Ich lese mir das gerade mit QApplication::postEvent() durch.
Leider fehlen mir fast alle Grundlagen zu QT.
Stehe also etwas dumm davor.
Nun heißt es mal wieder lesen, lesen und noch mehr lesen.
Über ein paar Tips wo und was ich lesen sollte wäre ich dankbar.

Ein Beispiel wäre auch sehr gut! :-)

Verfasst: 31. Mai 2005 11:17
von lepsai
Denn ich arbeite bisher mit socket.h unter Linux und winsock2.h unter Windows
Na ja, gut, die Header unterscheiden sich, aber die Schnittstelle ist die Gleiche: bind(), accept(), listen() usw.

Das habe ich gemeint.

Verfasst: 31. Mai 2005 11:41
von FlorianBecker
Ok, verstehe. Danke.

Verfasst: 31. Mai 2005 13:26
von december_soul
Ich bin nun seit 4 Std am lesen und habe nicht mal die richtige stelle gefunden wo ich lesen muss. :-( *frust*

Es gibt schon die ersten Probleme beim linken.

Unter Kdevelop habe ich dann noch unter
Target-Einstellungen für xyz->
linken Bibiliotheken ausserhalb des Projektes(LDADD)
-lqt-mt
eingetragen.

Nun noch unter Projket-Optionen->Einstellung für Configure->
Schalter für den Linker(LDFLAGS)
das -thread zugefügt.

Und zum schluß noch unter
Nun noch unter Projket-Optionen->Einstellung für Configure->C++
Schalter für den Compiler(CXXFLAGS)
das -DQT_THREAD_SUPPORT zugefügt.

Ich hoffe das es soweit alles richtig ist.
Wenn nicht bitte was sagen!!

Nun habe ich gerade eine Seite mit einigen Beispielen gefunden.
Ich hoffe das da auch eins mit Threads bei ist........