[C/C++] Abbruch durch Tastendruck (Button)

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von BuffaloBill, 19. September 2012 .

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. 19. September 2012
    Abbruch durch Tastendruck (Button)

    Hallo zusammen,
    ich bin grade dabei ein kleines Programm mit Qt und C++ zu schreiben.

    Das ganze soll Strings von einem Port lesen und diese in einem QTextedit ausgeben und später in einer Textdatei mitloggen.

    Jetzt stehe ich vor folgenden Problemen:

    Momentan lese ich die Daten per QTcpSocket::readAll() ein, das führt dazu, das er immer erst "sammelt" und dann wenn ich den nächsten durchlauf starte alles was in der Zwischenzeit aufgelaufen ist in ein QTextEdit ausgibt.
    Beim ersten mal gibt es also keine Ausgabe und danach immer erst nachdem das Programm abgelaufen ist.

    Nun meine Fragen:
    1. Gibt es eine Funktion die besser geeignet wäre jede gelesene Zeile einzeln einzulesen?
    2. Wie kann ich zur Laufzeit das QTextEdit Fenster füllen und aktualisieren?
    3. Wie könnte ich per Tasten- (oder QPushButton-) druck das einlesen stoppen? (Denn während der while-Schleife des einlesens, ist das Programm nicht bedienbar)
    Für jede Hilfe gibt es natürlich eine BW.


    Danke schonmal

    BuffaloBill
     
    1 Person gefällt das.
  2. 19. September 2012
    AW: Abbruch durch Tastendruck (Button)

    1. Verwende die Memberfunktionen canReadLine und readLine der QTcpSocket Klasse.

    2. Du kannst mit setPlainText oder setHtml (wenn du noch HTML Tags verwendens wills um irgend etwas hervorzuheben) den Text setzen. Des Weiteren gibt es noch die Funktion append, um Text anzuhängen, mit der hab ich aber eher schlechte Erfahrungen gemacht, könnte jedoch auch funktionieren.

    3. Wenn du das schon fragst dann solltest du dein Konzept noch mal überarbeiten. Qt ist Signal und Slot basierend, dh. du musst deine Daten nicht in Blockierenden-Schleifen sammeln sondern du kriegst eine Mittelung wenn Daten reinkommen auf die du dann erst regieren solltest. Bei dir wäre es dann bei der QTcpSocket das Signal readyRead.

    Mfg Rushh0ur
     
    1 Person gefällt das.
  3. 19. September 2012
    Zuletzt bearbeitet: 19. September 2012
    AW: Abbruch durch Tastendruck (Button)

    Danke schon mal, habe jetzt noch ein bisschen was verändert.

    Das ist der Teil bei dem es um die Abbruchbedingung und die Ausgabe zur Laufzeit geht.

    Mein Konzept sieht ja schon vor, dass ein Tasten druck auf den QPushButton "Stop" die Verbindung schließt und das funktioniert auch.
    Allerdings kann ich den Button während die while-Schleife zum einlesen läuft nicht bedienen.
     
  4. 19. September 2012
    AW: Abbruch durch Tastendruck (Button)

    Wie gesagt, du solltest versuchen die Schleife komplett weg zubekommen.
    Es gäbe noch die die extrem unsaubere Lösung in der Schleife QCoreApplication: rocessEvents zu verwenden, sodass alle Signale (zb ds clicken auf einen PushButton) bearbeitet werden, aber ist dass wie gesagt nicht zu empfehlen.

    Beachte das durch den simplen Aufruf von connectToHost nicht garantiert ist, dass direkt eine Verbindungen besteht, dann musst du schon waitForConnected noch verwenden.

    Wie gesagt am besten ist es mit Singalen und Slots zu arbeiten, wegen dieses Systems wird der Effekt von insertPlainText auch erst nach der Schleife sichtbar. Ich erstell mal ein minimal Beispiel...

    Mfg Rushh0ur
     
  5. 19. September 2012
    AW: Abbruch durch Tastendruck (Button)

    Ich habe irgndwie nen kleinen Knoten im Kopf.

    Also bisher sieht es wie folgt aus:
    • Eingabefelder für IP & Port
    • Start, Stop, Save Button
    • Start verbindet mit dem Port und macht die Ausgabe
    • Stop schließt die Verbindung zum Port
    • Save öffnet im Moment noch einen Dialog zum speichern des Inhalts des Textfeldes
    Wie ich das ganze jetzt über Signals & Slots ändern könnte wird mir nicht klar.
     
  6. 19. September 2012
    AW: Abbruch durch Tastendruck (Button)

    Ok der Aufbau sieht auf jeden Fall sehr gut aus.
    Das Signal & Slot System ist eventuell am Anfang nicht so einfach,
    man sollte sich aber dran schnell gewöhnen können.

    Hier ein Beispiel:

    Header:
    PHP:
    #ifndef QTCPTEST_H
    #define QTCPTEST_H

    #include <QtGui/QWidget>
    #include <QTcpSocket>
    #include <QAbstractSocket>
    #include "ui_qtcptest.h"

    class  QTcpTest  : public  QWidget
    {
        
    Q_OBJECT

    public:
        
    QTcpTest ( QWidget  * parent  0 Qt :: WFlags flags  0 );
        ~
    QTcpTest ();

    private:
        
    Ui :: QTcpTestClass ui ;
        
    QTcpSocket client ;   // die TcpSockent Instanz

    public  slots :
        
    void on_pushButtonConnect_clicked ();     // wird beim clicken auf den Connect Button ausgeführt
        
    void on_pushButtonDisconnect_clicked ();  // wird beim clicken auf den Disonnect Button ausgeführt
        
        
        
    void on_client_readyRead ();  // wird ausgeführt wenn neue Daten am TcpSocket ankommen
        
    void on_client_connected ();  // wird ausgeführt wenn eine Verbindung hergestellt worden ist
        
    void on_client_disconnected ();  // wird ausgeführt wenn die Verbindung vom Clienten oder vom Host getrennt wird
        
    void on_client_error ( QAbstractSocket :: SocketError socketError );  // wird ausgeführt wenn ein Verbindungsfehler auftritt
    };

    #endif // QTCPTEST_H
    CPP-Source:
    PHP:
    #include "qtcptest.h"

    QTcpTest :: QTcpTest ( QWidget  * parent Qt :: WFlags flags )
        : 
    QWidget ( parent flags )
    {
        
    ui . setupUi ( this );

        
    // WICHTIG!!!! 
        // SIGNALE vom Sender (TcpSocket Instanz) mit den SLOTS vom Empfänger (hier das Hauptfesnter) verbinden
        // Sobald die TcpSocket Instanz eine der Unteren SIGNALE sendet werden diese ans Hauptfenster weitergeleitet
        // und die Entsprechende funktion aufgerufen.
        // WICHTIG!!!!
        
    QObject :: connect (& client SIGNAL ( readyRead ()),  this SLOT ( on_client_readyRead ()));
        
    QObject :: connect (& client SIGNAL ( connected ()),  this SLOT ( on_client_connected ()));
        
    QObject :: connect (& client SIGNAL ( disconnected ()),  this SLOT ( on_client_disconnected ()));
        
    QObject :: connect (& client SIGNAL ( error ( QAbstractSocket :: SocketError socketError )),  this SLOT ( on_client_error ( QAbstractSocket :: SocketError socketError )));
    }

    QTcpTest ::~ QTcpTest (){
    }

    void QTcpTest :: on_pushButtonConnect_clicked (){
        
    client . connectToHost ( "www.google.de" 80 );
        
    // sende etwas
    }

    void QTcpTest :: on_pushButtonDisconnect_clicked (){
        
    client . disconnectFromHost ();
    }

    void QTcpTest :: on_client_readyRead (){
        if (
    client . canReadLine ())
            
    ui . textEdit -> insertPlainText ( client . readLine ());
    }

    void QTcpTest :: on_client_connected (){
        
    ui . textEdit -> insertPlainText ( "Connected to Host\n" );
    }

    void QTcpTest :: on_client_disconnected (){
        
    ui . textEdit -> insertPlainText ( "Disconnected from Host\n" );
    }

    void QTcpTest :: on_client_error ( QAbstractSocket :: SocketError socketError ){
        
    ui . textEdit -> insertPlainText ( "Cann't connect to host\n" );
    }
    Sollte mehr oder weniger selbsterklärend sein.

    Mfg Rushh0ur
     
  7. 19. September 2012
    AW: Abbruch durch Tastendruck (Button)

    Ah ok, man kann also auch "Programm interne" Events als Signals nehmen, das hebt das ganze auf ein ganz anderes Level. ^^

    Vielen Dank, ich würde dich ja noch öfter bewerten, aber das geht leider nicht.
     
  8. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.