最近在做一个基于sim900 的串口通信工具,基于qml和c++来实现。
首先,对于串口,qt有自带的QSerialPort,可以实现同步,和异步通信,qt creator也有自带的例子,本例子是从其中一个名为“terminal”的例子学习了qt如何实现异步通信(c++),然后通过qml来写界面,逻辑部分由c++实现。
通过qmlc++混合编程基于QSerialPort的异步通信(记得在pro中加上QT+=serialport),主要步骤包括下面几个:
1.使用setPort()或者setPortName()方指定想要访问的串口设备。
2.以只读或者只写或者读写模式调用open()方法打开串口。(注意:串口都是以互斥的方式访问,这也就是说我们不能打开一个已经打开的串口。)
3.成功打开之后,QSerialPort尝试着获取串口当前的配置并初始化它。你也可以使用setBaudRate(),setDataBits(),setParity(),setStopBits()和setFlowControl()方法重新配置它,
4.如果串口用读写模式打开,你就可以调用read()或者write()方法,可选的还有readline()和readAll()方法。可以使用close()方法来关闭串口和取消I/O操作。
下边叙述本程序: serial.h,serial.cpp为主函数,main.qml为主界面,Settings.qml为串口设置界面:
/main.qml///
import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Rectangle{
width: 800
height: 600
color: "lightblue"
Settings{
id:settingwindow
visible: false
}
Column{
anchors.fill: parent
spacing: 50
Row{
spacing: 50
Button{
width: 60
text: "Open"
onClicked: {
settingwindow.visible=true//使设置窗口可见,通过设置串口的apply按钮触发的serialtest.openAndSetPort函数打开和设置串口
}
}
Button{
width: 60
text: "Close"
onClicked: {
serialtest.closePort()//关闭串口
Qt.quit()
}
}
}
Grid{
rows:2
columns:4
rowSpacing: 20
columnSpacing: 40
Label{
height: 25
text: "Send Data : "
verticalAlignment :Text.AlignVCenter
}
TextField {
id: textInput1
width: 300
height: 25
placeholderText: qsTr("Send Data")
font.pixelSize: 12
}
Label{
height: 25
text: "Number of Send Data: "+serialtest.sendnumber//显示发送数据计数
verticalAlignment :Text.AlignVCenter
}
Button{
id:sendData
width: 60
text: "Send"
onClicked: {
serialtest.sendto(textInput1.text);//触发发送数据函数
}
}
Label{
height: 25
text: "Receive Data : "
verticalAlignment :Text.AlignVCenter
}
Rectangle{
height: 300
width: 300
color: "lightgreen"
radius: 10
Label{
anchors.fill: parent
id: textreceive
font.pixelSize: 12
text:serialtest.receivedata
}
}
Label{
height: 25
text: "Number of receive Data: "+serialtest.receivenumber//显示接收数据计数
verticalAlignment :Text.AlignVCenter
}
Button{
width: 60
text: "Clear"
onClicked: {//清空接收数据显示,将数据计数清零
serialtest.receivedata=""
serialtest.sendnumber="0"
serialtest.receivenumber="0"
serialtest.clearnumber();
}
}
}
}
}
/Settings.qml/
import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
Window{
id:setwindow
width: 300
height: 300
Column{
id: maincolumn
anchors.fill: parent
spacing: 10
Rectangle{
anchors.horizontalCenter: parent.horizontalCenter
height: 1
width: parent.width
}
Label{
anchors.horizontalCenter: parent.horizontalCenter
text: "Set Serial Port"
font.pointSize:12
font.bold: true
}
Grid{
id:selectgrid
anchors.horizontalCenter: parent.horizontalCenter
rows:6
columns: 2
columnSpacing: 20
rowSpacing: 10
Label{
id:selectlabel
height: 20
text: "PortName:"
font.pointSize:9
horizontalAlignment : Text.AlignHCenter
verticalAlignment :Text.AlignVCenter
}
ComboBox {
id :firstcombo
width: maincolumn.width/2
currentIndex: 2
model: [ "COM1", "COM2", "COM3" ,"COM4" ,"COM5" ,"COM6" ]
}
Label{
text: "BaudRate:"
height: 20
font.pointSize:selectlabel.font.pointSize
horizontalAlignment : Text.AlignHCenter
verticalAlignment :Text.AlignVCenter
}
ComboBox {
id: baudRate
width:firstcombo.width
currentIndex: 0
model: [ "9600", "19200", "38400","115200" ]
}
Label{
text: "Data bits:"
height: 20
font.pointSize:selectlabel.font.pointSize
horizontalAlignment : Text.AlignHCenter
verticalAlignment :Text.AlignVCenter
}
ComboBox {
id:dataBits
width:firstcombo.width
currentIndex: 3
model: [ "5", "6", "7", "8" ]
}
Label{
text: "Parity:"
height: 20
font.pointSize:selectlabel.font.pointSize
horizontalAlignment : Text.AlignHCenter
verticalAlignment :Text.AlignVCenter
}
ComboBox {
id:parity
width:firstcombo.width
currentIndex: 0
model: [ "None", "Even", "Odd", "Mark", "Space" ]
}
Label{
height: 20
text: "Stop bits:"
font.pointSize:selectlabel.font.pointSize
horizontalAlignment : Text.AlignHCenter
verticalAlignment :Text.AlignVCenter
}
ComboBox {
id:stopBits
width:firstcombo.width
currentIndex: 0
model: [ "1", "1.5", "2" ]
}
Label{
height: 20
text: "Flow control:"
font.pointSize:selectlabel.font.pointSize
horizontalAlignment : Text.AlignHCenter
verticalAlignment :Text.AlignVCenter
}
ComboBox {
id:flowControl
currentIndex: 0
width:firstcombo.width
model: [ "None", "RTS/CTS", "XON/XOFF" ]
}
}
Button{
width: 60
text: "Apply"
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
serialtest.openAndSetPort(firstcombo.currentIndex,baudRate.currentIndex,dataBits.currentIndex
,parity.currentIndex,stopBits.currentIndex,flowControl.currentIndex)
//触发此函数,由combobox控件的currentIndex作为函数变量,(所有combobox的model值和顺序都和serialtest.openAndSetPort一致,这样就可以通过传递index来获取当前设置信息)
setwindow.visible=false
}
}
}
}
<span style="font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="html"><span style="font-family: Arial, Helvetica, sans-serif;"></span><span style="font-family: Arial, Helvetica, sans-serif;">serialset.h/</span>
#include <QObject>