Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6dd3ba0731 | ||
|
|
ae928e210b | ||
|
|
5007c383c8 | ||
|
|
0511050cd4 | ||
|
|
635b515a70 | ||
|
|
b29bd9e878 | ||
|
|
e931c365a9 | ||
|
|
e289e0a9cb | ||
|
|
e380ab24fa | ||
|
|
c3f6dfe736 | ||
|
|
abfea0101a | ||
|
|
aa8ea39c9e | ||
|
|
843321e1a5 | ||
|
|
eefa78a243 | ||
|
|
bab4d23f57 | ||
|
|
58ce96c767 | ||
|
|
f7f507d868 | ||
|
|
7d8818bfc7 | ||
|
|
efaf6dfb83 | ||
|
|
97a30114d3 | ||
|
|
fc79c2f327 | ||
|
|
b690aef900 | ||
|
|
0a1d127390 | ||
|
|
1e2fad8cbe | ||
|
|
7ff5fc91a6 | ||
|
|
9044a30873 |
@@ -0,0 +1,81 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(SerialAsst VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS SerialPort)
|
||||
|
||||
set(PROJECT_SOURCES
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h
|
||||
mainwidget.cpp mainwidget.h
|
||||
serialcontroller.cpp serialcontroller.h
|
||||
)
|
||||
|
||||
set(app_icon_resource_windows "${CMAKE_CURRENT_SOURCE_DIR}/serialasst.rc")
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_executable(SerialAsst
|
||||
MANUAL_FINALIZATION
|
||||
${PROJECT_SOURCES}
|
||||
${app_icon_resource_windows}
|
||||
resource.qrc
|
||||
)
|
||||
# Define target properties for Android with Qt 6 as:
|
||||
# set_property(TARGET qtCmakeTemplate APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
||||
else()
|
||||
if(ANDROID)
|
||||
add_library(SerialAsst SHARED
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# Define properties for Android with Qt 5 after find_package() calls as:
|
||||
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||
else()
|
||||
add_executable(SerialAsst
|
||||
${PROJECT_SOURCES}
|
||||
${app_icon_resource_windows}
|
||||
resource.qrc
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(SerialAsst PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
target_link_libraries(SerialAsst PRIVATE Qt${QT_VERSION_MAJOR}::SerialPort)
|
||||
|
||||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
||||
# If you are developing for iOS or macOS you should consider setting an
|
||||
# explicit, fixed bundle identifier manually though.
|
||||
if(${QT_VERSION} VERSION_LESS 6.1.0)
|
||||
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.SerialAsst)
|
||||
endif()
|
||||
set_target_properties(SerialAsst PROPERTIES
|
||||
${BUNDLE_ID_OPTION}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||
MACOSX_BUNDLE TRUE
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS SerialAsst
|
||||
BUNDLE DESTINATION .
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_finalize_executable(SerialAsst)
|
||||
endif()
|
||||
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -1,44 +0,0 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2018-01-16T00:25:36
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui serialport
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = SerialAsst
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has 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 \
|
||||
serialcontroller.cpp \
|
||||
mainwidget.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
serialcontroller.h \
|
||||
mainwidget.h \
|
||||
mainwindow.h
|
||||
|
||||
RESOURCES += \
|
||||
resource.qrc
|
||||
|
||||
DISTFILES += \
|
||||
serialasst.rc
|
||||
|
||||
RC_FILE += \
|
||||
serialasst.rc
|
||||
@@ -0,0 +1,4 @@
|
||||
title: SerialAsst
|
||||
description: SerialAsst is a simple tools for testing serial ports.
|
||||
show_downloads: true
|
||||
theme: jekyll-theme-cayman
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 750 B |
@@ -1,10 +1,19 @@
|
||||
#include <QApplication>
|
||||
#include <QOperatingSystemVersion>
|
||||
#include <QtGlobal>
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows) {
|
||||
QApplication::setFont(QFont{"Segoe UI", 10});
|
||||
}
|
||||
QApplication a(argc, argv);
|
||||
a.setWindowIcon(QIcon(QString(":/pic/icon/icon.png")));
|
||||
a.setStyle("fusion");
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
|
||||
+302
-133
@@ -1,17 +1,36 @@
|
||||
#include "mainwidget.h"
|
||||
#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<<tr("无")<<tr("奇校验")<<tr("偶校验");
|
||||
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 << tr("无") << tr("奇校验") << tr("偶校验");
|
||||
FlowControlList << tr("无") << tr("硬件") << tr("软件");
|
||||
|
||||
//初始化ComboBox
|
||||
COMBox = new QComboBox();
|
||||
COMBox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
|
||||
BaudrateBox = new QComboBox();
|
||||
BaudrateBox->addItems(BaudrateList);
|
||||
BaudrateBox->setCurrentIndex(settings.value("Baud rate", 0).toInt());
|
||||
@@ -24,23 +43,34 @@ MainWidget::MainWidget(QWidget *parent)
|
||||
ParityBox = new QComboBox();
|
||||
ParityBox->addItems(ParityList);
|
||||
ParityBox->setCurrentIndex(settings.value("Parity", 0).toInt());
|
||||
FlowControlBox = new QComboBox();
|
||||
FlowControlBox->addItems(FlowControlList);
|
||||
FlowControlBox->setCurrentIndex(settings.value("Flow Control", 0).toInt());
|
||||
|
||||
//初始化label
|
||||
COMLabel = new QLabel(tr("串口号"));
|
||||
BaudrateLabel = new QLabel(tr("波特率"));
|
||||
StopbitsLabel = new QLabel(tr("停止位"));
|
||||
DatabitsLabel = new QLabel(tr("数据位"));
|
||||
ParityLabel = new QLabel(tr("校验位"));
|
||||
FlowControlLabel = new QLabel(tr("流控"));
|
||||
|
||||
//发送与接受区域
|
||||
RecvArea = new QTextEdit();
|
||||
RecvArea = new QPlainTextEdit();
|
||||
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 = new QPlainTextEdit();
|
||||
|
||||
QFont areaFont = SendArea->font();
|
||||
areaFont.setPointSize(11);
|
||||
SendArea->setFont(areaFont);
|
||||
areaFont.setPointSize(11);
|
||||
RecvArea->setFont(areaFont);
|
||||
// RecvArea->setFont(QFont(tr("Microsoft YaHei UI"), 10));
|
||||
// SendArea->setFont(QFont(tr("Microsoft YaHei UI Light"), 12));
|
||||
SendArea->installEventFilter(this);
|
||||
|
||||
//按钮
|
||||
@@ -48,11 +78,13 @@ MainWidget::MainWidget(QWidget *parent)
|
||||
SendButton = new QPushButton(tr("发送"));
|
||||
SendButton->setDisabled(true);
|
||||
SendButton->setToolTip(tr("Ctrl+Enter"));
|
||||
ClearButton = new QPushButton(tr("清除接收"));
|
||||
ClearRecvButton = new QPushButton(tr("清除接收"));
|
||||
ClearSendButton = new QPushButton(tr("清除发送"));
|
||||
|
||||
connect(OpenButton, QPushButton::clicked, this, OpenSerial);
|
||||
connect(SendButton, QPushButton::clicked, this, SendContent);
|
||||
connect(ClearButton, QPushButton::clicked, this, ClearRecv);
|
||||
connect(OpenButton, &QPushButton::clicked, this, &MainWidget::OpenSerial);
|
||||
connect(SendButton, &QPushButton::clicked, this, &MainWidget::SendContent);
|
||||
connect(ClearRecvButton, &QPushButton::clicked, this, &MainWidget::ClearRecv);
|
||||
connect(ClearSendButton, &QPushButton::clicked, this, &MainWidget::ClearSend);
|
||||
|
||||
//复选框
|
||||
NewLineBox = new QCheckBox(tr("发送新行"));
|
||||
@@ -61,174 +93,226 @@ MainWidget::MainWidget(QWidget *parent)
|
||||
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);
|
||||
// RTS和 DTR复选框
|
||||
RTSBox = new QCheckBox(tr("RTS"));
|
||||
DTRBox = new QCheckBox(tr("DTR"));
|
||||
|
||||
//spinbox
|
||||
flowControlLayout = new QHBoxLayout();
|
||||
flowControlLayout->addWidget(RTSBox);
|
||||
flowControlLayout->addWidget(DTRBox);
|
||||
|
||||
//绑定复选框信号
|
||||
connect(NewLineBox, &QCheckBox::stateChanged, this, &MainWidget::detNewLine);
|
||||
connect(TimerBox, &QCheckBox::stateChanged, this, &MainWidget::ControlSendTimer);
|
||||
connect(HexSend, &QCheckBox::stateChanged, this, &MainWidget::detHex);
|
||||
connect(HexRecv, &QCheckBox::stateChanged, this, &MainWidget::detRecvHex);
|
||||
connect(RTSBox, &QCheckBox::stateChanged, this, &MainWidget::RTSControl);
|
||||
connect(DTRBox, &QCheckBox::stateChanged, this, &MainWidget::DTRControl);
|
||||
|
||||
//定时发送spinbox
|
||||
TimerSpin = new QSpinBox();
|
||||
TimerSpin->setSuffix(tr(" ms"));
|
||||
TimerSpin->setMaximum(1000000);
|
||||
TimerSpin->setValue(1000);
|
||||
|
||||
//valueChanged有多个重载
|
||||
connect(TimerSpin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
|
||||
this, changeSendTimer);
|
||||
this, &MainWidget::changeSendTimer);
|
||||
|
||||
//初始化布局
|
||||
leftLlayout = new QFormLayout();
|
||||
leftLlayout->addRow(BaudrateLabel, BaudrateBox);
|
||||
leftLlayout->addRow(StopbitsLabel, StopbitsBox);
|
||||
leftLlayout->addRow(DatabitsLabel, DatabitsBox);
|
||||
leftLlayout->addRow(ParityLabel, ParityBox);
|
||||
leftLlayout->addRow(FlowControlLabel, FlowControlBox);
|
||||
leftLlayout->addRow(flowControlLayout);
|
||||
leftLlayout->addRow(COMLabel, COMBox);
|
||||
leftLlayout->addRow(OpenButton);
|
||||
leftLlayout->setAlignment(OpenButton, Qt::AlignVCenter);
|
||||
leftLlayout->setContentsMargins(15, 25, 15, 25);
|
||||
leftLlayout->setHorizontalSpacing(20);
|
||||
leftLlayout->setVerticalSpacing(20);
|
||||
|
||||
paramGroup = new QGroupBox(tr("串口参数"));
|
||||
paramGroup->setLayout(leftLlayout);
|
||||
paramGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
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);
|
||||
bottomLayout = new QHBoxLayout();
|
||||
bottomLayout->addWidget(ClearSendButton, 0, Qt::AlignLeft);
|
||||
bottomLayout->addWidget(HexSend);
|
||||
bottomLayout->addWidget(NewLineBox, 0, Qt::AlignLeft);
|
||||
bottomLayout->addWidget(TimerBox, 0, Qt::AlignRight);
|
||||
bottomLayout->addWidget(TimerSpin, 1, Qt::AlignLeft);
|
||||
bottomLayout->addWidget(SendButton, 0, Qt::AlignRight);
|
||||
|
||||
rightLayout = new QVBoxLayout();
|
||||
rightLayout->addWidget(ClearRecvButton, 0, Qt::AlignCenter);
|
||||
rightLayout->addWidget(HexRecv);
|
||||
|
||||
centralLayout = new QGridLayout(this);
|
||||
|
||||
centralLayout->addWidget(paramGroup, 0, 0, 2, 1);
|
||||
centralLayout->addLayout(bottomLayout, 1, 1);
|
||||
centralLayout->addLayout(cvlayout, 0, 1, 1, 1);
|
||||
centralLayout->addLayout(rightLayout, 0, 2, Qt::AlignTop);
|
||||
|
||||
centralLayout->setColumnMinimumWidth(0, 150);
|
||||
centralLayout->setColumnMinimumWidth(2, 100);
|
||||
|
||||
centralLayout->setColumnStretch(0, 0);
|
||||
centralLayout->setColumnStretch(1, 2);
|
||||
centralLayout->setColumnStretch(2, 0);
|
||||
|
||||
setLayout(centralLayout);
|
||||
|
||||
//计时器 初始化
|
||||
CheckTimer = new QTimer(this);
|
||||
CheckTimer->start(1000);
|
||||
SendTimer = new QTimer(this);
|
||||
connect(CheckTimer, QTimer::timeout, this, CheckSerials);
|
||||
connect(SendTimer, QTimer::timeout, SendButton, QPushButton::click);
|
||||
connect(CheckTimer, &QTimer::timeout, this, &MainWidget::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);
|
||||
serialController = new SerialController(this);
|
||||
|
||||
//connect开关串口控制信号 以及是否成功的返回信号
|
||||
connect(this, &MainWidget::requestOpen, serialController, &SerialController::openSerial);
|
||||
connect(this, &MainWidget::requestClose, serialController, &SerialController::closeSerial);
|
||||
connect(serialController, &SerialController::openSuccess, this, &MainWidget::serialOpened);
|
||||
connect(serialController, &SerialController::openFailed, this, &MainWidget::serialNotOpened);
|
||||
connect(serialController, &SerialController::closeSuccess, this, &MainWidget::serialClosed);
|
||||
//connect波特率等参数的控制信号
|
||||
connect(this, &MainWidget::setBaudRate, serialController, &SerialController::getBaudrate);
|
||||
connect(this, &MainWidget::setStopBits, serialController, &SerialController::getStopbits);
|
||||
connect(this, &MainWidget::setDataBits, serialController, &SerialController::getDatabits);
|
||||
connect(this, &MainWidget::setParity, serialController, &SerialController::getParity);
|
||||
connect(this, &MainWidget::setFlowControl, serialController, &SerialController::getFlowControl);
|
||||
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, &MainWidget::changeRTS, serialController, &SerialController::contrloRTS);
|
||||
connect(this, &MainWidget::changeDTR, serialController, &SerialController::controlDTR);
|
||||
connect(this, &MainWidget::sendData, serialController, &SerialController::writeData);
|
||||
connect(serialController, &SerialController::recvData, this, &MainWidget::getRecv);
|
||||
}
|
||||
|
||||
void MainWidget::CheckSerials()
|
||||
{
|
||||
emit sendDateTime(QDateTime::currentDateTime().toString());
|
||||
//不断检查可用串口列表,并与当前列表进行比较,若发生变化则重新生成列表
|
||||
emit sendDateTime(QDateTime::currentDateTime().toString(Qt::ISODate)); //更新状态栏时间
|
||||
|
||||
QList<QSerialPortInfo> SerialList = QSerialPortInfo::availablePorts();
|
||||
if(!SerialList.isEmpty())
|
||||
{
|
||||
QStringList TmpComList;
|
||||
for(QSerialPortInfo serial : SerialList)
|
||||
{
|
||||
TmpComList<<serial.portName() + " " + serial.description();
|
||||
|
||||
if (!SerialList.isEmpty()) {
|
||||
QStringList TmpComList, TmpPortNameList, TmpDesList;
|
||||
for (QSerialPortInfo &serial : SerialList) {
|
||||
TmpComList << serial.portName() + " " + serial.description();
|
||||
TmpPortNameList << serial.portName();
|
||||
TmpDesList << serial.description();
|
||||
}
|
||||
if(COMList != TmpComList)
|
||||
if (COMList != TmpComList)
|
||||
{
|
||||
//TODO: 可用串口发生改变却不为空时,保持串口打开状态,及其他细节的处理
|
||||
//只在串口发生变化时刷新ComboBox
|
||||
COMList = TmpComList;
|
||||
PortNameList = TmpPortNameList;
|
||||
DescList = TmpDesList;
|
||||
COMBox->setDisabled(false);
|
||||
COMBox->clear();
|
||||
// COMBox->addItems(PortNameList);
|
||||
COMBox->addItems(COMList);
|
||||
|
||||
OpenButton->setDisabled(false);
|
||||
for (int i = 0; i < COMList.count(); i++) //为串口列表增加ToolTip
|
||||
{
|
||||
COMBox->setItemData(i, DescList[i], Qt::ToolTipRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
} else //可用串口为空时发送关闭串口信号
|
||||
{
|
||||
COMBox->clear();
|
||||
COMList.clear();
|
||||
COMBox->addItem(tr("(空)"));
|
||||
COMBox->setDisabled(true);
|
||||
OpenButton->setDisabled(true);
|
||||
emit CloseSerial();
|
||||
CloseSerial();
|
||||
isOpened = false;
|
||||
}
|
||||
}
|
||||
|
||||
MainWidget::~MainWidget()
|
||||
{
|
||||
SerialThr.terminate();
|
||||
// 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());
|
||||
settings.setValue("Flow Control", FlowControlBox->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);
|
||||
isOpened = true;
|
||||
int portIndex = COMBox->currentIndex();
|
||||
emit sendStatus(QString(PortNameList[portIndex] + tr(" ") + DescList[portIndex]));
|
||||
//串口关闭时无法设置RTS,DTR信号(但此时checkbox仍然是可操作的),串口打开时发送stateChanged信号来应用改变
|
||||
emit RTSBox->stateChanged(RTSBox->checkState());
|
||||
emit DTRBox->stateChanged(DTRBox->checkState());
|
||||
//相应控件可用性做出改变(setDisabled)
|
||||
ActionAttachToSerial(true);
|
||||
}
|
||||
|
||||
void MainWidget::serialNotOpened()
|
||||
{
|
||||
//设置状态栏 并发出警告音
|
||||
//TODO: 此处应有更容易察觉的提示
|
||||
emit sendStatus(tr("串口打开失败"));
|
||||
QApplication::beep();
|
||||
}
|
||||
|
||||
void MainWidget::serialClosed()
|
||||
{
|
||||
OpenButton->setText(tr("打开串口"));
|
||||
COMBox->setDisabled(false);
|
||||
SendButton->setDisabled(true);
|
||||
disconnect(OpenButton, QPushButton::clicked, this, CloseSerial);
|
||||
connect(OpenButton, QPushButton::clicked, this, OpenSerial);
|
||||
isOpened = false;
|
||||
//相应控件可用性做出改变(setDisabled)
|
||||
ActionAttachToSerial(false);
|
||||
emit sendStatus(tr("串口已关闭"));
|
||||
}
|
||||
|
||||
void MainWidget::getRecv(QByteArray recv)
|
||||
void MainWidget::getRecv(const QByteArray &recv)
|
||||
{
|
||||
RecvArea->moveCursor(QTextCursor::End);
|
||||
if(!isRecvHex)
|
||||
//需要时将受到的数据进行16进制转换
|
||||
//TODO: 支持更多编码(可选择)
|
||||
if (!isRecvHex)
|
||||
RecvArea->textCursor().insertText(QString::fromLocal8Bit(recv));
|
||||
else
|
||||
{
|
||||
RecvArea->textCursor().insertText(QString(recv.toHex())+tr(" "));
|
||||
if (!RecvArea->toPlainText().isEmpty())
|
||||
RecvArea->textCursor().insertText(QChar(HEX_SEPARATOR));
|
||||
RecvArea->textCursor().insertText(QString(recv.toHex(HEX_SEPARATOR)));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::OpenSerial()
|
||||
{
|
||||
QString portName = COMBox->currentText().split(' ')[0];
|
||||
emit requestOpen(portName);
|
||||
QString portName = COMBox->currentText();
|
||||
emit setBaudRate(BaudrateBox->currentText());
|
||||
emit setStopBits(StopbitsBox->currentText());
|
||||
emit setDataBits(DatabitsBox->currentText());
|
||||
emit setParity(ParityBox->currentText());
|
||||
emit setFlowControl(FlowControlBox->currentText());
|
||||
emit requestOpen(portName);
|
||||
}
|
||||
|
||||
void MainWidget::CloseSerial()
|
||||
@@ -241,19 +325,24 @@ void MainWidget::ClearRecv()
|
||||
RecvArea->clear();
|
||||
}
|
||||
|
||||
void MainWidget::ClearSend()
|
||||
{
|
||||
SendArea->clear();
|
||||
}
|
||||
|
||||
void MainWidget::detNewLine(int state)
|
||||
{
|
||||
if(state==2)
|
||||
if (state == 2)
|
||||
isSendNewLine = true;
|
||||
else if(state == 0)
|
||||
else if (state == 0)
|
||||
isSendNewLine = false;
|
||||
}
|
||||
|
||||
void MainWidget::ControlSendTimer(int state)
|
||||
{
|
||||
if(state == 0)
|
||||
if (state == 0)
|
||||
SendTimer->stop();
|
||||
else if(state == 2)
|
||||
else if (state == 2)
|
||||
SendTimer->start(TimerSpin->value());
|
||||
}
|
||||
|
||||
@@ -264,66 +353,146 @@ void MainWidget::changeSendTimer()
|
||||
|
||||
void MainWidget::detHex(int state)
|
||||
{
|
||||
if(state == 2)
|
||||
//TODO: 换行也可以作为16进制的分隔符
|
||||
if (state == 2)
|
||||
{
|
||||
isSendHex = true;
|
||||
SendArea->setText(SendArea->toPlainText().toLocal8Bit().toHex(' '));
|
||||
// SendArea->setPlainText(SendArea->toPlainText().toLocal8Bit().toHex(' '));
|
||||
}
|
||||
else if(state == 0)
|
||||
else if (state == 0)
|
||||
{
|
||||
isSendHex = false;
|
||||
QString tmpstr = SendArea->toPlainText();
|
||||
SendArea->clear();
|
||||
SendArea->setText(HexStringToString(tmpstr));
|
||||
// QString tmpstr = SendArea->toPlainText();
|
||||
// SendArea->clear();
|
||||
// SendArea->setPlainText(HexStringToString(tmpstr));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::detRecvHex(int state)
|
||||
{
|
||||
if(state == 2)
|
||||
if (state == 2)
|
||||
{
|
||||
isRecvHex = true;
|
||||
RecvArea->setText(RecvArea->toPlainText().toLocal8Bit().toHex(' '));
|
||||
RecvArea->moveCursor(QTextCursor::End);
|
||||
RecvArea->insertPlainText(tr(" "));
|
||||
// RecvArea->setPlainText(RecvArea->toPlainText().toLocal8Bit().toHex(' '));
|
||||
// RecvArea->moveCursor(QTextCursor::End);
|
||||
// RecvArea->insertPlainText(tr(" "));
|
||||
}
|
||||
else if(state == 0)
|
||||
else if (state == 0)
|
||||
{
|
||||
isRecvHex = false;
|
||||
QString tmpstr = RecvArea->toPlainText();
|
||||
RecvArea->clear();
|
||||
RecvArea->setText(HexStringToString(tmpstr));
|
||||
// QString tmpstr = RecvArea->toPlainText();
|
||||
// RecvArea->clear();
|
||||
// RecvArea->setPlainText(HexStringToString(tmpstr));
|
||||
}
|
||||
}
|
||||
|
||||
QString MainWidget::HexStringToString(QString hexstr)
|
||||
void MainWidget::RTSControl(int state)
|
||||
{
|
||||
QStringList list = hexstr.split(' ');
|
||||
QByteArray bit;
|
||||
foreach (QString str, list)
|
||||
if(isOpened)
|
||||
{
|
||||
if(!str.isEmpty())
|
||||
bit.append(str.toInt(nullptr, 16));
|
||||
if(state == 2)
|
||||
emit changeRTS(true);
|
||||
else if(state == 0)
|
||||
emit changeRTS(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::DTRControl(int state)
|
||||
{
|
||||
if(isOpened)
|
||||
{
|
||||
if(state == 2)
|
||||
emit changeDTR(true);
|
||||
else if(state == 0)
|
||||
emit changeDTR(false);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray MainWidget::HexStringToString(const QString &hexstr)
|
||||
{
|
||||
//将内容为16进制字符串的string转换成16进制对应的内容
|
||||
QStringList list = hexstr.split(' ');
|
||||
QByteArray bytes;
|
||||
char currentByte{0};
|
||||
bool hasReadFirstChar = false;
|
||||
for (auto ch : hexstr) {
|
||||
auto ascii = ch.toLatin1();
|
||||
if (ch == ' ') { // 允许空格
|
||||
continue;
|
||||
}
|
||||
auto numHex = convertAsciiToHex(ascii);
|
||||
if (numHex < 0) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
if (!hasReadFirstChar) {
|
||||
currentByte += (numHex - '0') << 4;
|
||||
hasReadFirstChar = true;
|
||||
} else {
|
||||
currentByte += numHex;
|
||||
bytes.append(currentByte);
|
||||
hasReadFirstChar = false;
|
||||
currentByte = 0;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
char MainWidget::convertAsciiToHex(char ascii)
|
||||
{
|
||||
if (ascii >= '0' && ascii <= '9') {
|
||||
return ascii - '0';
|
||||
} else if (ascii >= 'a' && ascii <= 'f') {
|
||||
return 10 + ascii - 'a';
|
||||
} else if (ascii >= 'A' && ascii <= 'F') {
|
||||
return 10 + ascii - 'A';
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::ActionAttachToSerial(bool set)
|
||||
{
|
||||
//根据串口开关状态决定一些控件的可用性
|
||||
if(set)
|
||||
{
|
||||
OpenButton->setText(tr("关闭串口"));
|
||||
COMBox->setDisabled(true);
|
||||
SendButton->setDisabled(false);
|
||||
disconnect(OpenButton, &QPushButton::clicked, this, &MainWidget::OpenSerial);
|
||||
connect(OpenButton, &QPushButton::clicked, this, &MainWidget::CloseSerial);
|
||||
}
|
||||
else
|
||||
{
|
||||
OpenButton->setText(tr("打开串口"));
|
||||
COMBox->setDisabled(false);
|
||||
SendButton->setDisabled(true);
|
||||
disconnect(OpenButton, &QPushButton::clicked, this, &MainWidget::CloseSerial);
|
||||
connect(OpenButton, &QPushButton::clicked, this, &MainWidget::OpenSerial);
|
||||
}
|
||||
return QString::fromLocal8Bit(bit);
|
||||
}
|
||||
|
||||
void MainWidget::SendContent()
|
||||
{
|
||||
QString content = SendArea->toPlainText();
|
||||
if(isSendHex)
|
||||
content = HexStringToString(content);
|
||||
if(isSendNewLine)
|
||||
content += "\r\n";
|
||||
emit sendData(content);
|
||||
QByteArray bytes;
|
||||
if (isSendNewLine)
|
||||
content += "\n";
|
||||
if (isSendHex) {
|
||||
bytes = HexStringToString(content);
|
||||
} else {
|
||||
bytes = content.toLatin1();
|
||||
}
|
||||
|
||||
emit sendData(bytes);
|
||||
}
|
||||
|
||||
bool MainWidget::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if(watched==SendArea&&event->type()==QEvent::KeyPress)
|
||||
if (watched == SendArea && event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent *e = (QKeyEvent*)event;
|
||||
if(e->modifiers()==Qt::ControlModifier)
|
||||
QKeyEvent *e = reinterpret_cast<QKeyEvent *>(event);
|
||||
if (e->modifiers() == Qt::ControlModifier)
|
||||
{
|
||||
switch (e->key())
|
||||
{
|
||||
|
||||
+74
-61
@@ -1,85 +1,98 @@
|
||||
#ifndef MAINWIDGET_H
|
||||
#ifndef MAINWIDGET_H
|
||||
#define MAINWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QApplication>
|
||||
#include <QByteArray>
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDateTime>
|
||||
#include <QFormLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QTextEdit>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
#include <QSerialPortInfo>
|
||||
#include <QLabel>
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
#include <QThread>
|
||||
#include <QDateTime>
|
||||
#include <QByteArray>
|
||||
#include <QSettings>
|
||||
#include <QSpinBox>
|
||||
#include <QTextEdit>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include "serialcontroller.h"
|
||||
|
||||
|
||||
|
||||
class MainWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWidget(QWidget *parent = 0);
|
||||
void CheckSerials();
|
||||
~MainWidget();
|
||||
void SendContent();
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
MainWidget(QWidget *parent = 0);
|
||||
void CheckSerials();
|
||||
~MainWidget();
|
||||
void SendContent();
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
signals:
|
||||
void requestOpen(QString portName);
|
||||
void requestClose();
|
||||
void setBaudRate(QString baudrate);
|
||||
void setStopBits(QString stopbits);
|
||||
void setDataBits(QString databits);
|
||||
void setParity(QString parity);
|
||||
void sendData(QString content);
|
||||
void sendStatus(QString status); //更新statusbar
|
||||
void sendDateTime(QString datetime); //更新stastatusbar中的时间
|
||||
signals:
|
||||
void requestOpen(const QString &portName);
|
||||
void requestClose();
|
||||
void setBaudRate(const QString &baudrate);
|
||||
void setStopBits(const QString &stopbits);
|
||||
void setDataBits(const QString &databits);
|
||||
void setParity(const QString &parity);
|
||||
void setFlowControl(const QString &flowControl);
|
||||
void sendData(const QByteArray &content);
|
||||
void sendStatus(const QString &status); //更新statusbar
|
||||
void sendDateTime(const QString &datetime); //更新stastatusbar中的时间
|
||||
void changeRTS(bool set);
|
||||
void changeDTR(bool set);
|
||||
|
||||
public slots:
|
||||
void serialOpened(); //串口打开成功
|
||||
void serialNotOpened(); //串口打开失败
|
||||
void serialClosed(); //串口关闭
|
||||
void getRecv(QByteArray recv); //串口接受数据
|
||||
void OpenSerial();
|
||||
void CloseSerial();
|
||||
void ClearRecv();
|
||||
void detNewLine(int state); //处理发送新行
|
||||
void ControlSendTimer(int state);
|
||||
void changeSendTimer();
|
||||
void detHex(int state); //处理16进制发送
|
||||
void detRecvHex(int state); //处理16进制接收
|
||||
public slots:
|
||||
void serialOpened(); //串口打开成功
|
||||
void serialNotOpened(); //串口打开失败
|
||||
void serialClosed(); //串口关闭
|
||||
void getRecv(const QByteArray &recv); //串口接受数据
|
||||
void OpenSerial();
|
||||
void CloseSerial();
|
||||
void ClearRecv();
|
||||
void ClearSend();
|
||||
void detNewLine(int state); //处理发送新行
|
||||
void ControlSendTimer(int state);
|
||||
void changeSendTimer();
|
||||
void detHex(int state); //处理16进制发送
|
||||
void detRecvHex(int state); //处理16进制接收
|
||||
void RTSControl(int state);
|
||||
void DTRControl(int state);
|
||||
|
||||
private:
|
||||
QComboBox *COMBox, *BaudrateBox, *StopbitsBox, *DatabitsBox, *ParityBox;
|
||||
QStringList COMList, BaudrateList, StopbitsList, DatabitsList, ParityList;
|
||||
QLabel *BaudrateLabel, *StopbitsLabel, *DatabitsLabel, *ParityLabel;
|
||||
QGridLayout *layout;
|
||||
QVBoxLayout *cvlayout, *rvlayout;
|
||||
QHBoxLayout *hlayout;
|
||||
QTextEdit *RecvArea, *SendArea;
|
||||
QPushButton *OpenButton, *SendButton, *ClearButton;
|
||||
QCheckBox *NewLineBox, *TimerBox, *HexSend, *HexRecv;
|
||||
QSpinBox *TimerSpin;
|
||||
QTimer *CheckTimer, *SendTimer;
|
||||
SerialController *serialController;
|
||||
QThread SerialThr;
|
||||
QSettings settings;
|
||||
private:
|
||||
QComboBox *COMBox, *BaudrateBox, *StopbitsBox, *DatabitsBox, *ParityBox, *FlowControlBox;
|
||||
QStringList BaudrateList, StopbitsList, DatabitsList, ParityList, FlowControlList;
|
||||
QStringList COMList, PortNameList, DescList;
|
||||
QLabel *COMLabel, *BaudrateLabel, *StopbitsLabel, *DatabitsLabel, *ParityLabel, *FlowControlLabel;
|
||||
QGridLayout *centralLayout;
|
||||
QVBoxLayout *cvlayout, *rightLayout;
|
||||
QHBoxLayout *bottomLayout, *flowControlLayout;
|
||||
QFormLayout *leftLlayout;
|
||||
QGroupBox *paramGroup;
|
||||
QPlainTextEdit *RecvArea, *SendArea;
|
||||
QPushButton *OpenButton, *SendButton, *ClearRecvButton, *ClearSendButton;
|
||||
QCheckBox *NewLineBox, *TimerBox, *HexSend, *HexRecv, *RTSBox, *DTRBox;
|
||||
QSpinBox *TimerSpin;
|
||||
QTimer *CheckTimer, *SendTimer;
|
||||
SerialController *serialController;
|
||||
QSettings settings;
|
||||
|
||||
bool isSendNewLine = false;
|
||||
bool isSendHex = false;
|
||||
bool isRecvHex = false;
|
||||
static const char HEX_SEPARATOR{':'};
|
||||
|
||||
QString HexStringToString(QString hexstr); //解码16进制字符串
|
||||
bool isSendNewLine = false;
|
||||
bool isSendHex = false;
|
||||
bool isRecvHex = false;
|
||||
bool isOpened = false;
|
||||
|
||||
QByteArray HexStringToString(const QString &hexstr); //解码16进制字符串
|
||||
char convertAsciiToHex(char ascii);
|
||||
void ActionAttachToSerial(bool set);
|
||||
};
|
||||
|
||||
#endif // MAINWIDGET_H
|
||||
|
||||
+49
-5
@@ -1,18 +1,28 @@
|
||||
#include "mainwindow.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
|
||||
widget(new MainWidget(this))
|
||||
widget(new MainWidget(this)),
|
||||
menuBar(new QMenuBar(this)),
|
||||
statusbar(new QStatusBar(this))
|
||||
{
|
||||
statusbar = new QStatusBar(this);
|
||||
setMenuBar(menuBar);
|
||||
setStatusBar(statusbar);
|
||||
|
||||
aboutQtAct = new QAction(QIcon(":/pic/icon/qt-icon.png"), tr("&关于Qt"), this);
|
||||
aboutAct = new QAction(QIcon(":/pic/icon/about.png"), tr("&关于SerialAsst"), this);
|
||||
helpMenu = menuBar->addMenu(tr("帮助(&H)"));
|
||||
helpMenu->addAction(aboutQtAct);
|
||||
helpMenu->addAction(aboutAct);
|
||||
setCentralWidget(widget);
|
||||
statusbar->showMessage(tr("准备就绪"));
|
||||
connect(widget, MainWidget::sendStatus, this, setNewMsg);
|
||||
connect(widget, &MainWidget::sendStatus, this, &MainWindow::setNewMsg);
|
||||
timeLabel = new QLabel(statusbar);
|
||||
statusBar()->addPermanentWidget(timeLabel);
|
||||
timeLabel->setText(QDateTime::currentDateTime().toString());
|
||||
|
||||
connect(widget, MainWidget::sendDateTime, this, setDateTime);
|
||||
connect(aboutQtAct, &QAction::triggered, this, &MainWindow::showAboutQt);
|
||||
connect(aboutAct, &QAction::triggered, this, &MainWindow::showAbout);
|
||||
connect(widget, &MainWidget::sendDateTime, this, &MainWindow::setDateTime);
|
||||
resize(900, 600);
|
||||
}
|
||||
|
||||
@@ -25,3 +35,37 @@ void MainWindow::setDateTime(QString datetime)
|
||||
{
|
||||
timeLabel->setText(datetime);
|
||||
}
|
||||
|
||||
void MainWindow::showAboutQt()
|
||||
{
|
||||
QMessageBox *aboutQtWindow = new QMessageBox(this);
|
||||
aboutQtWindow->aboutQt(this);
|
||||
}
|
||||
|
||||
void MainWindow::showAbout()
|
||||
{
|
||||
QMessageBox *aboutWindow = new QMessageBox(this);
|
||||
aboutWindow->setStandardButtons(QMessageBox::Ok);
|
||||
aboutWindow->setText(tr("<h1>SerialAsst</h1>"
|
||||
"<p>Based on Qt ")
|
||||
+ QT_VERSION_STR + " (" + getCompilerVersion()
|
||||
+ tr(")</p>"
|
||||
"Source Code: <a "
|
||||
"href=\"https://github.com/c-my/SerialAsst\">https://github.com/c-my/"
|
||||
"SerialAsst</a><br/>"
|
||||
"Email: "
|
||||
"<address><a href=\"mailto:cmy1113@outlook.com?subject=SerialAsst "
|
||||
"Feedback\">cai.my@outlook.com</a>"
|
||||
"</address>"));
|
||||
aboutWindow->show();
|
||||
}
|
||||
|
||||
QString MainWindow::getCompilerVersion()
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
return tr("GCC ") + QString::number(__GNUC__)+tr(".")+QString::number(__GNUC_MINOR__)+tr(".")+QString::number(__GNUC_PATCHLEVEL__);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return tr("MSVC ") + QString::number(_MSC_FULL_VER);
|
||||
#endif
|
||||
}
|
||||
|
||||
+21
-11
@@ -1,27 +1,37 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QStatusBar>
|
||||
#include <QKeyEvent>
|
||||
#include <mainwidget.h>
|
||||
#include <QMainWindow>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QStatusBar>
|
||||
#include "mainwidget.h"
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void setNewMsg(QString msg);
|
||||
void setDateTime(QString datetime);
|
||||
void setNewMsg(QString msg); //设置状态栏信息
|
||||
void setDateTime(QString datetime); //设置状态栏时间
|
||||
void showAboutQt();
|
||||
void showAbout();
|
||||
|
||||
private:
|
||||
MainWidget *widget;
|
||||
QStatusBar *statusbar;
|
||||
QLabel *timeLabel;
|
||||
MainWidget *widget;
|
||||
QMenuBar *menuBar;
|
||||
QMenu *helpMenu;
|
||||
QAction *aboutQtAct, *aboutAct;
|
||||
QStatusBar *statusbar;
|
||||
QLabel *timeLabel;
|
||||
|
||||
QString getCompilerVersion();
|
||||
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/pic">
|
||||
<file>icon/icon.png</file>
|
||||
<file>icon/qt-icon.png</file>
|
||||
<file>icon/about.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
+43
-22
@@ -1,18 +1,19 @@
|
||||
#include "serialcontroller.h"
|
||||
#include "serialcontroller.h"
|
||||
|
||||
SerialController::SerialController(QObject *parent) : QObject(parent)
|
||||
{
|
||||
serial = new QSerialPort(this);
|
||||
connect(serial, QSerialPort::readyRead, this, handleRecv);
|
||||
connect(serial, &QSerialPort::readyRead, this, &SerialController::handleRecv);
|
||||
}
|
||||
|
||||
void SerialController::openSerial(QString name)
|
||||
void SerialController::openSerial(const QString &name)
|
||||
{
|
||||
serial->setPortName(name);
|
||||
if(serial->open(QIODevice::ReadWrite))
|
||||
serial->setPortName(name.split(" ").at(0));
|
||||
if (serial->open(QIODevice::ReadWrite))
|
||||
{
|
||||
//串口打开成功
|
||||
serial->setDataTerminalReady(false);
|
||||
serial->setDataTerminalReady(false);
|
||||
emit openSuccess();
|
||||
}
|
||||
else
|
||||
@@ -24,52 +25,62 @@ void SerialController::openSerial(QString name)
|
||||
|
||||
void SerialController::closeSerial()
|
||||
{
|
||||
if(serial->isOpen())
|
||||
if (serial->isOpen())
|
||||
{
|
||||
serial->close();
|
||||
emit closeSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
void SerialController::getBaudrate(QString baudrate)
|
||||
void SerialController::getBaudrate(const QString &baudrate)
|
||||
{
|
||||
serial->setBaudRate(baudrate.toInt());
|
||||
|
||||
}
|
||||
|
||||
void SerialController::getStopbits(QString stopbits)
|
||||
void SerialController::getStopbits(const QString &stopbits)
|
||||
{
|
||||
if(stopbits == "1")
|
||||
if (stopbits == "1")
|
||||
serial->setStopBits(QSerialPort::OneStop);
|
||||
else if(stopbits == "1.5")
|
||||
else if (stopbits == "1.5")
|
||||
serial->setStopBits(QSerialPort::OneAndHalfStop);
|
||||
else if(stopbits == "2")
|
||||
else if (stopbits == "2")
|
||||
serial->setStopBits(QSerialPort::TwoStop);
|
||||
}
|
||||
|
||||
void SerialController::getDatabits(QString databits)
|
||||
void SerialController::getDatabits(const QString &databits)
|
||||
{
|
||||
serial->setDataBits(QSerialPort::DataBits(databits.toInt()));
|
||||
}
|
||||
|
||||
void SerialController::getParity(QString parity)
|
||||
void SerialController::getParity(const QString &parity)
|
||||
{
|
||||
if(parity == tr("无"))
|
||||
if (parity == tr("无"))
|
||||
serial->setParity(QSerialPort::NoParity);
|
||||
|
||||
else if(parity == tr("奇校验"))
|
||||
else if (parity == tr("奇校验"))
|
||||
serial->setParity(QSerialPort::OddParity);
|
||||
|
||||
else if(parity == tr("偶校验"))
|
||||
else if (parity == tr("偶校验"))
|
||||
serial->setParity(QSerialPort::EvenParity);
|
||||
}
|
||||
|
||||
void SerialController::writeData(QString content)
|
||||
void SerialController::getFlowControl(const QString &flowControl)
|
||||
{
|
||||
if(serial->isWritable())
|
||||
{
|
||||
qint64 result = serial->write(content.toLocal8Bit().data());
|
||||
if(result == -1)
|
||||
if (flowControl == tr("无")) {
|
||||
serial->setFlowControl(QSerialPort::NoFlowControl);
|
||||
} else if (flowControl == tr("硬件")) {
|
||||
serial->setFlowControl(QSerialPort::HardwareControl);
|
||||
|
||||
} else if (flowControl == tr("软件")) {
|
||||
serial->setFlowControl(QSerialPort::SoftwareControl);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialController::writeData(const QByteArray &content)
|
||||
{
|
||||
if (serial->isWritable()) {
|
||||
qint64 result = serial->write(content);
|
||||
if (result == -1)
|
||||
emit writeFailed();
|
||||
else
|
||||
emit writeSuccess(result);
|
||||
@@ -81,3 +92,13 @@ void SerialController::handleRecv()
|
||||
QByteArray data = serial->readAll();
|
||||
emit recvData(data);
|
||||
}
|
||||
|
||||
void SerialController::contrloRTS(bool set)
|
||||
{
|
||||
serial->setRequestToSend(set);
|
||||
}
|
||||
|
||||
void SerialController::controlDTR(bool set)
|
||||
{
|
||||
serial->setDataTerminalReady(set);
|
||||
}
|
||||
|
||||
+23
-21
@@ -1,4 +1,4 @@
|
||||
#ifndef SERIALCONTROLLER_H
|
||||
#ifndef SERIALCONTROLLER_H
|
||||
#define SERIALCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
@@ -6,31 +6,33 @@
|
||||
|
||||
class SerialController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SerialController(QObject *parent = nullptr);
|
||||
explicit SerialController(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void openSuccess(); //串口打开成功
|
||||
void openFailed(); //串口打开失败
|
||||
void closeSuccess(); //串口关闭成功
|
||||
void writeSuccess(int len); //串口发送成功 len为成功发送的字节
|
||||
void writeFailed(); //串口发送失败
|
||||
void recvData(QByteArray content); //发送接收到的数据
|
||||
void openSuccess(); //串口打开成功
|
||||
void openFailed(); //串口打开失败
|
||||
void closeSuccess(); //串口关闭成功
|
||||
void writeSuccess(int len); //串口发送成功 len为成功发送的字节
|
||||
void writeFailed(); //串口发送失败
|
||||
void recvData(const QByteArray &content); //发送接收到的数据
|
||||
|
||||
public slots:
|
||||
void openSerial(QString name);
|
||||
void closeSerial();
|
||||
void getBaudrate(QString baudrate); //改变波特率
|
||||
void getStopbits(QString stopbits); //改变停止位
|
||||
void getDatabits(QString databits); //改变数据为
|
||||
void getParity(QString parity); //改变校验位
|
||||
void writeData(QString content); //发送数据
|
||||
void handleRecv(); //接受数据
|
||||
|
||||
private:
|
||||
QSerialPort *serial;
|
||||
public slots:
|
||||
void openSerial(const QString &name);
|
||||
void closeSerial();
|
||||
void getBaudrate(const QString &baudrate); //改变波特率
|
||||
void getStopbits(const QString &stopbits); //改变停止位
|
||||
void getDatabits(const QString &databits); //改变数据为
|
||||
void getParity(const QString &parity); //改变校验位
|
||||
void getFlowControl(const QString &flowControl); //改变流控位
|
||||
void writeData(const QByteArray &content); //发送数据
|
||||
void handleRecv(); //接受数据
|
||||
void contrloRTS(bool set); //设置RTS位
|
||||
void controlDTR(bool set); //设置DTR位
|
||||
|
||||
private:
|
||||
QSerialPort *serial;
|
||||
};
|
||||
|
||||
#endif // SERIALCONTROLLER_H
|
||||
|
||||
Reference in New Issue
Block a user