Anzeige:
Ergebnis 1 bis 5 von 5

Thema: Qt/kde zweite Funktion abwarten

  1. #1
    Registrierter Benutzer
    Registriert seit
    14.11.2002
    Ort
    Obertshausen
    Beiträge
    87

    Qt/kde zweite Funktion abwarten

    Hallo zusammen,

    ich hoffe, ich bekomme das aus meinem wirren Hirn jetzt so raus, dass Ihr es auch verstehen könnt

    Ich habe folgendes Problem:


    Code:
    pb_jpg2mpg_start_clicked()
    {
    
    pb_jpg2mpg_start->setEnabled(false);
    zahl=0;
    converted_zahl=0;
    dummy=lb_jpg_img->text(zahl);
    if  ( !dummy.isEmpty())
    {
    convert_progress = new QProgressDialog( "Conversion in progress.\nPlease wait...", 0, 0 );
    convert_progress->show();
    
      while ( !dummy.isEmpty())
      {
        stillencode(dummy); //hier wird die andere Funktion aufgerufen
        lb_seg_items->insertItem( lb_jpg_img->text(zahl)+".mpg");
        zahl++;
        dummy = lb_jpg_img->text (zahl);
        
      }
    convert_progress->cancel();
    }
    else KMessageBox::error(this, i18n("Ooops ! No JPEGs in List to convert!"));
    
    
    }
    Ich habe oboige Funktion, die in der while-schleife n-mal eine andere Funktion aufruft.
    So wie das im Moment ist wird die Schleife komplett durchlaufen und die Funktion stillencode(dummy) wird fast "zeitgleich" n-mal aufgerufen.

    Ich möchte aber, dass die Schleife nach dem ersten Aufruf wartet, bis die Funktion Stillencode fertig ist (dauert nämlich was länger) und erst dann mit dem Rest der Schleife
    Code:
        lb_seg_items->insertItem( lb_jpg_img->text(zahl)+".mpg");
        zahl++;
        dummy = lb_jpg_img->text (zahl);
    weitermacht.

    Wie stelle ich das am besten an?
    Gibt es so etwas wie wait()?
    oder könnte man eine bool aktive = true benutzen, die von der zweiten Funktion wieder auf false gesetzt wird und die erste wartet so lange, bis aktive==true?

    Wer hat eine Idee? Am besten mit Code-beispiel!
    Alle meine Ansätze führten dazu, dass das Programm für die Dauer eingefroren ist

    Vielen Dank fürs Kopfzerbrechen
    Celindir
    May the source be with you...

    www.celindir.de

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477

    Re: Qt/kde zweite Funktion abwarten

    Original geschrieben von celindir

    Ich möchte aber, dass die Schleife nach dem ersten Aufruf wartet, bis die Funktion Stillencode fertig ist (dauert nämlich was länger)
    Hmm, wenn die Funktion returned, ist sie dohc fertig oder?

    Poste mal den Code von stillencode


    Alle meine Ansätze führten dazu, dass das Programm für die Dauer eingefroren ist
    Wahrscheinlich ist die Funktion ein Slot und wird durch des Signal ein GUI Elements aufgerufen, richtig?

    Da du dann den GUI Thread (eventloop) in die Schleife schickst, kann er nix anderes machen, bis er wieder raus ist.

    Ohne Code von stillencode kann man da aber wenig Hilfe geben.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    14.11.2002
    Ort
    Obertshausen
    Beiträge
    87
    OK jetzt wirds aber etwas länger

    Code:
    stillencode(QString dummy)
    {
     
    QString encodestill;
    if ( rb_vcd2->isChecked () )
    encodestill = "#!/bin/bash \n jpegtopnm "+dummy+" | 
    pnmscale  -xysize 768 576 | pnmpad -black -width=768 -height=576 | 
    pnmscale -xscale 0.916667 | ppmntsc --pal | ppmtoy4m | 
    mpeg2enc  -f 6 -F 3 -a 2 -n p -T 120 -o /tmp/STILL.m1v && 
    mplex  -f 6 -o "+dummy+".mpg /tmp/STILL.m1v ";
    if ( rb_svcd->isChecked () )
    encodestill = "#!/bin/bash \n jpegtopnm "+dummy+" | 
    pnmscale  -xysize 768 576 | pnmpad -black -width=768 -height=576 | 
    pnmscale -xscale 0.916667 | ppmntsc --pal | ppmtoy4m | 
    mpeg2enc  -f 7 -F 3 -a 2 -n p -T 120 -o /tmp/STILL.m2v && 
    mplex -f 7 -o "+dummy+".mpg /tmp/STILL.m2v ";
    bash_active=true;
    execute_script (encodestill);
    
    }

    Code:
    execute_script (QString bash)
    {
    //save bash-file
    QString scriptFileName;
    scriptFileName = "/tmp/tmpscript";
    QFile file( scriptFileName ); // Write the text to a file
     if ( file.open( IO_WriteOnly ) )
       {
            QTextStream stream( &file );
            stream << bash;
        }
    file.close();
    
     //make file executable
    QStringList setexec ;
    setexec.append("chmod") ;
    setexec.append("4711") ;
    setexec.append("/tmp/tmpscript") ;
    
    my_process->clearArguments();
    my_process->setArguments(setexec);
    my_process->start();
    
    QStringList scriptargs ;
    scriptargs.append("/tmp/tmpscript") ;
    
    //initializing Process
    my_bash_process->clearArguments();
    my_bash_process->setArguments(scriptargs);
    connect( my_bash_process , SIGNAL( processExited() ), this, SLOT( bash_end()) );
     if ( !my_bash_process->start() ) 
    {
      KMessageBox::error(this,i18n("Ooops...\n\n...could not start process"));
    }
    
    }
    Code:
    bash_end() //damit hatte ich ein wenig rumprobiert, aber ohne Erfolg
    {
    bash_active=false;
    converted_zahl++;
    if (converted_zahl == lb_jpg_img->numRows())
    {
    convert_progress->cancel();
    pb_jpg2mpg_start->setEnabled(true);
    }
    }
    Hier ist der Code, in der Hoffnung, dass er verständlich ist. Ich habe gestern so viel rumprobiert, dass manche Sachen vielleicht noch aus fehlgeschlagenen Versuchen stammen.

    Der Weg, den ich mit dem Bash-Script gegangen bin ist sicherlich nicht der sauberste, aber er funktioniert.

    Es soll also folgendes passieren:
    Eine Liste von Dateien aus der ListBox lb_jpg_img soll Datei für Datei abgearbeitet werden und mit Stillencode zu einem MPEG-Still konvertiert werden.
    Im Moment werden alle Dateien nahezu parallel konvertiert.
    Es müsste aber doch auch möglich sein, dass erst das erste Bild konvertiert wird und erst wenn bash-end() für die erste Datei ausgeführt wurde die nächste Datei in der Liste abgearbeitet wurde.
    Celindir
    May the source be with you...

    www.celindir.de

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Original geschrieben von celindir

    Hier ist der Code, in der Hoffnung, dass er verständlich ist. Ich habe gestern so viel rumprobiert, dass manche Sachen vielleicht noch aus fehlgeschlagenen Versuchen stammen.
    Ich brauch eh nur ungefähr einen Anhaltspunkt, was so gemacht wird.
    zB das QProcess benutzt wird


    Der Weg, den ich mit dem Bash-Script gegangen bin ist sicherlich nicht der sauberste, aber er funktioniert.
    Wäre es nicht einfacher, ein Bashscript zu haben und den Inhalt von Dummy als Parameter zu übergeben?

    Zum eigentlichen Problem:
    Die Benutzung von QProcess setzt eine laufende Eventloop vorraus, wie etwa bei QSocket.
    Du darfst also den Thread der Eventloop nicht blockieren, denn dass führt zu dem von dir schon bemerkten blockieren der gesamten Applikation.

    Es gibt da zwei Ansätze:
    1) asynchrones abarbeiten der Jobs. Da füllt du zB beim Klick eine Liste mit den Dateinamen (oder anderen relevanten Daten) und setzt ein Flag, dass die Bearbeitung läuft.
    Dann startest du einen Slot, der sich aus der Liste das erste Element holt und damit den QProcess startet. Dieser Slot ist auch mit processExited verbunden, holt sich also nach Beendingung den nächtsen Eintrag.
    Wenn der Slot keinen weiteren Eintrag mehr findet, setzt er das Flag zurück und ruft eventuell eine andere Methide auf, die das Ende der bearbeitung signalisiert.

    2) In der Startmethode in einer Schleife warten und mit qApp->processEvents() die Eventloop am Laufen halten.
    Man sollte sich dabei aber bewußt sein, dass damit auch User Input Events bearbeitet werden, man sollte dann zB einen modalen Dialog im Vordergrund haben, damit der User nichts klicken kann, was dazwischen funkt.
    Siehe dazu Doku von QProgressDialog

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer
    Registriert seit
    14.11.2002
    Ort
    Obertshausen
    Beiträge
    87
    Vielen Dank

    ich habe mich für die Variante 2 entschieden. Durch den ProgressDialog, den ich sowieso einsetzen wollte war das für mich der einfachere Weg.

    Gruß
    Celindir
    May the source be with you...

    www.celindir.de

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •