update: 阶段性提交,更新页面,添加C++

文件,添加串口刷新功能
This commit is contained in:
Alvin Young 2024-12-20 11:11:59 +08:00
parent a6fa2fa5d3
commit 2debe4b265
15 changed files with 341 additions and 64 deletions

View File

@ -7,7 +7,7 @@ set(CMAKE_AUTORCC ON)
find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) find_package(Qt6 6.5 REQUIRED COMPONENTS Quick)
find_package(Qt6 COMPONENTS Core Gui Svg Core5Compat REQUIRED) find_package(Qt6 COMPONENTS Core Gui Svg Core5Compat SerialPort REQUIRED)
qt_standard_project_setup(REQUIRES 6.5) qt_standard_project_setup(REQUIRES 6.5)
@ -15,6 +15,12 @@ qt_add_executable(appESP32_upper
main.cpp main.cpp
) )
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/src/components
${CMAKE_CURRENT_SOURCE_DIR}/src/services
${CMAKE_CURRENT_SOURCE_DIR}/src/wrapper
)
qt_add_qml_module(appESP32_upper qt_add_qml_module(appESP32_upper
URI ESP32_upper URI ESP32_upper
VERSION 1.0 VERSION 1.0
@ -33,6 +39,9 @@ qt_add_qml_module(appESP32_upper
QML_FILES QML/components/IconInfoLabel.qml QML_FILES QML/components/IconInfoLabel.qml
QML_FILES QML/components/HomePageConnectStateInfo.qml QML_FILES QML/components/HomePageConnectStateInfo.qml
QML_FILES QML_FILES
SOURCES src/wrapper/esp32uperwrapper.h src/wrapper/esp32uperwrapper.cpp
SOURCES src/services/esp32upperextservice.h src/services/esp32upperextservice.cpp
SOURCES src/components/serialportcomp.h src/components/serialportcomp.cpp
) )
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
@ -47,7 +56,7 @@ set_target_properties(appESP32_upper PROPERTIES
) )
target_link_libraries(appESP32_upper target_link_libraries(appESP32_upper
PRIVATE Qt6::Quick Qt6::Core Qt6::Gui Qt6::Svg Qt6::Core5Compat PRIVATE Qt6::Quick Qt6::Core Qt6::Gui Qt6::Svg Qt6::Core5Compat Qt6::SerialPort
) )
include(GNUInstallDirs) include(GNUInstallDirs)

View File

@ -11,7 +11,30 @@ Window {
minimumWidth: 800 minimumWidth: 800
// color: "green" // color: "green"
property var sharedData: ({
counter: 0 ,
gp_inited: 0,
global_banner: "Hello World",
left_menu_index_now: 0,
left_menu_index_last: 255,
left_menu_lighlight_color: "#FF00FF",
left_menu_non_lighlight_color: "#00FF00",
left_menu_focus_color: "#FAFA00",
left_menu_icon_color: "#0d4e8b",
font_info_pixel_size: 20,
btn_normalBackground: "#FFFFFF", // //
btn_hoverBackground: "#F0F0F0", // // hover
btn_pressedBackground: "#D0D0D0", // // pressed
btn_borderColor: "#000000", // // pressed
port_name_list_model: ListModel
})
MainPage { MainPage {
id: id_home_page id: id_home_page
} }
Component.onCompleted: {
console.log(sharedData.counter); //
sharedData.gp_inited = 1
}
} }

View File

