Ошибка, связанная с использованием класса Qthread в сетевом программировании

#c #qt

#c #qt

Вопрос:

Я работаю над проектом, где у меня есть 3 кнопки. когда пользователь нажимает на них, некоторая информация (номер ввода, Ip, порт и pm) считывается из ini-файла, затем выдается сигнал InputDetected(), объявленный в моем классе, и после отправки этого сигнала я хочу установить соединение с сервером и отправить pms на сервер. С этой целью я создал кнопки в классе dialog . Внутри класса tcpclient у меня есть функция ConfigClass() для чтения ini-файла, и для того, чтобы установить соединение с сервером и отправить на него pms, я использовал сигнал InputDetected(), слотом которого является функция Callrun() . Внутри функции Callrun я запустил thread(), чтобы его функция запуска существовала внутри класса «Mythread». Когда я запускаю программу, я получаю сообщение об ошибке: ‘tcpclient’ не называет тип (эта ошибка связана с файлом mythread.h)

Я был бы признателен, если бы кто-нибудь помог мне исправить эту ошибку. Кроме того, я не знаю, правильно ли я использовал класс qthread для установления соединения с сервером. Я был бы признателен, если бы кто-нибудь сказал мне, если что-то не так с концепцией моего кода

мой код: dialog.h:

   #ifndef DIALOG_H
  #define DIALOG_H

  #include <QDialog>
  #include "tcpclient.h"

  namespace Ui {
  class Dialog;
  }

   class Dialog : public QDialog
 {
   Q_OBJECT

public:
   explicit Dialog(QWidget *parent = 0);
   ~Dialog();

   tcpclient myClients[3];

 private slots:
     void on_pushButton_clicked();

     void on_pushButton_2_clicked();

     void on_pushButton_3_clicked();

  private:
      Ui::Dialog *ui;
   };

  #endif // DIALOG_H
 

mythread.h:

 #ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QObject>
#include <QThread>
#include <QTcpSocket>
#include "tcpclient.h"

class MyThread : public QThread
 {
   Q_OBJECT
public:
   explicit MyThread(QObject *parent = nullptr);

   void run();

   QTcpSocket *socket;



   tcpclient *client;


signals:

 public slots:
 };

#endif // MYTHREAD_H
 

tcpclient.h:

  #ifndef TCPCLIENT_H
 #define TCPCLIENT_H

 #include <QObject>
 #include <QDebug>
 #include <QSettings>
 #include <QTcpSocket>
 #include "mythread.h"

 class tcpclient : public QObject
 {
     Q_OBJECT
 public:
    explicit tcpclient(QObject *parent = nullptr);

    void ConfigClass();
    void StartClass(int _input);

    QString ip;
    QString pm;
    int port;
    int input;
    QTcpSocket *socket;
    MyThread *mthread;

 signals:
   void InputDetected();

public slots:
    void Callrun();
};

#endif // TCPCLIENT_H
 

dialog.cpp:

   #include "dialog.h"
  #include "ui_dialog.h"

 Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    for(int i=0; i<3; i  ){
       myClients[i].StartClass(i 1);
    }
 }

Dialog::~Dialog()
 {
    delete ui;
  }

void Dialog::on_pushButton_clicked()
 {
     emit myClients[0].InputDetected();
  }

 void Dialog::on_pushButton_2_clicked()
  {
      emit myClients[1].InputDetected();
  }

  void Dialog::on_pushButton_3_clicked()
 {
     emit myClients[2].InputDetected();
  }
 

tcpclient.cpp:

  #include "tcpclient.h"
 #include "mythread.h"

tcpclient::tcpclient(QObject *parent) : QObject(parent)
 {

  }

void tcpclient::StartClass(int _input)
{
    input = _input;

    ConfigClass();

    connect(this,SIGNAL(InputDetected()), this, SLOT(Callrun()));


 }

void tcpclient::ConfigClass()
{
    QSettings setting(QString("config.ini"),QSettings::IniFormat);

    QString tmp = "ServerInfo"   QString::number(input);
    QString m1 = tmp   "/Ip";
    QString m2 = tmp   "/Port";
    QString m3 = tmp   "/in";
    QString m4 = tmp   "/pm";
    ip = setting.value(m1,"192.167.1.23").toString();
    port = setting.value(m2,0).toInt();
    input = setting.value(m3,0).toInt();
    pm = setting.value(m4,"hi").toString();

 }


  void tcpclient::Callrun()
 {
    mthread = new MyThread(this);
    mthread->start();
 }
 

mythread.cpp:

 #include "mythread.h"
#include "tcpclient.h"
#include <QDebug>

 MyThread::MyThread(QObject *parent) : QThread(parent)
  {

  }


void MyThread::run()
{


   qDebug() << "class number = " << client->input;
   qDebug() << "server ip is: "<<client->ip;
   qDebug() << "server port: "<<client->port;


   socket = new QTcpSocket(this);

   socket->connectToHost(client->ip,client->port);


   if(socket->waitForConnected(3000))
   {
      qDebug() << "Connected!";


      QByteArray data = client->pm.toUtf8();
      socket->write(data);


      socket->waitForBytesWritten(1000);


      socket->waitForReadyRead(3000);


      qDebug() << "Reading"<<socket->bytesAvailable();


      qDebug() << socket->readAll();

      socket->close();
   }
  else
  {
      qDebug() << "Not connected";
   }


  }
 

Комментарии:

1.Циклическая зависимость, tcpclient.h включает в себя mythread,h и mythread.h включает tcpclient.h. Прервите цикл, и ошибка исчезнет. Вы можете сделать это с помощью прямого объявления class tcpclient; в mythread.h .

2. @john Спасибо за ответ. Я удалил #include «tcpclient.h» из файла Mythread.h, но я все еще получаю ту же ошибку.

3. Вы также добавили прямое объявление?

4. @john не могли бы вы объяснить, что вы подразумеваете под прямым объявлением?

5. В mythread, h перед class MyThread ... добавлением строки class tcpclient; . Это прямое объявление, оно сообщает компилятору, что tcpclient является классом, но больше ничего об этом не говорит. Это то, что позволяет вам прервать цикл, потому что вам нужно сообщить компилятору, что tcpclient является классом, но вы не можете этого сделать, включив tcpclient . h заголовочный файл, потому что это создает цикл заголовочных файлов.