@@ -1,6 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.0.3, 2025-07-28T19:27:23. --> | |||
<!-- Written by QtCreator 4.0.3, 2025-07-29T09:40:16. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
@@ -22,22 +22,24 @@ | |||
* 4. 连接信号槽 | |||
*/ | |||
SerialCommunicator::SerialCommunicator(QObject *parent) : QObject(parent) | |||
, serialPort(new QSerialPort(this)) | |||
, recvTimer(new QTimer(this)) | |||
, resendTimer(new QTimer(this)) | |||
, comCount(0) | |||
, maxRetry(3) | |||
, recvTimeout(50) | |||
, resendTimeout(1000) | |||
, serialPort_(new QSerialPort(this)) | |||
, recvTimer_(new QTimer(this)) | |||
, resendTimer_(new QTimer(this)) | |||
, comCount_(0) | |||
, maxRetry_(3) | |||
, recvTimeout_(50) | |||
, resendTimeout_(1000) | |||
{ | |||
// 配置定时器(单次触发) | |||
recvTimer->setSingleShot(true); | |||
resendTimer->setSingleShot(true); | |||
recvTimer_->setSingleShot(true); | |||
resendTimer_->setSingleShot(true); | |||
// 连接信号槽 | |||
connect(serialPort, &QSerialPort::readyRead, this, &SerialCommunicator::onReadyRead); | |||
connect(recvTimer, &QTimer::timeout, this, &SerialCommunicator::onRecvTimeout); | |||
connect(resendTimer, &QTimer::timeout, this, &SerialCommunicator::onResendTimeout); | |||
connect(serialPort_, &QSerialPort::readyRead, this, &SerialCommunicator::onReadyRead); | |||
connect(recvTimer_, &QTimer::timeout, this, &SerialCommunicator::onRecvTimeout); | |||
connect(resendTimer_, &QTimer::timeout, this, &SerialCommunicator::onResendTimeout); | |||
connect(serialPort_, SIGNAL(error(QSerialPort::SerialPortError)), | |||
this, SLOT(handleSerialError(QSerialPort::SerialPortError))); | |||
} | |||
/** | |||
@@ -64,11 +66,11 @@ void SerialCommunicator::setPortParams(const QString &portName, qint32 baudRate, | |||
QSerialPort::Parity parity, | |||
QSerialPort::StopBits stopBits) | |||
{ | |||
this->portName = portName; | |||
this->baudRate = baudRate; | |||
this->dataBits = dataBits; | |||
this->parity = parity; | |||
this->stopBits = stopBits; | |||
this->portName_ = portName; | |||
this->baudRate_ = baudRate; | |||
this->dataBits_ = dataBits; | |||
this->parity_ = parity; | |||
this->stopBits_ = stopBits; | |||
} | |||
/** | |||
@@ -84,37 +86,37 @@ void SerialCommunicator::setPortParams(const QString &portName, qint32 baudRate, | |||
bool SerialCommunicator::open() | |||
{ | |||
// 关闭已打开的串口(如果存在) | |||
if (serialPort->isOpen()) | |||
if (serialPort_->isOpen()) | |||
{ | |||
serialPort->close(); | |||
serialPort_->close(); | |||
} | |||
// 配置串口参数 | |||
serialPort->setPortName(portName); | |||
if (!serialPort->setBaudRate(baudRate)) | |||
serialPort_->setPortName(portName_); | |||
if (!serialPort_->setBaudRate(baudRate_)) | |||
{ | |||
emit statusChanged("波特率设置失败"); | |||
return false; | |||
} | |||
if (!serialPort->setDataBits(dataBits)) | |||
if (!serialPort_->setDataBits(dataBits_)) | |||
{ | |||
emit statusChanged("数据位设置失败"); | |||
return false; | |||
} | |||
if (!serialPort->setParity(parity)) | |||
if (!serialPort_->setParity(parity_)) | |||
{ | |||
emit statusChanged("校验位设置失败"); | |||
return false; | |||
} | |||
if (!serialPort->setStopBits(stopBits)) | |||
if (!serialPort_->setStopBits(stopBits_)) | |||
{ | |||
emit statusChanged("停止位设置失败"); | |||
return false; | |||
} | |||
serialPort->setFlowControl(QSerialPort::NoFlowControl); // 无流控制 | |||
serialPort_->setFlowControl(QSerialPort::NoFlowControl); // 无流控制 | |||
// 打开串口 | |||
if (serialPort->open(QIODevice::ReadWrite)) | |||
if (serialPort_->open(QIODevice::ReadWrite)) | |||
{ | |||
emit statusChanged("串口连接成功"); | |||
return true; | |||
@@ -136,9 +138,9 @@ bool SerialCommunicator::open() | |||
*/ | |||
void SerialCommunicator::close() | |||
{ | |||
if (serialPort->isOpen()) | |||
if (serialPort_->isOpen()) | |||
{ | |||
serialPort->close(); | |||
serialPort_->close(); | |||
emit statusChanged("串口断开"); | |||
} | |||
} | |||
@@ -156,17 +158,17 @@ void SerialCommunicator::close() | |||
*/ | |||
void SerialCommunicator::sendData(const QByteArray &data) | |||
{ | |||
if (!serialPort->isOpen()) | |||
if (!serialPort_->isOpen()) | |||
{ | |||
emit statusChanged("串口未打开,无法发送数据"); | |||
return; | |||
} | |||
// 保存待重发数据,初始化计数器,启动重发定时器 | |||
currentData = data; | |||
comCount = 0; | |||
serialPort->write(data); // 发送数据 | |||
currentData_ = data; | |||
comCount_ = 0; | |||
serialPort_->write(data); // 发送数据 | |||
emit statusChanged("发送报文:" + data.toHex().toUpper()); | |||
resendTimer->start(resendTimeout); // 启动超时计时 | |||
resendTimer_->start(resendTimeout_); // 启动超时计时 | |||
} | |||
/** | |||
@@ -175,7 +177,7 @@ void SerialCommunicator::sendData(const QByteArray &data) | |||
*/ | |||
void SerialCommunicator::setMaxRetry(int count) | |||
{ | |||
maxRetry = count; | |||
maxRetry_ = count; | |||
} | |||
/** | |||
@@ -186,7 +188,7 @@ void SerialCommunicator::setMaxRetry(int count) | |||
*/ | |||
void SerialCommunicator::setRecvTimeout(int ms) | |||
{ | |||
recvTimeout = ms; | |||
recvTimeout_ = ms; | |||
} | |||
/** | |||
@@ -195,7 +197,7 @@ void SerialCommunicator::setRecvTimeout(int ms) | |||
*/ | |||
void SerialCommunicator::setResendTimeout(int ms) | |||
{ | |||
resendTimeout = ms; | |||
resendTimeout_ = ms; | |||
} | |||
/** | |||
@@ -204,7 +206,7 @@ void SerialCommunicator::setResendTimeout(int ms) | |||
*/ | |||
bool SerialCommunicator::isOpen() const | |||
{ | |||
return serialPort->isOpen(); | |||
return serialPort_->isOpen(); | |||
} | |||
// ====================== 私有槽函数 ====================== // | |||
@@ -220,9 +222,9 @@ bool SerialCommunicator::isOpen() const | |||
void SerialCommunicator::onReadyRead() | |||
{ | |||
// 读取数据到缓冲区 | |||
recvBuffer.append(serialPort->readAll()); | |||
recvBuffer_.append(serialPort_->readAll()); | |||
//重置接收超时定时器 | |||
recvTimer->start(recvTimeout); | |||
recvTimer_->start(recvTimeout_); | |||
} | |||
/** | |||
@@ -236,9 +238,9 @@ void SerialCommunicator::onReadyRead() | |||
void SerialCommunicator::onRecvTimeout() | |||
{ | |||
// 接收完成,发送完整数据信号,停止重发定时器 | |||
emit dataReceived(recvBuffer); | |||
recvBuffer.clear(); | |||
resendTimer->stop(); | |||
emit dataReceived(recvBuffer_); | |||
recvBuffer_.clear(); | |||
resendTimer_->stop(); | |||
} | |||
/** | |||
@@ -251,18 +253,108 @@ void SerialCommunicator::onRecvTimeout() | |||
*/ | |||
void SerialCommunicator::onResendTimeout() | |||
{ | |||
if (comCount < maxRetry) | |||
if (comCount_ < maxRetry_) | |||
{ | |||
// 重发数据,更新计数器 | |||
serialPort->write(currentData); | |||
comCount++; | |||
emit statusChanged(QString("通信超时,重新发送中(%1/%2)").arg(comCount).arg(maxRetry)); | |||
resendTimer->start(resendTimeout); // 继续计时 | |||
serialPort_->write(currentData_); | |||
comCount_++; | |||
emit statusChanged(QString("通信超时,重新发送中(%1/%2)").arg(comCount_).arg(maxRetry_)); | |||
resendTimer_->start(resendTimeout_); // 继续计时 | |||
} | |||
else | |||
{ | |||
// 达到最大重发次数,触发超时信号 | |||
resendTimer->stop(); | |||
resendTimer_->stop(); | |||
emit timeoutOccurred(); | |||
} | |||
} | |||
/** | |||
* @brief 处理串口错误 | |||
* @param error 串口错误代码 | |||
* | |||
* @details 执行流程: | |||
* 1. 忽略无错误和超时错误(超时由其他机制处理) | |||
* 2. 根据错误代码生成错误描述 | |||
* 3. 对于物理断开错误(ResourceError): | |||
* - 自动关闭串口 | |||
* - 停止所有定时器 | |||
* - 清空接收缓冲区 | |||
* - 发送物理断开信号 | |||
* 4. 其他错误只发送状态通知 | |||
*/ | |||
void SerialCommunicator::handleSerialError(QSerialPort::SerialPortError error) | |||
{ | |||
// 忽略无错误和超时错误(超时由其他机制处理) | |||
if (error == QSerialPort::NoError || error == QSerialPort::TimeoutError) | |||
{ | |||
return; | |||
} | |||
QString errorMsg; | |||
switch (error) | |||
{ | |||
case QSerialPort::DeviceNotFoundError: | |||
errorMsg = "设备未找到"; | |||
break; | |||
case QSerialPort::PermissionError: | |||
errorMsg = "没有权限访问设备"; | |||
break; | |||
case QSerialPort::OpenError: | |||
errorMsg = "设备已打开"; | |||
break; | |||
case QSerialPort::ParityError: | |||
errorMsg = "奇偶校验错误"; | |||
break; | |||
case QSerialPort::FramingError: | |||
errorMsg = "帧错误"; | |||
break; | |||
case QSerialPort::BreakConditionError: | |||
errorMsg = "Break条件错误"; | |||
break; | |||
case QSerialPort::WriteError: | |||
errorMsg = "写入错误"; | |||
break; | |||
case QSerialPort::ReadError: | |||
errorMsg = "读取错误"; | |||
break; | |||
case QSerialPort::ResourceError: | |||
errorMsg = "资源错误(设备已断开)"; | |||
break; | |||
case QSerialPort::UnsupportedOperationError: | |||
errorMsg = "不支持的操作"; | |||
break; | |||
case QSerialPort::UnknownError: | |||
errorMsg = "未知错误"; | |||
break; | |||
case QSerialPort::NotOpenError: | |||
errorMsg = "设备未打开"; | |||
break; | |||
default: | |||
errorMsg = "未定义错误"; | |||
} | |||
// 物理断开处理(资源错误) | |||
if (error == QSerialPort::ResourceError) | |||
{ | |||
// 自动关闭串口 | |||
close(); | |||
// 停止所有定时器 | |||
recvTimer_->stop(); | |||
resendTimer_->stop(); | |||
// 清空缓冲区 | |||
recvBuffer_.clear(); | |||
// 通知上层 | |||
emit statusChanged("物理连接断开: " + errorMsg); | |||
emit physicalDisconnected(); | |||
} | |||
else | |||
{ | |||
// 其他错误只通知不自动断开 | |||
emit statusChanged("串口错误: " + errorMsg); | |||
} | |||
} |
@@ -60,10 +60,10 @@ public: | |||
* @param stopBits 停止位(通常为QSerialPort::OneStop) | |||
* @note 此方法应在打开串口前调用 | |||
*/ | |||
void setPortParams(const QString &portName, qint32 baudRate, | |||
QSerialPort::DataBits dataBits, | |||
QSerialPort::Parity parity, | |||
QSerialPort::StopBits stopBits); | |||
void setPortParams(const QString &portName_, qint32 baudRate_, | |||
QSerialPort::DataBits dataBits_, | |||
QSerialPort::Parity parity_, | |||
QSerialPort::StopBits stopBits_); | |||
/** | |||
* @brief 打开串口 | |||
@@ -137,6 +137,12 @@ signals: | |||
*/ | |||
void timeoutOccurred(); | |||
/** | |||
* @brief 串口错误信号 | |||
* @note 当串口发生异常错误时触发 | |||
*/ | |||
void physicalDisconnected(); | |||
private slots: | |||
/** | |||
* @brief 串口数据到达处理 | |||
@@ -156,23 +162,29 @@ private slots: | |||
*/ | |||
void onResendTimeout(); | |||
/** | |||
* @brief 处理串口错误 | |||
* @param error 串口错误代码 | |||
*/ | |||
void handleSerialError(QSerialPort::SerialPortError error); | |||
private: | |||
QSerialPort *serialPort; // 串口对象 | |||
QTimer *recvTimer; // 接收完成判断定时器 | |||
QTimer *resendTimer; // 超时重发定时器 | |||
QByteArray recvBuffer; // 接收缓冲区 | |||
QByteArray currentData; // 当前待重发数据 | |||
int comCount; // 重发计数器 | |||
int maxRetry; // 最大重发次数 | |||
int recvTimeout; // 接收超时时间(ms) | |||
int resendTimeout; // 重发间隔(ms) | |||
QSerialPort *serialPort_; // 串口对象 | |||
QTimer *recvTimer_; // 接收完成判断定时器 | |||
QTimer *resendTimer_; // 超时重发定时器 | |||
QByteArray recvBuffer_; // 接收缓冲区 | |||
QByteArray currentData_; // 当前待重发数据 | |||
int comCount_; // 重发计数器 | |||
int maxRetry_; // 最大重发次数 | |||
int recvTimeout_; // 接收超时时间(ms) | |||
int resendTimeout_; // 重发间隔(ms) | |||
// 串口参数 | |||
QString portName; | |||
qint32 baudRate; | |||
QSerialPort::DataBits dataBits; | |||
QSerialPort::Parity parity; | |||
QSerialPort::StopBits stopBits; | |||
QString portName_; | |||
qint32 baudRate_; | |||
QSerialPort::DataBits dataBits_; | |||
QSerialPort::Parity parity_; | |||
QSerialPort::StopBits stopBits_; | |||
}; | |||
#endif // SERIALCOMMUNICATOR_H |
@@ -15,6 +15,7 @@ Widget::Widget(QWidget *parent) : | |||
{ | |||
modbus = new MyModbus(); | |||
ui->setupUi(this); | |||
setFixedSize(700,500); | |||
serialComm = new SerialCommunicator(this); // 初始化串口通信类 | |||
// 配置串口参数 | |||
@@ -26,6 +27,12 @@ Widget::Widget(QWidget *parent) : | |||
connect(serialComm, &SerialCommunicator::dataReceived, this, &Widget::onSerialDataReceived); | |||
connect(serialComm, &SerialCommunicator::statusChanged, this, &Widget::onSerialStatusChanged); | |||
connect(serialComm, &SerialCommunicator::timeoutOccurred, this, &Widget::onSerialTimeout); | |||
connect(serialComm, &SerialCommunicator::physicalDisconnected, this, [=](){ | |||
ui->btnConnect->setText("连接"); | |||
ui->btn_read->setEnabled(false); | |||
ui->pushWrite->setEnabled(false); | |||
QMessageBox::warning(this, "警告", "物理连接已断开"); | |||
}); | |||
ui->comboBox_baudRate->setCurrentIndex(3); | |||
ui->comboBox_dataBit->setCurrentIndex(3); | |||
@@ -97,7 +104,6 @@ void Widget::on_pushWrite_clicked() | |||
switch (ui->comboBox_gongnengma->currentIndex()) | |||
{ | |||
case 2: //写多个线圈 | |||
{ | |||
QString sendData = ui->lineEdit->text().trimmed(); | |||
if (sendData.isEmpty()) | |||
@@ -118,7 +124,7 @@ void Widget::on_pushWrite_clicked() | |||
coils.append(ch == '1'); | |||
} | |||
quint16 stationAddress = ui->comboBox_stationAddress->currentText().toInt(); | |||
quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt(); | |||
quint16 functionCode = 0x0f; | |||
quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt(); | |||
quint16 length = ui->lineEdit_length->text().toInt(); | |||
@@ -138,7 +144,7 @@ void Widget::on_pushWrite_clicked() | |||
break; | |||
} | |||
case 3: | |||
case 3: //写多个寄存器 | |||
{ | |||
QString sendData = ui->lineEdit->text().trimmed(); | |||
if (sendData.isEmpty()) | |||
@@ -150,18 +156,46 @@ void Widget::on_pushWrite_clicked() | |||
QStringList sl = sendData.split(','); | |||
QVector<quint16> values; | |||
bool ok; | |||
// 检查输入是否是十进制 | |||
bool isDecimal = true; | |||
for (const QString &s : sl) | |||
{ | |||
quint16 v = s.toUShort(&ok, 16); | |||
s.toInt(&ok); | |||
if (!ok) | |||
{ | |||
QMessageBox::warning(this, "提示", "请输入正确的十六进制值,或检查逗号是否是英文格式!"); | |||
return; | |||
isDecimal = false; | |||
break; | |||
} | |||
} | |||
for (const QString &s : sl) | |||
{ | |||
quint16 v; | |||
if (isDecimal) | |||
{ | |||
// 如果是十进制输入 | |||
v = s.toUShort(&ok, 10); | |||
if (!ok) | |||
{ | |||
QMessageBox::warning(this, "提示", "请输入正确的十进制值(0-65535)"); | |||
return; | |||
} | |||
} | |||
else | |||
{ | |||
// 默认按十六进制处理 | |||
v = s.toUShort(&ok, 16); | |||
if (!ok) | |||
{ | |||
QMessageBox::warning(this, "提示", "请输入正确的十六进制值(0-FFFF),或检查逗号格式"); | |||
return; | |||
} | |||
} | |||
values.append(v); | |||
} | |||
quint16 stationAddress = ui->comboBox_stationAddress->currentText().toInt(); | |||
quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt(); | |||
quint16 functionCode = 0x10; | |||
quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt(); | |||
quint16 length = ui->lineEdit_length->text().toInt(); | |||
@@ -198,7 +232,7 @@ void Widget::on_btn_read_clicked() | |||
QMessageBox::warning(this, "提示", "请将“操作”切换为读线圈或读寄存器"); | |||
return; | |||
} | |||
quint16 stationAddress = ui->comboBox_stationAddress->currentText().toInt(); | |||
quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt(); | |||
quint16 functionCode; | |||
quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt(); | |||
quint16 length = ui->lineEdit_length->text().toInt(); | |||
@@ -7,7 +7,7 @@ | |||
<x>0</x> | |||
<y>0</y> | |||
<width>700</width> | |||
<height>486</height> | |||
<height>500</height> | |||
</rect> | |||
</property> | |||
<property name="windowTitle"> | |||
@@ -17,7 +17,7 @@ | |||
<property name="geometry"> | |||
<rect> | |||
<x>30</x> | |||
<y>240</y> | |||
<y>260</y> | |||
<width>181</width> | |||
<height>231</height> | |||
</rect> | |||
@@ -25,13 +25,13 @@ | |||
<property name="title"> | |||
<string>从站配置</string> | |||
</property> | |||
<widget class="QWidget" name=""> | |||
<widget class="QWidget" name="layoutWidget"> | |||
<property name="geometry"> | |||
<rect> | |||
<x>10</x> | |||
<y>30</y> | |||
<width>159</width> | |||
<height>131</height> | |||
<height>141</height> | |||
</rect> | |||
</property> | |||
<layout class="QGridLayout" name="gridLayout_2"> | |||
@@ -42,55 +42,6 @@ | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="0" column="1"> | |||
<widget class="QComboBox" name="comboBox_stationAddress"> | |||
<item> | |||
<property name="text"> | |||
<string>1</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>2</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>3</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>4</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>5</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>6</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>7</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>8</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>9</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="1" column="0"> | |||
<widget class="QLabel" name="label_10"> | |||
<property name="text"> | |||
@@ -150,13 +101,20 @@ | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="0" column="1"> | |||
<widget class="QLineEdit" name="lineEdit_stationAddress"> | |||
<property name="text"> | |||
<string>1</string> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
<widget class="QPushButton" name="btn_read"> | |||
<property name="geometry"> | |||
<rect> | |||
<x>10</x> | |||
<y>160</y> | |||
<y>170</y> | |||
<width>71</width> | |||
<height>51</height> | |||
</rect> | |||
@@ -169,7 +127,7 @@ | |||
<property name="geometry"> | |||
<rect> | |||
<x>90</x> | |||
<y>160</y> | |||
<y>170</y> | |||
<width>71</width> | |||
<height>51</height> | |||
</rect> | |||
@@ -185,165 +143,159 @@ | |||
<x>30</x> | |||
<y>19</y> | |||
<width>181</width> | |||
<height>211</height> | |||
<height>221</height> | |||
</rect> | |||
</property> | |||
<property name="title"> | |||
<string>串口配置</string> | |||
</property> | |||
<widget class="QWidget" name=""> | |||
<property name="geometry"> | |||
<rect> | |||
<x>10</x> | |||
<y>20</y> | |||
<width>161</width> | |||
<height>181</height> | |||
</rect> | |||
</property> | |||
<layout class="QGridLayout" name="gridLayout"> | |||
<item row="0" column="0"> | |||
<widget class="QLabel" name="label"> | |||
<property name="text"> | |||
<string>串口</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="0" column="1"> | |||
<widget class="QComboBox" name="comboBox_serialNum"/> | |||
</item> | |||
<item row="1" column="0"> | |||
<widget class="QLabel" name="label_2"> | |||
<property name="text"> | |||
<string>波特率</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="1" column="1"> | |||
<widget class="QComboBox" name="comboBox_baudRate"> | |||
<item> | |||
<layout class="QFormLayout" name="formLayout"> | |||
<item row="0" column="0"> | |||
<layout class="QGridLayout" name="gridLayout"> | |||
<item row="0" column="0"> | |||
<widget class="QLabel" name="label"> | |||
<property name="text"> | |||
<string>1200</string> | |||
<string>串口</string> | |||
</property> | |||
</item> | |||
<item> | |||
</widget> | |||
</item> | |||
<item row="0" column="1"> | |||
<widget class="QComboBox" name="comboBox_serialNum"/> | |||
</item> | |||
<item row="1" column="0"> | |||
<widget class="QLabel" name="label_2"> | |||
<property name="text"> | |||
<string>2400</string> | |||
<string>波特率</string> | |||
</property> | |||
</item> | |||
<item> | |||
</widget> | |||
</item> | |||
<item row="1" column="1"> | |||
<widget class="QComboBox" name="comboBox_baudRate"> | |||
<item> | |||
<property name="text"> | |||
<string>1200</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>2400</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>4800</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>9600</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>19200</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>38400</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="2" column="0"> | |||
<widget class="QLabel" name="label_3"> | |||
<property name="text"> | |||
<string>4800</string> | |||
<string>数据位</string> | |||
</property> | |||
</item> | |||
<item> | |||
</widget> | |||
</item> | |||
<item row="2" column="1"> | |||
<widget class="QComboBox" name="comboBox_dataBit"> | |||
<item> | |||
<property name="text"> | |||
<string>5</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>6</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>7</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>8</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>NONE</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="3" column="0"> | |||
<widget class="QLabel" name="label_7"> | |||
<property name="text"> | |||
<string>9600</string> | |||
<string>校验位</string> | |||
</property> | |||
</item> | |||
<item> | |||
</widget> | |||
</item> | |||
<item row="3" column="1"> | |||
<widget class="QComboBox" name="comboBox_xiaoyan"> | |||
<item> | |||
<property name="text"> | |||
<string>无校验(N)</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>奇校验(O)</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>偶校验(E)</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="4" column="0"> | |||
<widget class="QLabel" name="label_8"> | |||
<property name="text"> | |||
<string>19200</string> | |||
<string>停止位</string> | |||
</property> | |||
</item> | |||
<item> | |||
</widget> | |||
</item> | |||
<item row="4" column="1"> | |||
<widget class="QComboBox" name="comboBox_stopBit"> | |||
<item> | |||
<property name="text"> | |||
<string>1</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>2</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="5" column="0" colspan="2"> | |||
<widget class="QPushButton" name="btnConnect"> | |||
<property name="text"> | |||
<string>38400</string> | |||
<string>连接</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="2" column="0"> | |||
<widget class="QLabel" name="label_3"> | |||
<property name="text"> | |||
<string>数据位</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="2" column="1"> | |||
<widget class="QComboBox" name="comboBox_dataBit"> | |||
<item> | |||
<property name="text"> | |||
<string>5</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>6</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>7</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>8</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>NONE</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="3" column="0"> | |||
<widget class="QLabel" name="label_7"> | |||
<property name="text"> | |||
<string>校验位</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="3" column="1"> | |||
<widget class="QComboBox" name="comboBox_xiaoyan"> | |||
<item> | |||
<property name="text"> | |||
<string>无校验(N)</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>奇校验(O)</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>偶校验(E)</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="4" column="0"> | |||
<widget class="QLabel" name="label_8"> | |||
<property name="text"> | |||
<string>停止位</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="4" column="1"> | |||
<widget class="QComboBox" name="comboBox_stopBit"> | |||
<item> | |||
<property name="text"> | |||
<string>1</string> | |||
</property> | |||
</item> | |||
<item> | |||
<property name="text"> | |||
<string>2</string> | |||
</property> | |||
</item> | |||
</widget> | |||
</item> | |||
<item row="5" column="0" colspan="2"> | |||
<widget class="QPushButton" name="btnConnect"> | |||
<property name="text"> | |||
<string>连接</string> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
</widget> | |||
</item> | |||
</layout> | |||
</item> | |||
</layout> | |||
</widget> | |||
<widget class="QGroupBox" name="groupBox_3"> | |||
<property name="geometry"> | |||
@@ -403,7 +355,7 @@ | |||
<x>240</x> | |||
<y>340</y> | |||
<width>341</width> | |||
<height>131</height> | |||
<height>151</height> | |||
</rect> | |||
</property> | |||
<property name="title"> | |||
@@ -413,15 +365,15 @@ | |||
<property name="geometry"> | |||
<rect> | |||
<x>10</x> | |||
<y>0</y> | |||
<y>20</y> | |||
<width>311</width> | |||
<height>101</height> | |||
<height>91</height> | |||
</rect> | |||
</property> | |||
<property name="text"> | |||
<string>写线圈时,使用1、0代表线圈的开关状态, | |||
从左到右依次输入每个线圈的开关; | |||
写寄存器时要写入所有寄存器的16进制数值, | |||
写寄存器时要同时写入所有寄存器的数值, | |||
相邻寄存器的值之间用英文","分离。</string> | |||
</property> | |||
</widget> | |||
@@ -429,14 +381,14 @@ | |||
<property name="geometry"> | |||
<rect> | |||
<x>10</x> | |||
<y>90</y> | |||
<y>110</y> | |||
<width>301</width> | |||
<height>31</height> | |||
</rect> | |||
</property> | |||
</widget> | |||
</widget> | |||
<widget class="QWidget" name=""> | |||
<widget class="QWidget" name="layoutWidget"> | |||
<property name="geometry"> | |||
<rect> | |||
<x>240</x> | |||