文章大致分为三步:
1.串口使用
2.增加资源(添加图片)
3.修改背景
(想要看如何添加背景的直接跳到最后就可以了。)
首先新建一个工程,命名为serialRead,这里注意下选择编译器那个界面最好只选择一个,否则最后构建项目的时候没准就会编译器混着用,可能会出些奇怪的问题,虽然可以在构建那改,但多一事不如少一事。
新建工程之后,首先要在生成的pro文件的末尾加上一句
QT +=serialport
这样才可以使用串口类。
然后引入头文件,推荐在.h文件里引入,这样后面用着比较舒服。
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
引入头文件之后,要在私有变量(private)处新建两个变量,一个是串口相关的,一个是与数据相关的。
private:
QSerialPort *serial;
QByteArray data;
总的代码到讲完再附上,现在只讲一些过程。
然后到mainwindow.cpp进行下一步操作,在构造函数中添加一段搜索串口的代码。
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//查找可用的串口
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
QSerialPort serial;//一个串口相关变量
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))//搜索串口,如果找到了先关上,等按下打开按钮再打开。
{
ui->PortBox->addItem(serial.portName());
serial.close();
}
}
ui->sendEdit->setStyleSheet("background-color: rgba(255, 255, 255, 0);");//透明化两个文本框,a代表的是透明度
ui->acceptEdit->setStyleSheet("background-color: rgba(255, 255, 255, 50);");
qDebug()<<tr("界面设置成功!");
}
这里我用了qDebug来告诉我初始化成功,使用这个函数的前提是引入头文件 #include <QtDebug> ,这个函数非常好用,后期可以查看在运行程序时,到底有没有进入自己写的函数。
这些做完,我们就先移步ui界面,进行一下对ui界面的布局。
我就做了一个很简陋的布局,用到了三个按钮(pushbutton),一个下拉栏(QComboBox),两个文本框(EditText)。布局上用了垂直分裂器,这个布局看自己喜好了,自己看的准的,直接布也很好看。下面为控件图。
布完局先别跑,先给自己的控件改一下名字,一会方便用,具体名字看我上面布局图就有。改名的地方在:
改完名字呢还是先别走,直接在这里把几个按钮对应的槽函数给做了。槽函数是QT里很好玩的东西,正是信号与槽的出现,QT才实现了对 一个东西操作会引起另一个东西变化 这件事。举个例子就是按下按钮就会出一个新界面。
槽函数的操作有好几种,这里就讲最常用的一种:在按钮处右键–>转到槽,出现下面界面时,选择clicked()直接ok就行了。然后就会跳转回mainwindow.cpp进行函数具体内容的编写。
这段的意思就是按下按钮时进行编写函数里要执行的内容。
第一个打开串口按钮的代码为:
void MainWindow::on_openButton_clicked()
{
if(ui->openButton->text()==tr("打开串口"))
{
serial=new QSerialPort;//新建一个串口相关的变量
serial->setPortName(ui->PortBox->currentText());//在那个下拉栏里显示可用串口的名字
serial->open(QIODevice::ReadWrite);/打开串口
serial->setBaudRate(QSerialPort::Baud115200);//波特率设115200
serial->setDataBits(QSerialPort::Data8);//8位数据位
serial->setParity(QSerialPort::NoParity);//无校验位
serial->setStopBits(QSerialPort::OneStop);//一位停止位
ui->PortBox->setEnabled(false);//结束配置串口的过程
ui->openButton->setText(tr("关闭串口"));
//我这里是直接在代码里配了串口的参数,实际上是可以在控件里多加几个下拉栏
//然后通过下拉栏具体选择参数的,那个有兴趣的可以自己去尝试。
connect(serial,SIGNAL(readyRead()),this,SLOT(ReadData()));
//这个connect很重要,这个后文的一个ReadData()函数和槽联系起来,如果不连接的话,无法实现对串口缓存区数据的读取
}
else {
serial->clear();
serial->close();
serial->deleteLater();
ui->PortBox->setEnabled(true);
ui->openButton->setText(tr("打开串口"));
//这段是关闭串口或未发现串口时的操作
}
}
第二个发送数据的代码为
void MainWindow::on_sendButton_clicked()
{
serial->write(ui->sendEdit->toPlainText().toLatin1());
}
//把sendEdit里的内容转化为文本通过串口发送出去。
第三个清空串口的代码为:
void MainWindow::on_clearButton_clicked()
{
ui->acceptEdit->clear();
}
//将acceptEdit内的文字清空。
这样我们就有了查询串口,打开串口,发送数据,清空接收栏这几个功能,那么还缺什么呢?就是接收接收数据啦!!
这个需要的是回到.h文件,加一个槽函数 void ReadData();
private slots:
void on_sendButton_clicked();
void on_openButton_clicked();
void on_clearButton_clicked();
void ReadData();
我们可以发现槽函数突然多了三个,这三个其实就是我们在给三个按钮加槽函数时系统自动生成的。
看到这个新的槽函数void ReadData();我们不禁想到在前面我们用了一个connect操作了它。那我们再具体讲一讲,这期间到底发生了什么?
QT里信号与槽是两个密不可分的东西,我们在给按钮写槽函数之前就先选择了他的信号:clicked。那么我们在代码层面实现信号与槽的连接时就需要用到connect这个函数了,connect(serial,SIGNAL(readyRead()),this,SLOT(ReadData()));
其原本样子为connect(sender,SIGNAL(signal),receiver,SLOT(slot),Qt::DirectConnection);
第一个参数为发送者,我们用的和串口类有关,所以写serial,第二个参数是信号,我们是准备读取时和槽相连,第三个是接收者,我们是当前串口,所以是this,第四个为槽函数,我们自定义过了,就是ReadData(),其实还有第五个参数,但一般取默认值就行了。
这样一来就结束了,一个最简单的串口发送接收数据的QT小程序就写完了。下一步就可以加个好看的背景了。
对了对了,先贴总代码:
serialRead.pro文件
#-------------------------------------------------
#
# Project created by QtCreator 2020-03-30T13:48:09
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = serialRead
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
QT +=serialport
RESOURCES += \
background.qrc \
background.qrc \
background.qrc \
background.qrc
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_sendButton_clicked();
void on_openButton_clicked();
void ReadData();
void on_clearButton_clicked();
private:
Ui::MainWindow *ui;
QSerialPort *serial;
QByteArray data;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//查找可用的串口
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))//找到了先关上,等按下打开按钮再打开。
{
ui->PortBox->addItem(serial.portName());
serial.close();
}
}
ui->sendEdit->setStyleSheet("background-color: rgba(255, 255, 255, 0);");
ui->acceptEdit->setStyleSheet("background-color: rgba(255, 255, 255, 50);");
qDebug()<<tr("界面设置成功!");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ReadData()
{
ui->acceptEdit->setFontWeight(30);
ui->acceptEdit->setFontPointSize(40);
QByteArray buf;
buf = serial->readAll();
if(!buf.isEmpty())
{
QString str = ui->acceptEdit->toPlainText();
str+=tr(buf);
ui->acceptEdit->clear();
ui->acceptEdit->append(str);
}
buf.clear();
}
void MainWindow::on_sendButton_clicked()
{
serial->write(ui->sendEdit->toPlainText().toLatin1());
}
void MainWindow::on_openButton_clicked()
{
if(ui->openButton->text()==tr("打开串口"))
{
serial=new QSerialPort;
serial->setPortName(ui->PortBox->currentText());
serial->open(QIODevice::ReadWrite);
serial->setBaudRate(QSerialPort::Baud115200);//115200
serial->setDataBits(QSerialPort::Data8);//8位数据位
serial->setParity(QSerialPort::NoParity);//无校验位
serial->setStopBits(QSerialPort::OneStop);//一位停止位
ui->PortBox->setEnabled(false);
ui->openButton->setText(tr("关闭串口"));
connect(serial,SIGNAL(readyRead()),this,SLOT(ReadData()));
}
else {
serial->clear();
serial->close();
serial->deleteLater();
ui->PortBox->setEnabled(true);
ui->openButton->setText(tr("打开串口"));
}
}
void MainWindow::on_clearButton_clicked()
{
ui->acceptEdit->clear();
}
第二步是添加资源,一般添加的资源都是图片,这些图片后面可以添加为图标或者背景,可以让自己的程序增色不少。
添加的资源的步骤为,在工程文件夹处右键选择添加新文件。添加Qt的Qt Resource File。单击choose。
而后给它起个名字,比如为background。单击下一步后选择完成。
完成进入对此文件的编辑界面,点击添加,添加前缀,前缀一般为默认的/new/prefix1,这里随喜好修改。
添加完前缀后再次点击添加,选择添加文件。在添加文件前,我们在工程所在文件夹下新建一个images文件夹,并把自己要用到的图片放到文件夹内。
这样添加文件时进入images文件夹,选择其中的图片。添加完图片后crtl+s保存一下,图片就可以使用了。
那么我们就到了最后一步,添加背景!!
我们介绍最简单的一种办法,直接在ui界面内添加,我们回到ui界面,在MainWindow处找到styleSheet。点击省略号添加图片。
单击完进入如下页面
直接输入:
#MainWindow{background-image: url(:/new/prefix1/images/kjg.jpg);}
#MianWindow是说明只在主界面生效,如果不加会让每个控件的背景都变成所选的图片。
background-image指的是我选择其为背景图片,也可以改为border-image,两者效果稍有不同。
/new/prefix1/images/kjg.jpg就是图片的所在路径了。
当然如果不自己输入的话,也可以选择直接点击添加资源后的倒三角,选择一个添加图片的方式,就可以选择图片了。
这时发现自己的界面好像只加了个边框,并没有加上背景,但没有问题,这个运行的时候背景就全了。
具体效果为:
此章结束。