@ -16,7 +16,7 @@ Item {
Text { Text {
Layout.preferredWidth: 100 Layout.preferredWidth: 100
text: "连接状态:" text: "连接状态:"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
@ -24,7 +24,7 @@ Item {
Layout.preferredWidth: 100 Layout.preferredWidth: 100
id: id_text_home_page_connet_state id: id_text_home_page_connet_state
text: "未连接" text: "未连接"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
Rectangle { Rectangle {
@ -33,16 +33,16 @@ Item {
} }
Button { Button {
id: button id: id_button_refresh_portlist
text: "重新连接" text: "shuaxin"
Layout.preferredWidth: 100 Layout.preferredWidth: 100
Layout.preferredHeight: 50 Layout.preferredHeight: 40
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
background: Rectangle { background: Rectangle {
color: button.down ? id_gp.btn_pressedBackground : color: id_button_refresh_portlist.down ? sharedData.btn_pressedBackground :
button.hovered ? id_gp.btn_hoverBackground : id_gp.btn_normalBackground id_button_refresh_portlist.hovered ? sharedData.btn_hoverBackground : sharedData.btn_normalBackground
border.color: id_gp.btn_borderColor border.color: sharedData.btn_borderColor
radius: 10 radius: 10
} }
@ -52,9 +52,53 @@ Item {
// MouseArea // MouseArea
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onPressed: button.background.color = id_gp.btn_pressedBackground onPressed: id_button_refresh_portlist.background.color = sharedData.btn_pressedBackground
onReleased: button.background.color = button.hovered ? id_gp.btn_hoverBackground : id_gp.btn_normalBackground onReleased: id_button_refresh_portlist.background.color = id_button_refresh_portlist.hovered ? sharedData.btn_hoverBackground : sharedData.btn_normalBackground
onExited: button.background.color = id_gp.btn_normalBackground onExited: id_button_refresh_portlist.background.color = sharedData.btn_normalBackground
onClicked: {
console.log("clear all port")
id_combox_port_list.model.clear()
id_esp32upperwaper.GetPortNameList();
}
}
}
ComboBox {
id:id_combox_port_list
model: protname_list_model
Layout.preferredWidth: 100
Layout.preferredHeight: 40
background: Rectangle {
color: sharedData.btn_normalBackground
border.color: sharedData.btn_borderColor
radius: 10
}
font.pixelSize: sharedData.font_info_pixel_size
}
Button {
id: button
text: "重新连接"
Layout.preferredWidth: 100
Layout.preferredHeight: 40
font.pixelSize: sharedData.font_info_pixel_size
background: Rectangle {
color: button.down ? sharedData.btn_pressedBackground :
button.hovered ? sharedData.btn_hoverBackground : sharedData.btn_normalBackground
border.color: sharedData.btn_borderColor
radius: 10
}
// 使 Button hover
hoverEnabled: true
// MouseArea
MouseArea {
anchors.fill: parent
onPressed: button.background.color = sharedData.btn_pressedBackground
onReleased: button.background.color = button.hovered ? sharedData.btn_hoverBackground : sharedData.btn_normalBackground
onExited: button.background.color = sharedData.btn_normalBackground
} }
onClicked: { onClicked: {

View File

@ -24,7 +24,7 @@ Item {
ColorOverlay { ColorOverlay {
anchors.fill: parent anchors.fill: parent
source: parent source: parent
color: id_gp.left_menu_non_lighlight_color // SVG color: sharedData.left_menu_non_lighlight_color // SVG
} }
} }
@ -32,13 +32,13 @@ Item {
Text { Text {
text: "芯片类型:" text: "芯片类型:"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
Text { Text {
id: id_comp_ico_info_lb id: id_comp_ico_info_lb
text: "未确认" text: "未确认"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
} }
} }

View File

@ -11,31 +11,31 @@ Item {
Rectangle { Rectangle {
width: 60; height: 60 width: 60; height: 60
radius: 5 radius: 5
color: id_gp.left_menu_non_lighlight_color color: sharedData.left_menu_non_lighlight_color
MouseArea { MouseArea {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: { onClicked: {
// id_view.view.currentIndex = index // id_view.view.currentIndex = index
id_gp.left_menu_index_last = id_gp.left_menu_index_now sharedData.left_menu_index_last = sharedData.left_menu_index_now
id_gp.left_menu_index_now = index sharedData.left_menu_index_now = index
id_view.currentIndex = index id_view.currentIndex = index
id_layout_right_panel.currentIndex = index id_layout_right_panel.currentIndex = index
// console.log("left_menu_index", id_gp.left_menu_index_now) // console.log("left_menu_index", sharedData.left_menu_index_now)
} }
onEntered: { onEntered: {
if (index != id_gp.left_menu_index_now) { if (index != sharedData.left_menu_index_now) {
id_view.itemAtIndex(index).color = id_gp.left_menu_focus_color id_view.itemAtIndex(index).color = sharedData.left_menu_focus_color
} }
id_lm_tooltip_text.text = name; id_lm_tooltip_text.text = name;
id_lm_tooltip.visible = true; id_lm_tooltip.visible = true;
} }
onExited: { onExited: {
if (index != id_gp.left_menu_index_now) { if (index != sharedData.left_menu_index_now) {
id_view.itemAtIndex(index).color = id_gp.left_menu_non_lighlight_color id_view.itemAtIndex(index).color = sharedData.left_menu_non_lighlight_color
} }
id_lm_tooltip.visible = false; id_lm_tooltip.visible = false;
} }
@ -57,7 +57,7 @@ Item {
ColorOverlay { ColorOverlay {
anchors.fill: svgIMG anchors.fill: svgIMG
source: svgIMG source: svgIMG
color: id_gp.left_menu_icon_color // SVG color: sharedData.left_menu_icon_color // SVG
} }
} }
@ -105,13 +105,17 @@ Item {
clip : true clip : true
snapMode: ListView.SnapToItem snapMode: ListView.SnapToItem
onCurrentIndexChanged: { onCurrentIndexChanged: {
// console.log("2 left_menu_index", id_gp.left_menu_index_now) // console.log("2 left_menu_index", sharedData.left_menu_index_now)
itemAtIndex(id_gp.left_menu_index_last).color = id_gp.left_menu_non_lighlight_color if (sharedData.gp_inited == 1) {
itemAtIndex(id_gp.left_menu_index_now).color = id_gp.left_menu_lighlight_color itemAtIndex(sharedData.left_menu_index_last).color = sharedData.left_menu_non_lighlight_color
itemAtIndex(sharedData.left_menu_index_now).color = sharedData.left_menu_lighlight_color
}
} }
Component.onCompleted: { Component.onCompleted: {
console.log("complete at ", id_gp.left_menu_index_now) console.log("complete at ", sharedData.left_menu_index_now)
id_timer_leftmenu.start() id_timer_leftmenu.start()
} }
} }
@ -127,14 +131,14 @@ Item {
onTriggered: { onTriggered: {
// //
if (id_gp.gp_inited == 1) { if (sharedData.gp_inited == 1) {
running = false; running = false;
id_gp.left_menu_index_last = id_view.count sharedData.left_menu_index_last = id_view.count
id_gp.left_menu_index_now = 0 sharedData.left_menu_index_now = 0
id_view.itemAtIndex(id_gp.left_menu_index_now).color = id_gp.left_menu_lighlight_color id_view.itemAtIndex(sharedData.left_menu_index_now).color = sharedData.left_menu_lighlight_color
} else { } else {
pollForData(); pollForData();
console.log("id gp ini : " , id_gp.gp_inited ) console.log("id gp ini : " , sharedData.gp_inited )
} }
} }
} }

View File

@ -2,27 +2,27 @@ import QtQuick 2.15
import ESP32_upper import ESP32_upper
Item { Item {
property int gp_inited: 0 // property int gp_inited: 0
property string global_banner: "Hello World" // property string global_banner: "Hello World"
property int left_menu_index_now: 0 // property int left_menu_index_now: 0
property int left_menu_index_last: 255 // property int left_menu_index_last: 255
property color left_menu_lighlight_color: "#FF00FF" // property color left_menu_lighlight_color: "#FF00FF"
property color left_menu_non_lighlight_color: "#00FF00" // property color left_menu_non_lighlight_color: "#00FF00"
property color left_menu_focus_color: "#FAFA00" // property color left_menu_focus_color: "#FAFA00"
property color left_menu_icon_color: "#0d4e8b" // property color left_menu_icon_color: "#0d4e8b"
property int font_info_pixel_size: 20 // property int font_info_pixel_size: 20
// // //
property color btn_normalBackground: "#FFFFFF" // // property color btn_normalBackground: "#FFFFFF" //
// hover // // hover
property color btn_hoverBackground: "#F0F0F0" // // property color btn_hoverBackground: "#F0F0F0" //
// pressed // // pressed
property color btn_pressedBackground: "#D0D0D0" // // property color btn_pressedBackground: "#D0D0D0" //
// pressed // // pressed
property color btn_borderColor: "#000000" // // property color btn_borderColor: "#000000" //
Component.onCompleted: { // Component.onCompleted: {
console.log("global property has been initialized"); // console.log("global property has been initialized");
gp_inited = 1; // gp_inited = 1;
} // }
} }

View File

@ -26,21 +26,21 @@ Item {
spacing: 10 spacing: 10
Text { Text {
text: "版本号: 软件版本->" text: "版本号: 软件版本->"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
Text { Text {
id: id_text_soft_ver id: id_text_soft_ver
text: "未获取" text: "未获取"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
Text { Text {
text: " 硬件版本->" text: " 硬件版本->"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
Text { Text {
id: id_text_hard_ver id: id_text_hard_ver
text: "未获取" text: "未获取"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
} }
} }
@ -55,12 +55,12 @@ Item {
spacing: 10 spacing: 10
Text { Text {
text: "固件编译时间:" text: "固件编译时间:"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
Text { Text {
id: id_text_firm_build_time id: id_text_firm_build_time
text: "未获取" text: "未获取"
font.pixelSize: id_gp.font_info_pixel_size font.pixelSize: sharedData.font_info_pixel_size
} }
} }
} }

View File

@ -2,12 +2,23 @@ import QtQuick 2.15
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ESP32_upper 1.0 import ESP32_upper 1.0
import com.esp32upper 1.0
Item { Item {
id: root id: root
GlobalProperties { // GlobalProperties {
id: id_gp // id: id_gp
// }
ListModel {
id: protname_list_model
}
ESP32UperWrapper {
id: id_esp32upperwaper
onPortNameListChange: (port_name_list) => {
protname_list_model.append({text: qsTr(port_name_list)})
}
} }
RowLayout { RowLayout {
@ -48,5 +59,8 @@ Item {
} }
} }
} }
Component.onCompleted: {
id_esp32upperwaper.GetPortNameList();
}
} }

View File

@ -1,12 +1,15 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QIcon> #include <QIcon>
#include "esp32uperwrapper.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
app.setWindowIcon(QIcon(":/assets/img/esp32_upper.png")); // 设置应用窗口图标 app.setWindowIcon(QIcon(":/assets/img/esp32_upper.png")); // 设置应用窗口图标
qmlRegisterType<ESP32UperWrapper>("com.esp32upper", 1, 0, "ESP32UperWrapper");
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
QObject::connect( QObject::connect(
&engine, &engine,

View File

@ -0,0 +1,45 @@
#include "serialportcomp.h"
SerialPortComp::SerialPortComp(QObject *parent)
: QObject{parent}
{}
void SerialPortComp::RefreshPorts()
{
this->ports = QSerialPortInfo::availablePorts();
}
int SerialPortComp::OpenPort(int index)
{
serialPort.setPort(ports.at(index));
if (serialPort.open(QIODevice::ReadWrite)) { // 打开串口进行读写
serialPort.setBaudRate(QSerialPort::Baud9600); // 设置波特率
serialPort.setDataBits(QSerialPort::Data8); // 设置数据位
serialPort.setParity(QSerialPort::NoParity); // 设置校验位
serialPort.setStopBits(QSerialPort::OneStop); // 设置停止位
serialPort.setFlowControl(QSerialPort::NoFlowControl); // 设置流控制
} else {
}
return 0;
}
QByteArray SerialPortComp::PortRead()
{
QByteArray read_data;
if (serialPort.isOpen()) {
read_data = serialPort.readAll();
}
return read_data;
}
int SerialPortComp::PortWrite(QByteArray data)
{
if (serialPort.isOpen()) {
serialPort.write(data);
serialPort.flush();
}else {
return 1;
}
return 0;
}

View File

@ -0,0 +1,26 @@
#ifndef SERIALPORTCOMP_H
#define SERIALPORTCOMP_H
#include <QObject>
#include <QList>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
class SerialPortComp : public QObject
{
Q_OBJECT
public:
QList<QSerialPortInfo> ports;
explicit SerialPortComp(QObject *parent = nullptr);
void RefreshPorts();
int OpenPort(int index);
QByteArray PortRead();
int PortWrite(QByteArray date);
signals:
private:
QSerialPort serialPort;
};
#endif // SERIALPORTCOMP_H

View File

@ -0,0 +1,27 @@
#include "esp32upperextservice.h"
#include <QSerialPortInfo>
ESP32UpperExtService::ESP32UpperExtService(QObject *parent)
: QThread{parent}
{
serial_comp.RefreshPorts();
}
QList<QString> ESP32UpperExtService::GetPortNameList()
{
serial_comp.RefreshPorts();
this->port_name_list.clear();;
foreach (QSerialPortInfo item, serial_comp.ports) {
item.portName();
this->port_name_list.append(item.portName());
}
return this->port_name_list;
}
void ESP32UpperExtService::run()
{
while (thread_alive) {
// do sth
msleep(1);
}
}

View File

@ -0,0 +1,26 @@
#ifndef ESP32UPPEREXTSERVICE_H
#define ESP32UPPEREXTSERVICE_H
#include <QObject>
#include "serialportcomp.h"
#include <QThread>
#include <QList>
class ESP32UpperExtService : public QThread
{
Q_OBJECT
public:
explicit ESP32UpperExtService(QObject *parent = nullptr);
QList<QString> GetPortNameList();
protected:
void run() override;
signals:
private:
QList<QString> port_name_list;
SerialPortComp serial_comp;
int thread_alive = 1;
};
#endif // ESP32UPPEREXTSERVICE_H

View File

@ -0,0 +1,30 @@
#include "esp32uperwrapper.h"
#include <QDebug>
ESP32UperWrapper::ESP32UperWrapper(QObject *parent)
: QObject{parent}
{
qDebug("init ESP32UperWrapper OK\r\n");
}
void ESP32UperWrapper::OutPortWriteData(QByteArray &data)
{
}
void ESP32UperWrapper::GetPortNameList()
{
serial_comp.RefreshPorts();
this->port_name_list.clear();;
foreach (QSerialPortInfo item, serial_comp.ports) {
item.portName();
this->port_name_list.append(item.portName());
emit portNameListChange(item.portName());
}
}
void ESP32UperWrapper::OpenPort(int index)
{
this->serial_comp.OpenPort(index);
}

View File

@ -0,0 +1,26 @@
#ifndef ESP32UPERWRAPPER_H
#define ESP32UPERWRAPPER_H
#include <QObject>
#include <QByteArray>
#include "serialportcomp.h"
#include <QList>
class ESP32UperWrapper : public QObject
{
Q_OBJECT
public:
explicit ESP32UperWrapper(QObject *parent = nullptr);
Q_INVOKABLE void OutPortWriteData(QByteArray &data);
Q_INVOKABLE void GetPortNameList();
Q_INVOKABLE void OpenPort(int index);
signals:
void outPortDataRecv(QByteArray data);
void portNameListChange(QString port_name_list);
private:
QList<QString> port_name_list;
SerialPortComp serial_comp;
};
#endif // ESP32UPERWRAPPER_H