如何将用户输入从控制台传递到不同线程中的对象 -> QTcpsocket

How to pass user input form the console to an object in a diffrent thread -> QTcpsocket

我正在尝试创建一个应用程序,让用户输入一个整数值,然后通过 tcp 将其发送到我的 esp32。

我已经将我的 esp32 设置为连接到我的 wifi 路由器的 tcp 服务器,然后通过串行监视器显示其 ipv4 地址。 esp32 连接到 2 个步进驱动器,稍后将使用应用程序中的数据控制它们。

因此,当必须发送的数据在运行时之前已知时,我的应用程序可以正常工作,例如,我可以创建一个包含所需数据的 const char* 变量,然后简单地使用 socket->write(foo); 发送它。

但这对我不起作用,因为我需要在运行时从控制台获取输入,然后将其传递给函数 socket->write()。问题是 QTcpSocket 对象必须在另一个线程中。所以我一直在研究如何在线程之间传递数据。

我尝试使用信号和槽机制来做到这一点,如果我正确理解的话,它就是用于此目的。

尤其是这一行让我很头疼。 (该行在主要功能中) emit IO->doSendData(IO->getInput());

我尝试发出信号 doSendData 并将输入从控制台传递到连接的插槽 sendData() 这是网络中的一种方法 class threadNET 中的对象从控制台获取输入的对象位于主线程中,我想这就是这里的问题,但我不知道如何修复它。 我在 QTcreator 中没有收到任何错误消息。

提前感谢您花时间帮助我。 如果有什么不清楚的地方,请随时问我。那是我在 Stack overflow 上的第一个 post,对于如何提高问题质量的任何反馈,我将不胜感激。

完整代码

main.cpp

//MAIN

#include <QCoreApplication>
#include <network.h>
#include <userio.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);


    QThread* threadNET = new QThread();

    network* net = new network();
    userIO* IO = new userIO();

    net->moveToThread(threadNET);


    QObject::connect(threadNET,
                     &QThread::started,
                     net,
                     &network::Connect);


    QObject::connect(IO,
                     &userIO::doSendData,
                     net,
                     &network::sendData);


    threadNET->start();

    while(true)
    {
    emit IO->doSendData(IO->getInput());
    }

    return a.exec();
}

network.h

//NETWORK HEADER

#ifndef NETWORK_H
#define NETWORK_H

#include <QObject>
#include <QTcpSocket>
#include <QAbstractSocket>
#include <QString>
#include <QDebug>
#include <iostream>
#include <string>

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

signals:
    void finished(QString ffs);
    void error(QString err);

public slots:
    void Connect();
    void sendData(QString dataToSend);

private:
    QTcpSocket *socket;
};
#endif // NETWORK_H

userIO.h

//USERIO HEADER

#ifndef USERIO_H
#define USERIO_H

#include <QObject>
#include <QString>
#include <iostream>
#include <QDebug>
#include <limits>
#include <string>

class userIO : public QObject
{
    Q_OBJECT
public:
    explicit userIO(QObject *parent = nullptr);
    QString getInput();
signals:
void doSendData(QString dataToSend);

public slots:
};

#endif // USERIO_H

network.cpp

//NETWORK SOURCE

#include "network.h"

network::network(QObject *parent) : QObject(parent)
{

}

network::~network()
{

}

void network::Connect()
{
     socket = new QTcpSocket(this);

     socket->connectToHost("192.168.179.167", 80);

     if(socket->waitForConnected(5000))
     {
         std::cout << "Connected to TcpServer";
     }
     else
     {
         qDebug() << "Error: " << socket->errorString();
     }
     emit finished("send help");
}

void network::sendData(QString dataToSend)
{
    qDebug() << "sendData" << dataToSend << "\n";

    std::string convert = dataToSend.toStdString();
    const char* formattedData = convert.c_str();

    socket->write(formattedData);
}

userIO.cpp

//USERIO SOURCE

#include "userio.h"

userIO::userIO(QObject *parent) : QObject(parent)
{

}

QString userIO::getInput()
{

    std::string rawInput;

    qDebug() << "Enter the amount of steps to go\n";
    std::cin >> rawInput;

    while(std::cin.fail())
    {
        qDebug() << "Invalid input only Integer numbers are allowed\n";
        qDebug() << "try again...\n";
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cin >> rawInput;
    }

    QString convert;
    convert.fromStdString(rawInput);
    return convert;
}

QString::fromStdString(const std::string &str)static 成员,returns 是 str 字符串的副本。

调用 convert.fromStdString(rawInput); 不会将复制的字符串存储在 convert !!

你需要写:

convert = QString::fromStdString(rawInput)

或 直接初始化:

...
QString convert(QString::fromStdString(rawInput));
return convert;