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

Posted

技术标签:

【中文标题】如何将用户输入从控制台传递到不同线程中的对象-> QTcpsocket【英文标题】:How to pass user input form the console to an object in a diffrent thread -> QTcpsocket 【发布时间】:2019-09-08 19:00:41 【问题描述】:

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

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

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

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

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

尤其是这条线让我非常头疼。 (该行在 main 函数中) emit IO->doSendData(IO->getInput());

我尝试发出信号 doSendData 并将输入从控制台传递到连接的插槽 sendData() 这是一个来自网络类的方法,该对象位于 threadNET 中,并且对象从控制台获取输入生活在主线程中我想这就是问题所在,但我没有胶水如何解决它。 我在 QTcreator 中没有收到任何错误消息。

提前感谢您抽出宝贵时间帮助我。 如果有什么不清楚的,请随时问我。这是我关于 Stack Overflow 的第一篇文章,如果有任何关于如何提高我的问题质量的反馈,我将不胜感激。

完整代码

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;


【问题讨论】:

【参考方案1】:

QString::fromStdString(const std::string &str) 是一个 static 成员,它返回 str 字符串的副本。

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

你需要写:

convert = QString::fromStdString(rawInput)

或 直接初始化:

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

【讨论】:

以上是关于如何将用户输入从控制台传递到不同线程中的对象-> QTcpsocket的主要内容,如果未能解决你的问题,请参考以下文章

通过组合动作链接和 ASP.Net MVC 5 中的输入将用户键入的输入从视图传递到动作控制器?

将数据从UI线程传递到c#中的另一个线程

iOS MVC - 如何将数据从模型传递到控制器?

如何将对象从单元格传递到新控制器

如何将自定义对象从异步操作过滤器传递到 ASP.net 核心中的控制器?

无法将变量从控制器传递到模型以处理codeigniter中的多个上载字段