使用qt creater创建一个串口助手demo

1.在CMakeList.txt后加入SerialPort
 

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets SerialPort)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets SerialPort)

target_link_libraries(03_SerialPort PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt6::SerialPort)

2.设置槽函数

private slots:
    void on_openPortBtn_released();

    void on_sendBtn_released();

    void onReadyRead();
    void on_sendFileBtn_released();

    void on_openFileBtn_released();

    void on_hexDisplayChx_toggled(bool checked);

    void on_timerSendChx_toggled(bool checked);

    void on_sendStopBtn_released();

    void on_servoleft_released();

    void on_servoright_released();

    void on_clearRecbBtn_released();

    void on_pushButton_released();

    void on_sendClearBtn_released();

3.在头文件建立好头文件后在cpp文将各个槽函数用处置入

void QMainwindow::init()
{
    //获取所有可用的串口
    auto portsInfo =QSerialPortInfo::availablePorts();
    for(auto& info : portsInfo)
    {
        qInfo() << info.description() << info.portName()<<info.systemLocation();
        ui->portsCmd->addItem(info.portName() +":" + info.description(),info.portName());
    }
    //获取标准的波特率
    auto baudRates = QSerialPortInfo::standardBaudRates();
    for(auto br : baudRates)
    {
        ui->baudrateCmd->addItem(QString::number(br),br);
    }
    ui->baudrateCmd->setCurrentText("9600");
    //设置停止位
    ui->stopBitsCmd->addItem("1",QSerialPort::OneStop);
    ui->stopBitsCmd->addItem("1.5",QSerialPort::OneAndHalfStop);
    ui->stopBitsCmd->addItem("2",QSerialPort::TwoStop);
    //设置数据位
    ui->dataCmd->addItem("5",QSerialPort::Data5);
    ui->dataCmd->addItem("6",QSerialPort::Data6);
    ui->dataCmd->addItem("7",QSerialPort::Data7);
    ui->dataCmd->addItem("8",QSerialPort::Data8);
    ui->dataCmd->setCurrentText("8");
    //设置校验位
    ui->parityCmd->addItem("None",QSerialPort::NoParity);
    ui->parityCmd->addItem("Even",QSerialPort::EvenParity);
    ui->parityCmd->addItem("Odd",QSerialPort::OddParity);

    connect(&serialport,&QSerialPort::readyRead,this,&QMainwindow::onReadyRead);
    timer.callOnTimeout([=]
    {
       this->on_sendBtn_released();
    });

    //设置改变
    connect(ui->baudrateCmd,&QComboBox::currentIndexChanged,this,[=]
    {
        auto br = ui->baudrateCmd->currentData().value<QSerialPort::BaudRate>();
        if(!serialport.setBaudRate(br))
            {
            QMessageBox::warning(this,"false","设置波特率失败:"+serialport.errorString());
        }
    });
    connect(ui->dataCmd,&QComboBox::currentIndexChanged,this,[=]
    {
        auto value = ui->dataCmd->currentData().value<QSerialPort::DataBits>();
        if(!serialport.setDataBits(value))
            {
            QMessageBox::warning(this,"false","设置数据位失败:"+serialport.errorString());
        }
    });
    connect(ui->stopBitsCmd,&QComboBox::currentIndexChanged,this,[=]
    {
        auto value = ui->stopBitsCmd->currentData().value<QSerialPort::StopBits>();
        if(!serialport.setStopBits(value))
            {
            QMessageBox::warning(this,"false","设置停止位失败:"+serialport.errorString());
        }
    });
    connect(ui->parityCmd,&QComboBox::currentIndexChanged,this,[=]
    {
        auto value = ui->parityCmd->currentData().value<QSerialPort::Parity>();
        if(!serialport.setParity(value))
            {
            QMessageBox::warning(this,"false","设置校验位失败:"+serialport.errorString());
        }
    });


}

