自己写的一个HID和COM的命令收发工具。特色是自定义标题栏。记录一下:
平台:Qt Creator 10.0.2
QT版本:Qt 6.2.4 (MinGW 11.2.0 64bit)
这里实现自定义标题栏的方法是从其它前辈那里学来的一种,先上图
下面是mainwindow.cpp原码:
#include <QScreen>
#include <QApplication>
#include <QMouseEvent>
#include <QtGlobal>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "hid_report_parse.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->phBtn_max->setVisible(true);
ui->phBtn_restore->setVisible(false);
QString icon_path_str = "://images/titleIcon.png";
titleIcon.load(icon_path_str);
QPixmap scaled_icon = titleIcon.scaledToHeight(50);
ui->lb_titleIcon->setPixmap(scaled_icon);
setWindowIcon(QIcon("://images/titleIcon.png"));
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
init_com_port_param();
init_Hid_param_func();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_phBtn_min_clicked()
{
showMinimized();
}
void MainWindow::on_phBtn_max_clicked()
{
ui->phBtn_max->setVisible(false);
ui->phBtn_restore->setVisible(true);
showMaximized();
}
void MainWindow::on_phBtn_close_clicked()
{
close();
}
void MainWindow::on_phBtn_restore_clicked()
{
ui->phBtn_max->setVisible(true);
ui->phBtn_restore->setVisible(false);
showNormal();
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons().testFlag(Qt::LeftButton) && mousePressed)
{
QPointF movePoint = event->globalPosition() - startMovePos;
// QPointF widgetPos = this->parentWidget()->pos();
// this->parentWidget()->move(widgetPos.x() + movePoint.x(),widgetPos.y() + movePoint.y());
this->move(this->pos() + movePoint.toPoint());
startMovePos = event->globalPosition();
}
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
mousePressed = true;
startMovePos = event->globalPosition();
}
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
mousePressed = false;
}
}
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_UNUSED(event);
if (ui->phBtn_max->isVisible())
{
emit ui->phBtn_max->clicked();
}
else
{
emit ui->phBtn_restore->clicked();
}
}
void MainWindow::writeDataToPlainTextEdit_func(char * write_buff, int color, int pla_num, int data_length)
{
int ascii_length = data_length*3;
char *ascii_buff = (char *)malloc(ascii_length);
for (int i = 0, j = 0; i < data_length; i ++)
{
ascii_buff[j] = decToChar_transfer((unsigned char)(write_buff[i] >> 4) & 0x0f);
ascii_buff[j + 1] = decToChar_transfer((unsigned char)write_buff[i] & 0x0f);
ascii_buff[j + 2] = ' ';
j += 3;
}
QString receiveTxt_String(ascii_buff);
QTextCharFormat charFmt;
if (color == BLUE_TEXT)
{
charFmt.setForeground(Qt::blue);
}
else
{
charFmt.setForeground(Qt::black);
}
if (pla_num == 0)
{
ui->plaTxtEdit_USB->mergeCurrentCharFormat(charFmt);
ui->plaTxtEdit_USB->appendPlainText(receiveTxt_String);
}
else
{
ui->plaTxtEdit_COM->mergeCurrentCharFormat(charFmt);
ui->plaTxtEdit_COM->appendPlainText(receiveTxt_String);
}
free(ascii_buff);
}
void MainWindow::on_puBtn_scanUSB_clicked()
{
QString list_text;
int dev_i = 0;
hid_info = hid_enumerate(0,0); //traversal all hid device
ui->cbBox_usbList->clear();
memset((char *)&hid_dev_list[0][0], 0, sizeof(hid_dev_list));
if (hid_handle != nullptr)
{
hid_close(hid_handle);
hid_handle = nullptr;
}
for (; hid_info != nullptr; hid_info = hid_info->next)
{
list_text = QString::fromStdWString(hid_info->product_string);
if (hid_info->usage_page == CONSUMER_PAGE ||
hid_info->usage_page == GAME_CONTROLS_PAGE)
{
if (dev_i < 20)
{
ui->cbBox_usbList->addItem(list_text);
hid_dev_list[dev_i][0] = hid_info->product_id;
hid_dev_list[dev_i][1] = hid_info->vendor_id;
hid_path[dev_i] = hid_info->path;
hid_serialNum[dev_i] = hid_info->serial_number;
dev_i ++;
}
}
}
}
下面是mainwindow.h代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include <QTimer>
#include "hidapi.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
typedef enum
{
BLACK_TEXT,
BLUE_TEXT,
}TEXT_COLOR_enum;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void hidWriteFail_criticalMsgBox();
void writeDataToPlainTextEdit_func(char * write_buff, int color, int pla_num, int data_length);
void init_com_port_param();
void uartSend(QString cmd);
void init_Hid_param_func();
private slots:
void on_phBtn_min_clicked();
void on_phBtn_max_clicked();
void on_phBtn_close_clicked();
void on_phBtn_restore_clicked();
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void on_phBtn_send1_clicked();
void on_phBtn_send2_clicked();
void on_phBtn_send3_clicked();
void on_phBtn_send4_clicked();
void on_phBtn_send1_com_clicked();
void on_phBtn_send2_com_clicked();
void on_phBtn_send3_com_clicked();
void on_phBtn_send4_com_clicked();
void on_phBtn_openCOM_clicked();
void do_com_readyRead(); //串口有数据可读
void read_hidDataTimer_func();
void on_puBtn_scanUSB_clicked();
void on_cbBox_usbList_currentIndexChanged(int index);
void on_phBtn_stopDiplay_USB_clicked();
void on_phBtn_stopDiplay_COM_clicked();
private:
Ui::MainWindow *ui;
QPointF startMovePos;
bool mousePressed;
QPixmap titleIcon;
QSerialPort comPort;
unsigned short hid_dev_list[20][2];
char *hid_path[20];
wchar_t *hid_serialNum[20];
unsigned short opened_pid;
unsigned short opened_vid;
hid_device_info *hid_info;
hid_device *hid_handle;
QTimer *read_hid_timer;
int show_hid_data_flag;
bool show_com_data_flag;
};
unsigned char decToChar_transfer(unsigned char preTranData);
unsigned char char_to_hex_transfer(char preTransfer);
void charToByte_Transfer(unsigned char *write_buff, char * read_buff, int size);
#endif // MAINWINDOW_H
下面是hid_tool_class.cpp代码
#include <QMessageBox>
#include "mainwindow.h"
#include "ui_mainwindow.h"
void MainWindow::init_Hid_param_func()
{
read_hid_timer = new QTimer(this);
read_hid_timer->stop();
read_hid_timer->setTimerType(Qt::PreciseTimer);
connect(read_hid_timer, SIGNAL(timeout()), this, SLOT(read_hidDataTimer_func()));
show_hid_data_flag = 1;
hid_handle = nullptr;
}
void MainWindow::on_phBtn_send1_clicked()
{
int result;
unsigned char write_buff[63];
QString input_text = ui->liEdit_USBsend1->text();
QByteArray byteArray = input_text.toLocal8Bit();
if (byteArray.length() == 0)
{ //don't send void data
return;
}
const char *read_buff = byteArray.constData();
memset(write_buff, 0, sizeof(write_buff));
charToByte_Transfer(write_buff, (char *)read_buff, byteArray.length());
if (write_buff[0] != 0x4D)
{ //data error
return;
}
result = hid_write(hid_handle, write_buff, sizeof(write_buff));
if (result < 0)
{
hidWriteFail_criticalMsgBox();
}
else
{
writeDataToPlainTextEdit_func((char *)write_buff, BLACK_TEXT, 0, 63);
}
}
void MainWindow::on_phBtn_send2_clicked()
{
int result;
unsigned char write_buff[63];
QString input_text = ui->liEdit_USBsend2->text();
QByteArray byteArray = input_text.toLocal8Bit();
if (byteArray.length() == 0)
{ //don't send void data
return;
}
const char *read_buff = byteArray.constData();
memset(write_buff, 0, sizeof(write_buff));
charToByte_Transfer(write_buff, (char *)read_buff, byteArray.length());
if (write_buff[0] != 0x4D)
{ //data error
return;
}
result = hid_write(hid_handle, write_buff, sizeof(write_buff));
if (result < 0)
{
hidWriteFail_criticalMsgBox();
}
else
{
writeDataToPlainTextEdit_func((char *)write_buff, BLACK_TEXT, 0, 63);
}
}
void MainWindow::on_phBtn_send3_clicked()
{
int result;
unsigned char write_buff[63];
QString input_text = ui->liEdit_USBsend3->text();
QByteArray byteArray = input_text.toLocal8Bit();
if (byteArray.length() == 0)
{ //don't send void data
return;
}
const char *read_buff = byteArray.constData();
memset(write_buff, 0, sizeof(write_buff));
charToByte_Transfer(write_buff, (char *)read_buff, byteArray.length());
if (write_buff[0] != 0x4D)
{ //data error
return;
}
result = hid_write(hid_handle, write_buff, sizeof(write_buff));
if (result < 0)
{
hidWriteFail_criticalMsgBox();
}
else
{
writeDataToPlainTextEdit_func((char *)write_buff, BLACK_TEXT, 0, 63);
}
}
void MainWindow::on_phBtn_send4_clicked()
{
int result;
unsigned char write_buff[63];
QString input_text = ui->liEdit_USBsend4->text();
QByteArray byteArray = input_text.toLocal8Bit();
if (byteArray.length() == 0)
{ //don't send void data
return;
}
const char *read_buff = byteArray.constData();
memset(write_buff, 0, sizeof(write_buff));
charToByte_Transfer(write_buff, (char *)read_buff, byteArray.length());
if (write_buff[0] != 0x4D)
{ //data error
return;
}
result = hid_write(hid_handle, write_buff, sizeof(write_buff));
if (result < 0)
{
hidWriteFail_criticalMsgBox();
}
else
{
writeDataToPlainTextEdit_func((char *)write_buff, BLACK_TEXT, 0, 63);
}
}
void MainWindow::hidWriteFail_criticalMsgBox()
{
QString dlg_title = "发送失败!";
QString str_info = "请重新扫描设备";
QMessageBox::critical(this, dlg_title, str_info);
}
void MainWindow::read_hidDataTimer_func()
{
int result;
char read_buff[64];
if (hid_handle == 0 || show_hid_data_flag == 0)
return;
hid_set_nonblocking(hid_handle, 1); //非阻塞试读取
result = hid_read(hid_handle, (unsigned char *)read_buff, 63);
if (result < 0)
{
qDebug("err_string = %ls\n", hid_error(hid_handle));
}
else if (read_buff[0] == 0x4D)
{
writeDataToPlainTextEdit_func(read_buff, BLUE_TEXT, 0, 63);
}
}
void MainWindow::on_cbBox_usbList_currentIndexChanged(int index)
{
const char send_buff1[] = "4D 02 00 02 01 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
const char send_buff2[] = "4D 10 00 06 42 A8 B2 47 B6 60 00 00 00 00 00 00 00 00 00 00 00 00 00";
const char send_buff3[] = "4D 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
const char send_buff4[] = {
'4','D',' ','0','9',' ','0','1',' ','2','0',' ','E','8',' ','4','4',' ','0','A',' ','0','0',' ',
'0','C',' ','3','F',' ','0','A',' ','0','0',' ','5','8',' ','5','C',' ','0','A',' ','0','0',' ',
'1','C',' ','6','6',' ','0','A',' ','0','0',' ','9','8',' ','7','B',' ','0','A',' ','0','0',' ',
'6','8',' ','8','3',' ','0','A',' ','0','0',' ','2','0',' ','8','F',' ','0','A',' ','0','0',' ',
'D','8',' ','9','A',' ','0','A',' ','0','0',' ','0','0',' ','0','0',' ','0','0',' ','0','0',' ',
'0','0',' ','0','0',' ','0','0',' ','0','0',' ','0','0',' ','0','0',' ','0','0',' ','0','0',' ',
'0','0',' ','0','0',' ','0','0',' ','0','0',' ','1','C'};
QString send_String1(send_buff1);
QString send_String2(send_buff2);
QString send_String3(send_buff3);
QString send_String4(send_buff4);
#if 0
int test_count = 0;
unsigned char * report_buff = (unsigned char *)malloc(HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
#endif
if ((hid_dev_list[index][0] != opened_pid || hid_dev_list[index][1] != opened_vid) &&
(hid_dev_list[index][0] != 0 || hid_dev_list[index][1] != 0))
{
#if 1
hid_handle = hid_open_path(hid_path[index]);
#else
hid_handle = hid_open(hid_dev_list[index][1], hid_dev_list[index][0],hid_serialNum[index]);
#endif
if (hid_handle == 0)
{ //open device fail
return;
}
#if 0
test_count = hid_get_report_descriptor(hid_handle, report_buff, HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
HidReportParse_func(report_buff, test_count);
#endif
hid_free_enumeration(hid_info);
hid_info = nullptr;
ui->liEdit_USBsend1->setText(send_String1);
ui->liEdit_USBsend2->setText(send_String2);
ui->liEdit_USBsend3->setText(send_String3);
ui->liEdit_USBsend4->setText(send_String4);
read_hid_timer->setInterval(5);
read_hid_timer->setSingleShot(false);
read_hid_timer->stop();
read_hid_timer->start();
}
}
void MainWindow::on_phBtn_stopDiplay_USB_clicked()
{
if (show_hid_data_flag)
{
show_hid_data_flag = 0;
ui->phBtn_stopDiplay_USB->setText("继续显示");
ui->phBtn_stopDiplay_USB->setStyleSheet("background-color: red;"
"color:#FFFFFF;");
}
else
{
show_hid_data_flag = 1;
ui->phBtn_stopDiplay_USB->setText("暂停显示");
ui->phBtn_stopDiplay_USB->setStyleSheet("background-color: black;"
"color:#FFFFFF;");
}
}
unsigned char decToChar_transfer(unsigned char preTranData)
{
if (preTranData <= 9)
{
return preTranData + 0x30;
}
else if (preTranData < 16)
{
return preTranData - 10 + 0x41;
}
return 0x30;
}
unsigned char char_to_hex_transfer(char preTransfer)
{
unsigned char result = 0;
if (preTransfer >= 0x30 && preTransfer <= 0x39) // 0~9
{
result = preTransfer - 0x30;
}
else if (preTransfer >= 0x41 && preTransfer <= 0x46) //A ~ F
{
result = preTransfer - 0x41 + 0x0A;
}
else if (preTransfer >= 0x61 && preTransfer <= 0x66) //a ~ f
{
result = preTransfer - 0x61 + 0x0A;
}
return result;
}
void charToByte_Transfer(unsigned char *write_buff, char * read_buff, int size)
{
for (int ind = 0, j = 0; ind < size; ind ++)
{
if (read_buff[ind] == ' ') //don't parse space character
continue;
write_buff[j] = (char_to_hex_transfer(read_buff[ind])) << 4;
ind ++;
write_buff[j] |= char_to_hex_transfer(read_buff[ind]);
j ++;
}
}
下面是com_tool_file.cpp代码:
#include <QMessageBox>
#include <QSerialPortInfo>
#include "mainwindow.h"
#include "ui_mainwindow.h"
void MainWindow::init_com_port_param()
{
ui->phBtn_openCOM->setEnabled(false);
foreach(QSerialPortInfo portInfo, QSerialPortInfo::availablePorts())
ui->cbBox_comList->addItem(portInfo.portName()+":"+portInfo.description());
connect(&comPort, &QIODevice::readyRead, this, &MainWindow::do_com_readyRead);
ui->phBtn_openCOM->setEnabled(ui->cbBox_comList->count() > 0);
ui->cbBox_baudRate->clear();
foreach(qint32 baud, QSerialPortInfo::standardBaudRates())
ui->cbBox_baudRate->addItem(QString::number(baud));
ui->cbBox_baudRate->setCurrentText("115200");//默认使用115200
ui->cbBox_bitNum->addItem(QString::number(QSerialPort::Data5)+"bit");
ui->cbBox_bitNum->addItem(QString::number(QSerialPort::Data6)+"bit");
ui->cbBox_bitNum->addItem(QString::number(QSerialPort::Data7)+"bit");
ui->cbBox_bitNum->addItem(QString::number(QSerialPort::Data8)+"bit");
ui->cbBox_bitNum->setCurrentText(QString::number(QSerialPort::Data8)+"bit");
ui->cbBox_crcNum->addItem("无");
ui->cbBox_crcNum->addItem("奇校验");
ui->cbBox_crcNum->addItem("偶校验");
ui->cbBox_crcNum->addItem("掩码校验");
ui->cbBox_crcNum->addItem("空格校验");
ui->cbBox_crcNum->setCurrentText("无");
ui->cbBox_stopNum->addItem("1bit");
ui->cbBox_stopNum->addItem("2bit");
ui->cbBox_stopNum->addItem("1.5bit");
ui->cbBox_stopNum->setCurrentText("1bit");
show_com_data_flag = 1;
}
void MainWindow::do_com_readyRead()
{
QByteArray byteArray=comPort.readAll();
const char *read_buff = byteArray.constData();
if (show_com_data_flag)
writeDataToPlainTextEdit_func((char *)read_buff, BLUE_TEXT, 1, byteArray.length());
}
void MainWindow::on_phBtn_openCOM_clicked()
{
if (comPort.isOpen())
{
comPort.close();
QMessageBox::warning(this,"完成","串口关闭");
ui->phBtn_openCOM->setText("打开串口");
ui->cbBox_stopNum->setEnabled(true);
ui->cbBox_bitNum->setEnabled(true);
ui->cbBox_usbList->setEnabled(true);
return;
}
ui->phBtn_openCOM->setText("关闭串口");
QList<QSerialPortInfo> comList=QSerialPortInfo::availablePorts();
QSerialPortInfo portInfo=comList.at(ui->cbBox_comList->currentIndex());
comPort.setPort(portInfo); //设置使用哪个串口
// comPort.setPortName(portInfo.portName()); //也可以设置串口名称
//设置串口通信参数
QString str=ui->cbBox_baudRate->currentText();
comPort.setBaudRate(str.toInt()); //设置波特率
str = ui->cbBox_bitNum->currentText();
str = str.left(1);
int value=str.toInt();
comPort.setDataBits(QSerialPort::DataBits(value)); //数据位,默认8位
value=1+ui->cbBox_stopNum->currentIndex();
comPort.setStopBits(QSerialPort::StopBits(value)); //停止位,默认1位
if (ui->cbBox_crcNum->currentIndex()==0)
value=0;
else
value=1+ui->cbBox_crcNum->currentIndex();
comPort.setParity(QSerialPort::Parity(value)); //校验位,默认无
QString uart_cmd1 = "5a a5 03 00 01 fb 5a a5 03 00 07 f5 5a a5 03 00 fb 01";
QString uart_cmd2 = "5a a5 03 00 09 f3";
ui->liEdit_COMsend1->setText(uart_cmd1);
ui->liEdit_COMsend2->setText(uart_cmd2);
if (comPort.open(QIODeviceBase::ReadWrite))
{
ui->cbBox_stopNum->setEnabled(false);
ui->cbBox_bitNum->setEnabled(false);
ui->cbBox_usbList->setEnabled(false);
QMessageBox::information(this,"提示信息","串口已经被成功打开");
}
else
{
qDebug()<<"error:"<< comPort.error();
}
}
//UART发送 char* 字符串
void MainWindow::uartSend(QString cmd)
{
if (cmd.length() == 0)
{
QMessageBox::critical(this,"错误","数据为空");
return;
}
if (comPort.isOpen() == false)
{
QMessageBox::warning(this,"错误","请先打开串口");
return;
}
// ui->plaTxtEdit_COM->appendPlainText(cmd);
QByteArray byteArray=cmd.toLocal8Bit(); //转换为8位字符数据数组
const char *read_buff = byteArray.constData();
char *write_buff = (char *)malloc(byteArray.length()/2);
memset(write_buff, 0, byteArray.length()/2);
charToByte_Transfer((unsigned char*)write_buff, (char *)read_buff, byteArray.length());
comPort.write(write_buff,byteArray.length()/2);
if (show_com_data_flag)
writeDataToPlainTextEdit_func(write_buff, BLACK_TEXT, 1, byteArray.length()/2);
free(write_buff);
}
void MainWindow::on_phBtn_send1_com_clicked()
{
QString cmd = ui->liEdit_COMsend1->text().trimmed(); //指令字符串
uartSend(cmd); //通过串口发送字符串数据
}
void MainWindow::on_phBtn_send2_com_clicked()
{
QString cmd = ui->liEdit_COMsend2->text().trimmed(); //指令字符串
uartSend(cmd); //通过串口发送字符串数据
}
void MainWindow::on_phBtn_send3_com_clicked()
{
QString cmd = ui->liEdit_COMsend3->text().trimmed(); //指令字符串
uartSend(cmd); //通过串口发送字符串数据
}
void MainWindow::on_phBtn_send4_com_clicked()
{
QString cmd = ui->liEdit_COMsend4->text().trimmed(); //指令字符串
uartSend(cmd); //通过串口发送字符串数据
}
void MainWindow::on_phBtn_stopDiplay_COM_clicked()
{
if (show_com_data_flag)
{
show_com_data_flag = 0;
ui->phBtn_stopDiplay_COM->setText("继续显示");
ui->phBtn_stopDiplay_COM->setStyleSheet("background-color: red;"
"color:#FFFFFF;");
}
else
{
show_com_data_flag = 1;
ui->phBtn_stopDiplay_COM->setText("暂停显示");
ui->phBtn_stopDiplay_COM->setStyleSheet("background-color: black;"
"color:#FFFFFF;");
}
}
下面是hid_report_parse.h代码,hid库是从github上获取的,版本是hidapi_0.14.0
#ifndef HID_REPORT_PARSE_H
#define HID_REPORT_PARSE_H
typedef enum
{
UNDEFINED,
GENERIC_DESKTOP_PAGE = 0x01,
SIMULATION_CONTROL_PAGE = 0x02,
VR_CONTROL_PAGE = 0x03,
SPORT_CONTROL_PAGE,
GAME_CONTROLS_PAGE,
GENERIC_DEVICE_CONTROL_PAGE,
KEYBOARD_PAGE,
LED_PAGE,
BUTTON_PAGE,
ORDINAL_PAGE,
TELEPHONY_DEVICE_PAGE,
CONSUMER_PAGE = 0x0C,
DIGITIZERS_PAGE
}USAGE_PAGE_type;
struct hidReportInfo_struct
{
unsigned short report_id;
unsigned short input_report_size;
unsigned short output_report_size;
unsigned int usage;
unsigned int usage_page;
struct hidReportInfo_struct *next;
};
struct hidReportInfo_struct * HidReportParse_func(unsigned char *report_buff, unsigned short repotr_size);
void free_hidReportInfoStruct_func(hidReportInfo_struct *first_struct);
#endif // HID_REPORT_PARSE_H
下面是mainwindow.ui代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>660</width>
<height>660</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(0, 170, 127, 255), stop:1 rgba(255, 255, 255, 255));
border-radius:10px;</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color:none;</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_4">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="lb_titleName">
<property name="geometry">
<rect>
<x>52</x>
<y>0</y>
<width>211</width>
<height>51</height>
</rect>
</property>
<property name="font">
<font>
<family>Trebuchet MS</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>COM_HID_Tool</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QLabel" name="lb_titleIcon">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>50</width>
<height>50</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_5">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QPushButton" name="phBtn_close">
<property name="geometry">
<rect>
<x>290</x>
<y>10</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
border:none;
border-radius:8px;
background-color: rgb(255, 85, 0);
}
QPushButton:hover{
background-color: rgba(255, 85, 0, 127);
}</string>
</property>
<property name="text">
<string>x</string>
</property>
</widget>
<widget class="QPushButton" name="phBtn_min">
<property name="geometry">
<rect>
<x>210</x>
<y>10</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
border:none;
border-radius:8px;
background-color: rgb(85, 255, 127);
}
QPushButton:hover{
background-color: rgba(85, 255, 127, 127);
}</string>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
<widget class="QPushButton" name="phBtn_restore">
<property name="geometry">
<rect>
<x>250</x>
<y>10</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
border:none;
border-radius:8px;
background-color: rgb(0, 170, 255);
}
QPushButton:hover{
background-color: rgba(0, 170, 255, 127);
}</string>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
<widget class="QPushButton" name="phBtn_max">
<property name="geometry">
<rect>
<x>250</x>
<y>10</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
border:none;
border-radius:8px;
background-color: rgb(255, 170, 0);
}
QPushButton:hover{
background-color: rgba(255, 170, 0, 127);
}</string>
</property>
<property name="text">
<string>++</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="styleSheet">
<string notr="true">background-color:none;</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="styleSheet">
<string notr="true">QTabWidget::tab-bar{
alignment:center;
}
QTabWidget::pane{
border:none;
background:transparent;
}
QTabBar::tab {
border-color: rgba(170, 255, 127, 127);
background-color: rgb(170, 255, 127);
border-top-left-radius:4px;
border-top-right-radius:4px;
min-width:20px;
padding:2px;
}
QTabBar::tab:hover {
background-color: rgb(255, 255, 127);
}
QTabBar::tab:selected {
background-color: rgb(85, 255, 0);
border-color: rgb(66, 197, 96);
}
QTabBar::tab:tab_USB{
margin-left:0px;
width:100px;
height:30px;
}
QTabBar::tab:tab_com{
margin-left:10px;
width:100px;
height:30px;
}</string>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="tab_USB">
<attribute name="title">
<string>USB Tool</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QFrame" name="frame_openUSBDev">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QComboBox" name="cbBox_usbList">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>36</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="puBtn_scanUSB">
<property name="geometry">
<rect>
<x>510</x>
<y>5</y>
<width>93</width>
<height>30</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>扫描设备</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_sendUSBData">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_sendTxt1">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLineEdit" name="liEdit_USBsend1">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>610</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send1">
<property name="geometry">
<rect>
<x>560</x>
<y>30</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_SendTxt3">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLineEdit" name="liEdit_USBsend2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>610</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send2">
<property name="geometry">
<rect>
<x>560</x>
<y>30</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_sendTxt2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLineEdit" name="liEdit_USBsend3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>610</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send3">
<property name="geometry">
<rect>
<x>560</x>
<y>30</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_sendTxt4">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLineEdit" name="liEdit_USBsend4">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>610</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send4">
<property name="geometry">
<rect>
<x>560</x>
<y>30</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_displayTxRxData">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QPushButton" name="phBtn_stopDiplay_USB">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>80</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>暂停显示</string>
</property>
</widget>
<widget class="QPlainTextEdit" name="plaTxtEdit_USB">
<property name="geometry">
<rect>
<x>0</x>
<y>30</y>
<width>610</width>
<height>200</height>
</rect>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_com">
<property name="enabled">
<bool>true</bool>
</property>
<attribute name="title">
<string>COM Tool</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_6">
<property name="minimumSize">
<size>
<width>0</width>
<height>81</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>81</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_7">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QComboBox" name="cbBox_baudRate">
<property name="geometry">
<rect>
<x>475</x>
<y>5</y>
<width>160</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_openCOM">
<property name="geometry">
<rect>
<x>270</x>
<y>5</y>
<width>80</width>
<height>30</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>打开串口</string>
</property>
</widget>
<widget class="QComboBox" name="cbBox_comList">
<property name="geometry">
<rect>
<x>80</x>
<y>5</y>
<width>180</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="lb_comName">
<property name="geometry">
<rect>
<x>0</x>
<y>5</y>
<width>70</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>COM口</string>
</property>
</widget>
<widget class="QLabel" name="lb_baudRate">
<property name="geometry">
<rect>
<x>400</x>
<y>5</y>
<width>69</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>波特率</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_8">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QComboBox" name="cbBox_stopNum">
<property name="geometry">
<rect>
<x>555</x>
<y>5</y>
<width>80</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="lb_bitNum">
<property name="geometry">
<rect>
<x>0</x>
<y>5</y>
<width>60</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>数据位</string>
</property>
</widget>
<widget class="QComboBox" name="cbBox_bitNum">
<property name="geometry">
<rect>
<x>61</x>
<y>5</y>
<width>80</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="lb_stopNum">
<property name="geometry">
<rect>
<x>494</x>
<y>5</y>
<width>60</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>停止位</string>
</property>
</widget>
<widget class="QComboBox" name="cbBox_crcNum">
<property name="geometry">
<rect>
<x>308</x>
<y>5</y>
<width>80</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="lb_crcNum">
<property name="geometry">
<rect>
<x>247</x>
<y>5</y>
<width>60</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>校验位</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_9">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLineEdit" name="liEdit_COMsend1">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>635</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send1_com">
<property name="geometry">
<rect>
<x>580</x>
<y>30</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
<widget class="QLineEdit" name="liEdit_COMsend2">
<property name="geometry">
<rect>
<x>0</x>
<y>60</y>
<width>635</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="liEdit_COMsend3">
<property name="geometry">
<rect>
<x>0</x>
<y>120</y>
<width>635</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="liEdit_COMsend4">
<property name="geometry">
<rect>
<x>0</x>
<y>180</y>
<width>635</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send2_com">
<property name="geometry">
<rect>
<x>580</x>
<y>90</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send3_com">
<property name="geometry">
<rect>
<x>580</x>
<y>150</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
<widget class="QPushButton" name="phBtn_send4_com">
<property name="geometry">
<rect>
<x>580</x>
<y>210</y>
<width>50</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_10">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QPlainTextEdit" name="plaTxtEdit_COM">
<property name="geometry">
<rect>
<x>0</x>
<y>31</y>
<width>635</width>
<height>200</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phBtn_stopDiplay_COM">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
color:#FFFFFF;
background-color: rgb(0, 0, 0);
}</string>
</property>
<property name="text">
<string>暂停显示</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
QT工程文件如下所示
QT += core gui
QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
com_tool_file.cpp \
hid_tool_class.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
hid_report_parse.h \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
images.qrc
RC_ICONS += images/titleIcon.ico
win32: LIBS += -L$$PWD/./ -lhidapi
INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/.