木風488 2025-12-30 11:19 采纳率: 50%
浏览 2

关于#qt#的问题:点了两下发送(输入框无内容),然后又点了两下发送(输入框无内容 ,结果他竟然触发了readyread信号(相关搜索:初始化|笔记本电脑)

#没有用串口助手发数据,但是有数据发过来触发了readyread信号。
#我打开软件之后,点了两下发送(输入框无内容),然后点了打开串口,然后又点了两下发送(输入框无内容 ,结果他竟然触发了readyread信号。 串口参数是com5,110 6 1,none,none(初始化的参数,没有做过更改)。
#笔记本电脑没有连接外设(只用充电器和蓝牙鼠标)
#打印出来的消息是

img

代码:

#include "stdafx.h"

#include "AitThermometer.h"
#include <QSerialPortInfo>
AitThermometer::AitThermometer(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    m_Port = new QSerialPort();
    m_Timer = new QTimer();
    connect(ui.Send, SIGNAL(clicked()), this, SLOT(SendData()));
    connect(ui.OpenPort, SIGNAL(clicked()), this, SLOT(OpenPort()));
    connect(ui.ClosePort, SIGNAL(clicked()), this, SLOT(ClosePort()));
    connect(ui.refresh, SIGNAL(clicked()), this, SLOT(refreshSerialList()));
    connect(m_Port, SIGNAL(readyRead()), this, SLOT(ReadData()));
    connect(m_Timer, &QTimer::timeout, this, &AitThermometer::ParseData);
    Init();
}

AitThermometer::~AitThermometer()
{
}

void AitThermometer::SendData(QByteArray data)
{
    if (!m_Port->isOpen()) {
        m_Port->open(QIODevice::ReadWrite);
        if (!m_Port->isOpen()) {
            PrintText(QSFL8("串口打开失败"),1);
            return;
        }
    }
    m_Port->write(data);
    PrintText(data, 1);
}

void AitThermometer::SendData(QString data)
{
    SendData(data.toLocal8Bit());
}
//# 按钮发送数据
void AitThermometer::SendData()
{
    QString str = ui.textEdit->toPlainText();
    QByteArray data;
    if (ui.checkBox->isChecked()) {
        data += "\r\n";
    }
    if (ui.checkBox_2->isChecked()) {
        data = QByteArray::fromHex(str.toLocal8Bit());
        SendData(data);
    }
    else {
        data = str.toLocal8Bit();
        SendData(data);
    }
}

void AitThermometer::ReadData()
{
    wholedata =m_Port->readAll();
    m_Timer->start(30);//30ms未收到数据就开始解析
}
//# 解析数据
void AitThermometer::ParseData()
{
    QByteArray data = wholedata.toHex(' ').toUpper();//转16进制转大写
    PrintText(QSFL8(data), 2);
    quint8 func = quint8(wholedata[1]);
    switch (func) {
    case 0x03:
        if (wholedata.size() == 9) {
            {
                uint32_t rawValue = 0;
                rawValue |= (uint32_t(quint8(wholedata[3])) << 24);// 拼接第 1 字节(最高位)
                rawValue |= (uint32_t(quint8(wholedata[4])) << 16);// 拼接第 2 字节
                rawValue |= (uint32_t(quint8(wholedata[5])) << 8);// 拼接第 3 字节
                rawValue |= (uint32_t(quint8(wholedata[6])));
                std::memcpy(&m_Temp, &rawValue, sizeof(float));
            }
        }
        break;
    default:
        break;

    }
    wholedata.clear();
    m_Timer->stop();
    PrintText(QSFL8("温度=%1").arg(m_Temp), 2);
}

void AitThermometer::Init()
{
    {
        refreshSerialList();
        ui.DataBits->addItem(QString::number(6), QSerialPort::Data6);//数据位
        ui.DataBits->addItem(QString::number(7), QSerialPort::Data7);
        ui.DataBits->addItem(QString::number(8), QSerialPort::Data8);
        ui.StopBits->addItem(QString::number(1), QSerialPort::OneStop);//停止位
        ui.StopBits->addItem(QString::number(1.5), QSerialPort::OneAndHalfStop);
        ui.StopBits->addItem(QString::number(2), QSerialPort::TwoStop);
        ui.Parity->addItem("None", QSerialPort::NoParity);//校验
        ui.Parity->addItem("Even", QSerialPort::EvenParity);
        ui.Parity->addItem("Odd", QSerialPort::OddParity);
        ui.FlowControl->addItem("None", QSerialPort::NoFlowControl);//流控制
        ui.FlowControl->addItem("RTS/CTS (Hardware)", QSerialPort::HardwareControl);
        ui.FlowControl->addItem("XON/XOFF (Software)", QSerialPort::SoftwareControl);
    }
}
//# 保存串口参数
void AitThermometer::SavePort()
{
}
//# 打印消息
void AitThermometer::PrintText(QString str, int type)
{
    QDateTime Time = QDateTime::currentDateTime();
    ui.textBrowser->append(QString("<font color=\"gray\">%1:</font>").arg(Time.toString("yyyy-MM-dd-hh-mm-ss")));
    if (type == 1) {
        ui.textBrowser->append(QString("<font color=\"green\">%1</font>").arg(str));
    }
    else {
        ui.textBrowser->append(QString("<font color=\"blue\">%1</font>").arg(str));
    }
}

