Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Comunicazione fra threads
Forum Updated to NodeBB v4.3 + New Features

Comunicazione fra threads

Scheduled Pinned Locked Moved Italian
8 Posts 2 Posters 3.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bruschetta
    wrote on last edited by
    #1

    Salve ragazzi.
    Provo a descrivere la situazione che mi si presenta e il problema ad esso connesso.

    Nella mia applicaizone ho due Threads:

    1. Un TCPThread (un thread di ascolto su di un Socket) che viene creato nella main page (figlio quindi del thread GUI)
    2. Il main Thread (GUI) che fa funzionare tutta l'applicazione...

    L'utente quindi utilizza l'applicazione gestita dal main thread e può interagire con una serie di dialog. Diaciamo che l'utente a questo punto crea il Dialog1 che crea il Dialog2 etc... In questa situazione ho necessità che il Dialog3 riceva dei dati che il thread TCP sta registrando.

    Nella mia infinita ignoranza avrei ustato una CONNECT se il thread TCP e il Dialog3 fossero stati tutti figli del solito dialog, ma così non è... Uno infatti è figlio di Dialog2 e uno di Mainpage(o GUIthread che dir si voglia).

    Avete qualche consiglio da darmi? Ve ne sarei infinitamente grato.

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      Probabilmente devi semplicemente creare una catena di signals o passare un puntatore all'oggetto che emette i segnali dal TCP. Io preferisco la prima soluzione quindi:

      • creerei un signal in Dialog1 che e' identico a quello emesso dal TCP object, da Mainpage connetti il signal nell'oggetto TCP con quello in Dialog1.
      • creerei un signal in Dialog2 che e' identico a quello in Dialog1 e in Dialog1 connetti i due segnali
      • In Dialog2 connetti il segnale in Dialog2 con lo slot in Dialog3

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      B 1 Reply Last reply
      1
      • VRoninV VRonin

        Probabilmente devi semplicemente creare una catena di signals o passare un puntatore all'oggetto che emette i segnali dal TCP. Io preferisco la prima soluzione quindi:

        • creerei un signal in Dialog1 che e' identico a quello emesso dal TCP object, da Mainpage connetti il signal nell'oggetto TCP con quello in Dialog1.
        • creerei un signal in Dialog2 che e' identico a quello in Dialog1 e in Dialog1 connetti i due segnali
        • In Dialog2 connetti il segnale in Dialog2 con lo slot in Dialog3
        B Offline
        B Offline
        Bruschetta
        wrote on last edited by
        #3

        @VRonin
        Capito Ronin. Grazie per la risposta ;)

        1 Reply Last reply
        0
        • B Offline
          B Offline
          Bruschetta
          wrote on last edited by Bruschetta
          #4

          Allora dopo un po' di tempo sono tornato ad occuparmi del problema dei thread...
          L'ultima volta avevo capito che il tuo consiglio consisteva in questo:

          Lancio il mio thread in mainwindow

          TCPThread *thread = new TCPThread;
                thread->start();
          

          faccio le mie cose e poi collego mainwindow con dialog1

          Dialog1 *dia1=new Dialog1();
              dia1->setModal(true);
              connect(this, SIGNAL(sendIdThread(const TCPThread &) ), dia1, SLOT( getIdThread(const TCPThread & )));
              emit sendIdThread(*thread);
              dia1->exec();
          

          stessa cosa farò in Dialog2 e Dialog3

          Dialog2 *dia2=new Dialog2();
              dia2->setModal(true);
              connect(this, SIGNAL(sendIdThread(const TCPThread &) ), dia2, SLOT( getIdThread(const TCPThread & )));
          	emit sendIdThread(*thread);
              dia2->exec();
          

          etc..
          Così finalmente odvrei avere il riferimento al thread nel mio dialog 3. Ho capito bene?
          Il problema che incontro è che già durante il primo passaggio di riferimento nello slot getIdThread(const TCPThread & ) prendo questo errore:
          `

          error: use of deleted function 'TCPThread::TCPThread(const TCPThread&)'
                   case 7: _t->getIdThread((*reinterpret_cast< const TCPThread(*)>(_a[1]))); break;
          

          Sapresti indicarmi cosa sbaglio? Grazie mille per la disponibilità

          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            TCPThread e' un QObject e i QObject non possono essere copiati. usa i puntatori invece delle referenze: const TCPThread& deve diventare TCPThread* (probabilmente il const e' un po' troppo restrittivo, io l'ho tolto ma lo puoi tenere se pensi sia accettabile)

            P.S.
            Di solito QThread non va reimplementato, protesti postare il codice di TCPThread?

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            B 1 Reply Last reply
            1
            • VRoninV VRonin

              TCPThread e' un QObject e i QObject non possono essere copiati. usa i puntatori invece delle referenze: const TCPThread& deve diventare TCPThread* (probabilmente il const e' un po' troppo restrittivo, io l'ho tolto ma lo puoi tenere se pensi sia accettabile)

              P.S.
              Di solito QThread non va reimplementato, protesti postare il codice di TCPThread?

              B Offline
              B Offline
              Bruschetta
              wrote on last edited by Bruschetta
              #6

              @VRonin
              intanto grazie per la risposta. Il codice del thread è :

              .H
              #ifndef TCPTHREAD_H
              #define TCPTHREAD_H
              
              #include "utility/speaktts.h"
              
              #include <QDialog>
              #include <QMainWindow>
              #include <QTcpSocket>
              #include <QThread>
              
              namespace Ui {
              class TCPThread;
              }
              
              class TCPThread : public QThread
              {
                  Q_OBJECT
              
              public slots:
                  void connectToHost();
                  void connected();
                  void readServer();
                  void sendMessage();
                  void delay( int millisecondsToWait );
              
              private slots:
                  void on_sendMessage_clicked();
                  void on_control_clicked();
              
              
              private:
                  Ui::TCPThread *ui;
                  void run();
                  QTcpSocket *socket;
                  SpeakTTS *tts;
              };
              
              #endif // TCPTHREAD_H
              
              .C
              #include "tcpthread.h"
              #include "utility/speaktts.h"
              
              #include <QtGui>
              #include <QtNetwork>
              #include <QFormLayout>
              #include <QLineEdit>
              #include <QSpinBox>
              #include <QPushButton>
              #include <QTextEdit>
              #include <QString>
              #include <QTime>
              #include <QThread>
              #include <QtMath>
              #include <QVector>
              
              typedef struct
              {
                  long quotaX; //coord x
                  long quotaY; //coord y
                  long flags;  //touch
                  long progressivo;
              }DATI;
              
              void TCPThread::run()
              {
                  //Creo il socket TCP
                  socket=new QTcpSocket();
              
                  connect(socket, SIGNAL(connected()), this, SLOT(connected()));
                  connect(socket, SIGNAL(readyRead()), this, SLOT(readServer()));
              
                  this->connectToHost();
                  bool connected=false;
                  //Cicolo infinito di ascolto
                  while(1){
                      //Se la connessione esiste invio il messaggio
                      connected = (socket->state() == QTcpSocket::ConnectedState);
                      if(connected){
                          //Invio un messaggio di "polling" per ricevere le coordinate dal server
                          sendMessage();
                          delay(250);
                          //La connessione non esiste/è caduta, la ripristino
                      }else{
                          // qDebug() << "Stauts: abort ";
                          socket->abort();
                          socket->connectToHost(QHostAddress("192.168.2.115"), 5000);
                          delay(2000);
                          // qDebug() << "Stauts: connect ";
                      }
                  }
              }
              
              //Stabilisce la connessione con il server
              void TCPThread::connectToHost(){
                  socket->connectToHost(QHostAddress("192.168.2.115"), 5000);
              }
              
              void TCPThread::connected(){
                  socket->write(QString("Hello Server").toLatin1());
                  socket->waitForBytesWritten();
              }
              
              void TCPThread::sendMessage(){
                  //Invio un qualsiasi messaggio per avere la risposta coi dati
                  socket->write(QString("a").toLatin1());
                  //ui->trace->append("Ho inviato il messaggio");
                  socket->waitForBytesWritten();
              }
              
              void TCPThread::readServer(){
              
                  if(socket->bytesAvailable() < sizeof(DATI)) return;
                  const QByteArray raw = socket->read(sizeof(DATI));
                  const DATI* const rawData = reinterpret_cast<const DATI*>(raw.constData());
                     qDebug() << "Coord X: " +  QString::number(rawData->quotaX) << "Coord Y: " +  QString::number(rawData->quotaY) << "Touch: " +  QString::number(rawData->flags);
                  if(rawData->flags==0){
                     qDebug() << "Coord X: " +  QString::number(rawData->quotaX) << "Coord Y: " +  QString::number(rawData->quotaY) << "Touch: " +  QString::number(rawData->flags);
                  }
                  readServer();
              }
              
              //Evento click pulsante messaggio
              void TCPThread::on_sendMessage_clicked()
              {
                  this->sendMessage();
              }
              
              //Evento click pulsante connetti
              void TCPThread::on_control_clicked()
              {
                  this->connectToHost();
              }
              
              //Funzione per impostare il delay in millisecondi
              void TCPThread::delay( int millisecondsToWait )
              {
                  QTime dieTime = QTime::currentTime().addMSecs( millisecondsToWait );
                  while( QTime::currentTime() < dieTime )
                  {
                      QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
                  }
              }
              

              Che fondamentalmente manda un messaggio di un carattere ad un server che gli risponde sempre con 3 valori.

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #7

                Come temevo... la documentazione di QThread e' sbagliata dai tempi di Qt4, tutti si lamentano ma nessuno mai la cambia, ti consiglia di fare cose sbagliate. La spiegazione di come usarli correttamente la trovi qui: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ ma, in pratica, nel 99.9% dei casi QThread non va subclassato. Crea una classe che eredita da QObject che faccia il lavoro e usa moveToThread

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                B 1 Reply Last reply
                1
                • VRoninV VRonin

                  Come temevo... la documentazione di QThread e' sbagliata dai tempi di Qt4, tutti si lamentano ma nessuno mai la cambia, ti consiglia di fare cose sbagliate. La spiegazione di come usarli correttamente la trovi qui: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ ma, in pratica, nel 99.9% dei casi QThread non va subclassato. Crea una classe che eredita da QObject che faccia il lavoro e usa moveToThread

                  B Offline
                  B Offline
                  Bruschetta
                  wrote on last edited by Bruschetta
                  #8

                  @VRonin
                  ok grazie mille per le dritte. Ora mi studio meglio i threads ;)

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved