打印
[应用相关]

STM32遥控小车上位机部分

[复制链接]
楼主: 回复就哭哭
手机看帖
扫描二维码
随时随地手机跟帖
21
回复就哭哭|  楼主 | 2022-2-28 15:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
4. 控制组
控制组为主窗口的第三个部分,UI界面如图:

使用特权

评论回复
22
回复就哭哭|  楼主 | 2022-2-28 15:12 | 只看该作者
说明:

该组由8个按钮组成,每个按钮的功能统一,即按钮按下后程序会通过串口发出相应的指令,从而控制遥控小车的状态。

使用特权

评论回复
23
回复就哭哭|  楼主 | 2022-2-28 15:14 | 只看该作者
指令与功能的对应如下:
前进:        00                                右旋转:        04
后退:        01                                左旋转:        05
右转:        02                                加速:        06
左转:        03                                减速:        07
直走:        0a                                停止(刹车):ff               

使用特权

评论回复
24
回复就哭哭|  楼主 | 2022-2-28 15:15 | 只看该作者
a. 实现点击控制按钮时发出相应控制指令
功能描述:某一个控制按钮按下,程序跳转到对应的槽函数,槽函数中实现向串口写数据的功能。

代码片段:
void MainWindow::on_BtnGo_clicked()         //按钮 BtnGo 按下时的槽函数
{
    mSerialPort.write(QByteArray::fromHex("00"));
}
void MainWindow::on_BtnBack_clicked()        //按钮 BtnBack 按下时的槽函数
{
    mSerialPort.write(QByteArray::fromHex("01"));
}
void MainWindow::on_BtnRight_clicked()        //按钮 BtnRight 按下时的槽函数
{
    mSerialPort.write(QByteArray::fromHex("02"));
}
...

使用特权

评论回复
25
回复就哭哭|  楼主 | 2022-2-28 15:15 | 只看该作者
代码说明:

每一个槽函数都调用相同的函数write()函数,不同的只是传入的参数有区别。其余与测试按钮部分操作原理相同。

使用特权

评论回复
26
回复就哭哭|  楼主 | 2022-2-28 15:17 | 只看该作者
5. 菜单栏
菜单栏设计如下:


说明:

该菜单栏只有一个选项卡,即“帮助”,在该选项卡下有两个子菜单,分别为“说明”和“关于…”,点击说明栏可弹出新窗口,用于显示本软件的使用说明;点击“关于…”可弹出一个新窗口,用于显示本软件的制作信息等。

使用特权

评论回复
27
小叶三千| | 2022-2-28 15:19 | 只看该作者
PC端怎么控制小车呢,串口-蓝牙?还是串口wifi?还是直接连线。感觉手机端比较实用

使用特权

评论回复
28
回复就哭哭|  楼主 | 2022-2-28 15:22 | 只看该作者
a. 设计菜单栏
在QT中设计菜单栏可以直接使用交互界面进行UI设计,当然,前提是该窗口为mainwindow类型窗口,如果是dialog或者widget,就需要使用代码进行编写菜单栏。

b. 设计菜单栏的槽函数
功能描述:当点击菜单栏中的某个选项时,程序转到执行槽函数,从而弹出相应的窗口。

使用特权

评论回复
29
回复就哭哭|  楼主 | 2022-2-28 15:23 | 只看该作者
代码片段:
//信号绑定槽函数写法:
connect(ui->ActIllstrate, SIGNAL(triggered()), this, SLOT(on_DescriptionWindow()));
//槽函数写法:
void MainWindow::on_DescriptionWindow()
{
    descriptionWidget *descriptionW = new descriptionWidget;
    descriptionW->setWindowModality(Qt::ApplicationModal);
    descriptionW->show();
}

使用特权

评论回复
30
回复就哭哭|  楼主 | 2022-2-28 15:25 | 只看该作者
代码说明:

该部分的代码与前文点击串口配置按钮的槽函数写法类似,同样也需要先新建一个qt设计师界面类,并加入到mainWindow.h文件中。
两个菜单选项的槽函数写法类似,具体见代码源文件。

使用特权

评论回复
31
回复就哭哭|  楼主 | 2022-2-28 15:27 | 只看该作者
6. 子窗口设计
子窗口界面设计如下:



使用特权

评论回复
32
回复就哭哭|  楼主 | 2022-2-28 15:34 | 只看该作者
说明:

该部分分为两个板块,分别为上板块与下板块:上板块中有5个静态标签Label,分别命名为串口的相关参数名,以及对应5个下拉选择框;下板块有两个按钮控件,分别命名为确定和取消。
对于上板块,与用户产生交互的控件只有那5个下拉框,第一个下拉框中的选项为可用的串口选项,该选项内容在启动程序时自动填充。后面4个下拉框选项固定,在UI界面设计时就填充好,不需要使用逻辑代码编写。
对于下板块,交互按钮分别为确定按钮和取消按钮。点击确定按钮时,程序将下拉框中的选项存储在config.ini文件中,然后关闭子窗口。点击取消按钮时,程序将只关闭子窗口。
除了上述两个板块的固定功能外,设计子窗口时还应实现以下功能:在开启子窗口时,程序能将当前的串口配置信息显示在下拉框中,即下拉框中的默认选项为当前配置的选项。

使用特权

评论回复
33
回复就哭哭|  楼主 | 2022-2-28 15:35 | 只看该作者
a. 实现下拉框的自动填充
功能描述:每次弹出子窗口时,程序能自动将当前已连接的所有串口端口名自动填充到串口名下拉框中。

代码片段:

newWindow::newWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::newWindow)
{
    ui->setupUi(this);
    //获取当前已连接的串口号,并将其填入到下拉框选项中
    QList<QSerialPortInfo> InfoSerialPort = QSerialPortInfo::availablePorts();
    int cnt = InfoSerialPort.count();
    for(int i=0; i<cnt; i++)
    {
        ui->CboxPortName->addItem(InfoSerialPort.at(i).portName());
    }
}

使用特权

评论回复
34
回复就哭哭|  楼主 | 2022-2-28 15:46 | 只看该作者
代码说明:

代码中QSerialPortInfo::availablePorts是QSerialPortInfo中的静态变量,可不需实例化对象直接调用。availablePorts中存储的是当前已连接上的串口信息。

使用特权

评论回复
35
回复就哭哭|  楼主 | 2022-2-28 15:47 | 只看该作者
b. 实现点击确定按钮时保存配置且关闭窗口
功能描述:点击确定按钮时,程序将当前下拉框的选项内容写到配置文件中,然后在关闭窗口。此过程的槽函数分为三步:1. 读取当前下拉框的内容,2. 写入配置文件,3. 关闭窗口。

使用特权

评论回复
36
回复就哭哭|  楼主 | 2022-2-28 15:52 | 只看该作者
代码片段:
void newWindow::on_BtnCommit_clicked()
{
    readCbox();
    makeConfigFile();
    this->close();
}
void newWindow::readCbox()
{
    mPortName = ui->CboxPortName->currentText();
    ...
}
void newWindow::makeConfigFile()
{
    QSettings iniConfigFile(fileName,QSettings::IniFormat);
    iniConfigFile.setValue("serialport/portname",mPortName);
    ...
}

使用特权

评论回复
37
回复就哭哭|  楼主 | 2022-2-28 15:54 | 只看该作者
代码说明:

readCbox()为槽函数的第一步,调用QComboBox类的currentText()或currentIndex()以获取当前选择的内容。
makeConfigFile()为槽函数的第二步,此函数与前文主窗口的makeConfigFile()函数写法相同,此处不多解释(注:这里可能有人会问了,既然两个函数相同,为啥不写成static类型函数然后直接调用呢?原因就是这个函数对类的成员变量有操作,改成static函数类型的话需要将成员变量弄成全局变量,整个工程就要大改,有点麻烦,感兴趣的朋友可以试一试。)
this->close()为槽函数的第三步,该函数可以直接将当前窗口关闭。

使用特权

评论回复
38
回复就哭哭|  楼主 | 2022-2-28 15:55 | 只看该作者
c. 实现点击取消按钮时关闭子窗口
功能描述:点击取消按钮时,直接等效于关闭该窗口。
代码片段:
void newWindow::on_BtnCancel_clicked()
{
    this->close();
}

使用特权

评论回复
39
回复就哭哭|  楼主 | 2022-2-28 15:55 | 只看该作者
代码说明:

该槽函数直接调用this->close()就行,与点击确定按钮槽函数的最后一步相同。

使用特权

评论回复
40
回复就哭哭|  楼主 | 2022-2-28 15:57 | 只看该作者
d. 开启子窗口时的初始化动作(实现当前串口配置的显示)
功能描述:每次弹出子窗口时,保证子窗口中的下拉框默认选项为当前配置选项。该过程分为两步:1. 读取配置文件,2. 将参数显示到下拉框中。要使每次初始化时都能执行此过程,将该过程添加到初始化的函数中就行。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则