bool AitThermometer::OpenPort()
{
    if (m_Port->isOpen()) {
        m_Port->close();
    }
    m_Port->setPortName(QString(ui.PortNum->currentText()));
    m_Port->setBaudRate(ui.BaudRate->currentData().toInt());
    /*
    ui.FlowControl->addItem("None", QSerialPort::NoFlowControl);//流控制
    currentText拿的是None,currentData拿的是QSerialPort::NoFlowControl
    */
    m_Port->setDataBits((QSerialPort::DataBits)ui.DataBits->currentData().toInt());
    m_Port->setStopBits((QSerialPort::StopBits)ui.StopBits->currentData().toInt());
    m_Port->setFlowControl((QSerialPort::FlowControl)ui.FlowControl->currentData().toInt());
    m_Port->setParity((QSerialPort::Parity)ui.Parity->currentData().toInt());
    m_Port->open(QIODevice::ReadWrite);//读写模式

    if(!m_Port->isOpen()) {
        PrintText(QSFL8("串口打开失败"), 1);
        return false;
    }
    else {
        PrintText(QSFL8("串口打开成功"), 1);
        return true;
    }
}

void AitThermometer::ClosePort()
{
    m_Port->close();
}
//# 刷新
void AitThermometer::refreshSerialList()
{
    ui.PortNum->clear();//串口号
    for (const QSerialPortInfo &info :QSerialPortInfo::availablePorts())
    {
        ui.PortNum->addItem(info.portName());
    }
    ui.BaudRate->clear();//波特率
    for (const qint32 baud: QSerialPortInfo::standardBaudRates()) {
        ui.BaudRate->addItem(QString::number(baud),baud);
    }
}


  • 写回答

2条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-12-30 11:20
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析:
      - 没有通过串口助手发送数据,但readyRead信号却被触发。
      - 特定操作顺序(先点两下无内容的发送,再打开串口,又点两下无内容的发送)后触发了readyRead信号。
    2. 解决方案:
      - 首先,确认触发readyRead信号的来源。在Qt中,当有新的数据到达串口时会触发这个信号。检查代码中连接串口的部分,看是否有意外的数据接收逻辑。例如:
      cpp QSerialPort serial; // 连接串口信号槽 connect(&serial, &QSerialPort::readyRead, this, &YourClass::handleReadyRead); void YourClass::handleReadyRead() { QByteArray data = serial.readAll(); // 处理接收到的数据 qDebug() << "Received data:" << data; }
      - 对于这种意外触发的情况,可能是串口初始化或者相关配置有问题。检查串口打开时的参数设置,比如波特率、数据位、停止位等。
      cpp serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); if (serial.open(QIODevice::ReadWrite)) { qDebug() << "Serial port opened successfully"; } else { qDebug() << "Failed to open serial port:" << serial.errorString(); }
      - 另外,检查是否有其他线程或者异步操作影响了串口的状态。确保在操作串口时,没有其他代码在不恰当的时候干扰了数据接收。
    3. 多种解决方案优缺点:
      - 优点:
      • 仔细检查串口初始化和参数设置,可以从根本上解决串口配置不当导致意外数据接收的问题。
      • 排查其他线程或异步操作的影响,能全面考虑到程序中可能存在的干扰因素。
      • 缺点:
      • 检查代码可能比较繁琐,需要对整个串口相关的代码逻辑有清晰的理解。
      • 排查线程和异步操作可能涉及到较多的代码路径,需要花费一定时间。
    4. 总结:
      这种情况通常是由于串口配置错误或者有其他意外的数据源导致readyRead信号被触发。通过仔细检查串口初始化参数、相关代码逻辑以及排查其他可能干扰的操作,可以找到问题并解决。

    需要注意的是,以上代码示例是基于Qt的C++代码,具体实现可能因项目的实际情况有所不同。如果是使用Qt的其他语言版本(如Qt for Python等),代码形式会有所差异,但基本思路是相似的。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    评论

报告相同问题?

问题事件

  • 创建了问题 12月30日