void QMainwindow::on_openPortBtn_released()
{

    //串口是否已经被打开
    if(serialport.isOpen())
    {
        serialport.close();
        ui->openPortBtn->setText("打开串口");
        if(timer.isActive())
            timer.stop();
        return;
    }
    //获取串口名
    auto portName = ui->portsCmd->currentData().toString();
    //获取波特率
    auto baudRate = ui->baudrateCmd->currentData().value<QSerialPort::BaudRate>();
    //获取数据位
    auto dataBits =ui->dataCmd->currentData().value<QSerialPort::DataBits>();
    //获取停止位
    auto stopBits = ui->stopBitsCmd->currentData().value<QSerialPort::StopBits>();
    //获取校验位
    auto parity = ui->parityCmd->currentData().value<QSerialPort::Parity>();

    serialport.setPortName(portName);
    serialport.setBaudRate(baudRate);
    serialport.setDataBits(dataBits);
    serialport.setStopBits(stopBits);
    serialport.setParity(parity);

    //打开串口
    if(!serialport.open(QIODevice::ReadWrite))
    {
        QMessageBox::warning(this,"warning",portName +"  "+"open failed:"+ serialport.errorString());
        return;
    }
    else
    {
        ui->openPortBtn->setText("关闭串口");
    }
}

void QMainwindow::on_sendBtn_released()
{
    auto datastr = ui->sendEdit->toPlainText() + (ui->sendNewLineChx->isChecked() ? "\r\n":"");
    serialport.write(datastr.toLocal8Bit());
}

void QMainwindow::onReadyRead()
{
    auto data = serialport.readAll();
    auto datastr = QString::fromLocal8Bit(data);
    if(ui->hexDisplayChx->isChecked()){

        ui->recvEdit->appendPlainText(datastr.toLocal8Bit().toHex(' ').toUpper());
    }else{
        ui->recvEdit->appendPlainText(datastr);
    }
}

void QMainwindow::on_openFileBtn_released()
{
    auto filename = QFileDialog::getOpenFileName(this,"选择文件",QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
                                                "txt(*.txt);;all(*.*)");
    if(!filename.isEmpty())
    {
        ui->fileNameEdit->setText(filename);
    }
}

void QMainwindow::on_sendFileBtn_released()
{
    auto filename = ui->fileNameEdit->text();
    QFile file(filename);
    if(file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(this,"warning",filename + "open failed:"+ file.errorString());
        return;
    }

    //这个地方需要判断一下是什么编码
    serialport.write(QString::fromLocal8Bit(file.readAll()).toLocal8Bit());

    if(ui->fileNameEdit->text().isEmpty())
    {
        QMessageBox::warning(this,"warning","错误  你并没有选择文件");
    }

}

void QMainwindow::on_hexDisplayChx_toggled(bool checked)
{
    if(checked)
        displayHex();
    else
        displayText();
}

void QMainwindow::displayHex()
{
    //先把数据拿出来
    auto datastr = ui->recvEdit->toPlainText();
    //转成十六进制
    auto hexdata = datastr.toLocal8Bit().toHex(' ').toUpper();
    //写回去
    ui->recvEdit->setPlainText(hexdata);
}

void QMainwindow::displayText()
{
    //先把数据拿出来
    auto datastr = ui->recvEdit->toPlainText();
    //转成文本
    auto textdata =QString::fromLocal8Bit(datastr.toLocal8Bit());
    //写回去
    ui->recvEdit->appendPlainText(textdata);
}

void QMainwindow::on_timerSendChx_toggled(bool checked)
{
    if(checked)
    {
        timer.start(ui->timerperiodEdit->text().toUInt());
        ui->timerperiodEdit->setEnabled(false);
    }
    else
    {
        timer.stop();
        ui->timerperiodEdit->setEnabled(true);

    }
}

void QMainwindow::on_sendStopBtn_released()
{
    serialport.clear();
    if(timer.isActive())
        timer.stop();
}

void QMainwindow::on_servoleft_released()
{
            ui->sendEdit->clear();
        QString text = "1";
        ui->sendEdit->appendPlainText(text);
}

void QMainwindow::on_servoright_released()
{
        ui->sendEdit->clear();
        QString text = "0";
        ui->sendEdit->appendPlainText(text);
}

void QMainwindow::on_clearRecbBtn_released()
{
        ui->recvEdit->clear();
}

void QMainwindow::on_pushButton_released()
{
        ui->portsCmd->clear();
        auto portsInfo =QSerialPortInfo::availablePorts();
        for(auto& info : portsInfo)
        {
            qInfo() << info.description() << info.portName()<<info.systemLocation();
            ui->portsCmd->addItem(info.portName() +":" + info.description(),info.portName());
        }
}

void QMainwindow::on_sendClearBtn_released()
{
        ui->sendEdit->clear();
}

