#include "mainwidget.h" MainWidget::MainWidget(QWidget *parent) : QWidget(parent), settings("TurnMeOn", "SerialAsst") { //初始化各参数列表 BaudrateList<<"256000"<<"230400"<<"128000"<<"115200"<<"76800"<<"57600" <<"43000"<<"38400"<<"19200"<<"14400"<<"9600"<<"4800"<<"2400"<<"1200"; StopbitsList<<"1"<<"1.5"<<"2"; DatabitsList<<"8"<<"7"<<"6"<<"5"; ParityList<addItems(BaudrateList); BaudrateBox->setCurrentIndex(settings.value("Baud rate", 0).toInt()); StopbitsBox = new QComboBox(); StopbitsBox->addItems(StopbitsList); StopbitsBox->setCurrentIndex(settings.value("Stop bits", 0).toInt()); DatabitsBox = new QComboBox(); DatabitsBox->addItems(DatabitsList); DatabitsBox->setCurrentIndex(settings.value("Data bits", 0).toInt()); ParityBox = new QComboBox(); ParityBox->addItems(ParityList); ParityBox->setCurrentIndex(settings.value("Parity", 0).toInt()); //初始化label BaudrateLabel = new QLabel(tr("波特率")); StopbitsLabel = new QLabel(tr("停止位")); DatabitsLabel = new QLabel(tr("数据位")); ParityLabel = new QLabel(tr("校验位")); //发送与接受区域 RecvArea = new QTextEdit(); RecvArea->setReadOnly(true); QPalette pal; pal.setColor(QPalette::Base, Qt::black); pal.setColor(QPalette::Text, Qt::green); RecvArea->setPalette(pal); SendArea = new QTextEdit(); RecvArea->setFont(QFont(tr("Microsoft YaHei UI"), 10)); SendArea->setFont(QFont(tr("Microsoft YaHei UI Light"), 12)); SendArea->installEventFilter(this); //按钮 OpenButton = new QPushButton(tr("打开串口")); SendButton = new QPushButton(tr("发送")); SendButton->setDisabled(true); SendButton->setToolTip(tr("Ctrl+Enter")); ClearButton = new QPushButton(tr("清除接收")); connect(OpenButton, QPushButton::clicked, this, OpenSerial); connect(SendButton, QPushButton::clicked, this, SendContent); connect(ClearButton, QPushButton::clicked, this, ClearRecv); //复选框 NewLineBox = new QCheckBox(tr("发送新行")); TimerBox = new QCheckBox(tr("定时发送")); HexSend = new QCheckBox(tr("发送16进制")); HexRecv = new QCheckBox(tr("接收16进制")); HexSend->setToolTip(tr("以空格作为间隔符, \n非法字符及其后面的字符将被忽略")); connect(NewLineBox, QCheckBox::stateChanged, this, detNewLine); connect(TimerBox, QCheckBox::stateChanged, this, ControlSendTimer); connect(HexSend, QCheckBox::stateChanged, this, detHex); connect(HexRecv, QCheckBox::stateChanged, this, detRecvHex); //spinbox TimerSpin = new QSpinBox(); TimerSpin->setSuffix(tr(" ms")); TimerSpin->setMaximum(1000000); TimerSpin->setValue(1000); connect(TimerSpin, static_cast(&QSpinBox::valueChanged), this, changeSendTimer); //初始化布局 cvlayout = new QVBoxLayout(); cvlayout->addWidget(RecvArea, 7); cvlayout->addWidget(SendArea, 2); hlayout = new QHBoxLayout(); hlayout->addWidget(HexSend); hlayout->addWidget(NewLineBox, Qt::AlignRight); hlayout->addWidget(TimerBox, Qt::AlignRight); hlayout->addWidget(TimerSpin); hlayout->addWidget(SendButton); rvlayout = new QVBoxLayout(); rvlayout->addWidget(ClearButton); rvlayout->addWidget(HexRecv); layout = new QGridLayout(this); layout->addWidget(COMBox, 0, 0, 1, 2); layout->addWidget(BaudrateLabel, 1, 0); layout->addWidget(StopbitsLabel, 2, 0); layout->addWidget(DatabitsLabel, 3, 0); layout->addWidget(ParityLabel, 4, 0); layout->addWidget(BaudrateBox, 1, 1); layout->addWidget(StopbitsBox, 2, 1); layout->addWidget(DatabitsBox, 3, 1); layout->addWidget(ParityBox, 4, 1); layout->addWidget(OpenButton, 5, 1); layout->addLayout(hlayout, 5, 2); // layout->addWidget(SendButton, 5, 2, Qt::AlignRight); layout->addLayout(cvlayout, 0, 2, 5, 1); // layout->addWidget(ClearButton, 0, 3, Qt::AlignLeft); layout->addLayout(rvlayout, 0, 3); layout->setColumnStretch(0, 1); layout->setColumnStretch(1, 1); layout->setColumnStretch(2, 4); layout->setColumnStretch(3, 1); setLayout(layout); //计时器 初始化 CheckTimer = new QTimer(this); CheckTimer->start(1000); SendTimer = new QTimer(this); connect(CheckTimer, QTimer::timeout, this, CheckSerials); connect(SendTimer, QTimer::timeout, SendButton, QPushButton::click); //初始化串口列表 CheckSerials(); //开始串口进程 serialController = new SerialController; serialController->moveToThread(&SerialThr); SerialThr.start(); connect(this, requestOpen, serialController, SerialController::openSerial); connect(this, requestClose, serialController, SerialController::closeSerial); connect(serialController, SerialController::openSuccess, this, serialOpened); connect(serialController, SerialController::openFailed, this, serialNotOpened); connect(serialController, SerialController::closeSuccess, this, serialClosed); connect(this, setBaudRate, serialController, SerialController::getBaudrate); connect(this, setStopBits, serialController, SerialController::getStopbits); connect(this, setDataBits, serialController, SerialController::getDatabits); connect(this, setParity, serialController, SerialController::getParity); connect(BaudrateBox, QComboBox::currentTextChanged, serialController, SerialController::getBaudrate); connect(StopbitsBox, QComboBox::currentTextChanged, serialController, SerialController::getStopbits); connect(DatabitsBox, QComboBox::currentTextChanged, serialController, SerialController::getDatabits); connect(ParityBox, QComboBox::currentTextChanged, serialController, SerialController::getParity); connect(this, sendData, serialController, SerialController::writeData); connect(serialController, SerialController::recvData, this, getRecv); } void MainWidget::CheckSerials() { emit sendDateTime(QDateTime::currentDateTime().toString()); QList SerialList = QSerialPortInfo::availablePorts(); if(!SerialList.isEmpty()) { QStringList TmpComList; for(QSerialPortInfo serial : SerialList) { TmpComList<setDisabled(false); COMBox->clear(); COMBox->addItems(COMList); OpenButton->setDisabled(false); } } else { COMBox->clear(); COMList.clear(); COMBox->addItem(tr("(空)")); COMBox->setDisabled(true); OpenButton->setDisabled(true); emit CloseSerial(); } } MainWidget::~MainWidget() { SerialThr.terminate(); settings.setValue("Baud rate", BaudrateBox->currentIndex()); settings.setValue("Stop bits", StopbitsBox->currentIndex()); settings.setValue("Data bits", DatabitsBox->currentIndex()); settings.setValue("Parity", ParityBox->currentIndex()); } void MainWidget::serialOpened() { OpenButton->setText(tr("关闭串口")); emit sendStatus(QString(/*tr("串口已打开") + */COMBox->currentText())); COMBox->setDisabled(true); SendButton->setDisabled(false); disconnect(OpenButton, QPushButton::clicked, this, OpenSerial); connect(OpenButton, QPushButton::clicked, this, CloseSerial); } void MainWidget::serialNotOpened() { emit sendStatus(tr("串口打开失败")); } void MainWidget::serialClosed() { OpenButton->setText(tr("打开串口")); COMBox->setDisabled(false); SendButton->setDisabled(true); disconnect(OpenButton, QPushButton::clicked, this, CloseSerial); connect(OpenButton, QPushButton::clicked, this, OpenSerial); emit sendStatus(tr("串口已关闭")); } void MainWidget::getRecv(QByteArray recv) { RecvArea->moveCursor(QTextCursor::End); if(!isRecvHex) RecvArea->textCursor().insertText(QString::fromLocal8Bit(recv)); else { RecvArea->textCursor().insertText(QString(recv.toHex())+tr(" ")); } } void MainWidget::OpenSerial() { QString portName = COMBox->currentText().split(' ')[0]; emit requestOpen(portName); emit setBaudRate(BaudrateBox->currentText()); emit setStopBits(StopbitsBox->currentText()); emit setDataBits(DatabitsBox->currentText()); emit setParity(ParityBox->currentText()); } void MainWidget::CloseSerial() { emit requestClose(); } void MainWidget::ClearRecv() { RecvArea->clear(); } void MainWidget::detNewLine(int state) { if(state==2) isSendNewLine = true; else if(state == 0) isSendNewLine = false; } void MainWidget::ControlSendTimer(int state) { if(state == 0) SendTimer->stop(); else if(state == 2) SendTimer->start(TimerSpin->value()); } void MainWidget::changeSendTimer() { ControlSendTimer(TimerBox->checkState()); } void MainWidget::detHex(int state) { if(state == 2) { isSendHex = true; SendArea->setText(SendArea->toPlainText().toLocal8Bit().toHex(' ')); } else if(state == 0) { isSendHex = false; QString tmpstr = SendArea->toPlainText(); SendArea->clear(); SendArea->setText(HexStringToString(tmpstr)); } } void MainWidget::detRecvHex(int state) { if(state == 2) { isRecvHex = true; RecvArea->setText(RecvArea->toPlainText().toLocal8Bit().toHex(' ')); RecvArea->moveCursor(QTextCursor::End); RecvArea->insertPlainText(tr(" ")); } else if(state == 0) { isRecvHex = false; QString tmpstr = RecvArea->toPlainText(); RecvArea->clear(); RecvArea->setText(HexStringToString(tmpstr)); } } QString MainWidget::HexStringToString(QString hexstr) { QStringList list = hexstr.split(' '); QByteArray bit; foreach (QString str, list) { if(!str.isEmpty()) bit.append(str.toInt(nullptr, 16)); } return QString::fromLocal8Bit(bit); } void MainWidget::SendContent() { QString content = SendArea->toPlainText(); if(isSendHex) content = HexStringToString(content); if(isSendNewLine) content += "\r\n"; emit sendData(content); } bool MainWidget::eventFilter(QObject *watched, QEvent *event) { if(watched==SendArea&&event->type()==QEvent::KeyPress) { QKeyEvent *e = (QKeyEvent*)event; if(e->modifiers()==Qt::ControlModifier) { switch (e->key()) { case Qt::Key_Enter: case Qt::Key_Return: SendButton->click(); break; default: break; } } } return QWidget::eventFilter(watched, event); }