4.ui设计(基于ATK_XCOM)加了舵机0,1操作

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是一个简单的示例,使用 Qt Creator 编写机器人的 A* 算法路径规划程序。 首先,我们需要创建一个 Qt Widgets 应用程序,在主窗口中添加一些 UI 元素,例如一个绘图区域和一些按钮。我们还需要创建一个类,称为 `Node`,用于表示图中的每个节点。该类应包含以下成员变量: ```cpp int x; // x 坐标 int y; // y 坐标 int f; // f(n) = g(n) + h(n) int g; // 从起点到该节点的实际代价 int h; // 从该节点到终点的估计代价 bool blocked; // 是否被阻塞 Node *parent; // 父节点指针,用于构建路径 ``` 接下来,我们需要实现 A* 算法的核心逻辑。我们可以定义一个名为 `AStar` 的类,其中包含以下方法: ```cpp void setStartNode(Node *node); // 设置起点 void setEndNode(Node *node); // 设置终点 void addObstacle(Node *node); // 添加障碍物节点 void removeObstacle(Node *node); // 移除障碍物节点 void clear(); // 清空所有节点 bool search(); // 执行 A* 算法搜索 QVector<Node *> getPath(); // 获取搜索结果路径 ``` 在 `search` 方法中,我们需要实现 A* 算法的核心逻辑,包括开放列表、关闭列表、启发式函数、节点代价等。以下是一个简单的伪代码实现: ```cpp while (!openList.isEmpty()) { // 从开放列表中选取 f 值最小的节点 Node *current = openList.getSmallestF(); // 如果当前节点为终点,则搜索成功,返回 true if (current == endNode) { return true; } // 将当前节点从开放列表中移除 openList.remove(current); // 将当前节点加入关闭列表 closedList.append(current); // 遍历当前节点的相邻节点 foreach (Node *neighbor, current->neighbors) { // 如果相邻节点已经在关闭列表中,则跳过 if (closedList.contains(neighbor)) { continue; } // 如果相邻节点被阻塞,则跳过 if (neighbor->blocked) { continue; } // 计算从起点到相邻节点的代价 int g = current->g + distance(current, neighbor); // 如果相邻节点不在开放列表中,则加入开放列表 if (!openList.contains(neighbor)) { neighbor->g = g; neighbor->h = heuristic(neighbor, endNode); neighbor->f = neighbor->g + neighbor->h; neighbor->parent = current; openList.append(neighbor); } // 否则更新相邻节点的代价和父节点指针 else if (g < neighbor->g) { neighbor->g = g; neighbor->f = neighbor->g + neighbor->h; neighbor->parent = current; } } } // 如果开放列表为空,则搜索失败,返回 false return false; ``` 在 `getPath` 方法中,我们需要通过遍历每个节点的父节点指针,从终点开始构建路径。以下是一个简单的实现: ```cpp QVector<Node *> AStar::getPath() { QVector<Node *> path; Node *current = endNode; while (current != nullptr) { path.prepend(current); current = current->parent; } return path; } ``` 最后,我们需要实现绘图区域的绘制逻辑,以显示搜索结果路径。我们可以创建一个名为 `GraphicsView` 的类,继承自 `QGraphicsView`,其中包含以下方法: ```cpp void setNodes(const QVector<Node *> &nodes); // 设置节点列表 void setPath(const QVector<Node *> &path); // 设置搜索结果路径 void draw(); // 绘制节点和路径 ``` 在 `draw` 方法中,我们需要遍历节点列表,根据节点坐标和阻塞状态绘制节点,以及根据搜索结果路径绘制路径。以下是一个简单的实现: ```cpp void GraphicsView::draw() { // 清空场景 scene()->clear(); // 绘制节点 foreach (Node *node, nodes) { QGraphicsEllipseItem *item = new QGraphicsEllipseItem(node->x - 5, node->y - 5, 10, 10); item->setBrush(node->blocked ? Qt::black : Qt::white); scene()->addItem(item); } // 绘制路径 if (!path.isEmpty()) { QPainterPath painterPath; painterPath.moveTo(path.first()->x, path.first()->y); foreach (Node *node, path) { painterPath.lineTo(node->x, node->y); } QGraphicsPathItem *item = new QGraphicsPathItem(painterPath); item->setPen(QPen(Qt::red, 3)); scene()->addItem(item); } } ``` 这样,我们就完成了一个简单的机器人 A* 算法路径规划程序的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Siriesckck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值