2022-08-25 18:43:03 +08:00
|
|
|
|
#include "mainwin.h"
|
|
|
|
|
#include "fast.h"
|
|
|
|
|
#include "expertwin.h"
|
|
|
|
|
#include "brightwin.h"
|
|
|
|
|
#include "pcapwin.h"
|
2022-10-12 18:17:10 +08:00
|
|
|
|
#include "videowin.h"
|
2022-08-30 23:07:13 +08:00
|
|
|
|
#include <QLabel>
|
2022-08-25 18:43:03 +08:00
|
|
|
|
#include <QPushButton>
|
|
|
|
|
#include <QToolButton>
|
|
|
|
|
#include <QComboBox>
|
|
|
|
|
#include <QMouseEvent>
|
|
|
|
|
#include <QPainter>
|
|
|
|
|
#include <QPainterPath>
|
|
|
|
|
#include <QTimer>
|
2022-10-12 18:17:10 +08:00
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QDebug>
|
2022-12-16 15:08:53 +08:00
|
|
|
|
#include "table.h"
|
|
|
|
|
#include "globalfunc.h"
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include "basewin.h"
|
|
|
|
|
#include <QSettings>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QApplication>
|
2022-08-30 23:07:13 +08:00
|
|
|
|
|
2022-08-25 18:43:03 +08:00
|
|
|
|
class ImgBtn : public QToolButton {
|
|
|
|
|
public:
|
2022-09-06 23:40:02 +08:00
|
|
|
|
ImgBtn() {
|
|
|
|
|
setStyleSheet("QToolButton{border: none; padding-top: 4px;}");
|
2022-08-25 18:43:03 +08:00
|
|
|
|
}
|
2022-09-06 23:40:02 +08:00
|
|
|
|
bool isEnter{false};
|
2022-08-25 18:43:03 +08:00
|
|
|
|
protected:
|
2022-09-06 23:40:02 +08:00
|
|
|
|
void resizeEvent(QResizeEvent *event) override {
|
|
|
|
|
QToolButton::resizeEvent(event);
|
|
|
|
|
if(isEnter) setIconSize(QSize(width(), width()));
|
|
|
|
|
else setIconSize(QSize(width()-8, width()-8));
|
|
|
|
|
}
|
|
|
|
|
void enterEvent(QEvent *event) override {
|
|
|
|
|
QToolButton::enterEvent(event);
|
2022-08-25 18:43:03 +08:00
|
|
|
|
setStyleSheet("QToolButton{border: none;}");
|
|
|
|
|
setIconSize(QSize(width(), width()));
|
|
|
|
|
}
|
2022-09-06 23:40:02 +08:00
|
|
|
|
void leaveEvent(QEvent *event) override {
|
|
|
|
|
QToolButton::leaveEvent(event);
|
2022-08-25 18:43:03 +08:00
|
|
|
|
setIconSize(QSize(width()-8, width()-8));
|
|
|
|
|
setStyleSheet("QToolButton{border: none; padding-top: 4px;}");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline QLabel *newImgLabel(QPixmap pixmap){
|
|
|
|
|
QLabel *lb = new QLabel();
|
|
|
|
|
lb->setPixmap(pixmap);
|
|
|
|
|
return lb;
|
|
|
|
|
}
|
|
|
|
|
inline QLabel *newSubLabel(QString txt){
|
|
|
|
|
QLabel *lb = new QLabel(txt);
|
|
|
|
|
lb->setAlignment(Qt::AlignCenter);
|
|
|
|
|
return lb;
|
|
|
|
|
}
|
2022-09-06 23:40:02 +08:00
|
|
|
|
ImgBtn *addImg(QHBoxLayout *parent, const QIcon &icon, const QString &text) {
|
|
|
|
|
auto imgBtn = new ImgBtn();
|
|
|
|
|
imgBtn->setIcon(icon);
|
|
|
|
|
imgBtn->setText(text);
|
2022-08-25 18:43:03 +08:00
|
|
|
|
imgBtn->setFixedSize(76, 100);
|
|
|
|
|
imgBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
|
|
|
|
parent->addWidget(imgBtn);
|
2022-09-06 23:40:02 +08:00
|
|
|
|
return imgBtn;
|
2022-08-25 18:43:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MainWin::MainWin() {
|
2022-12-16 15:08:53 +08:00
|
|
|
|
setWindowTitle("LedSet Express");
|
2022-08-25 18:43:03 +08:00
|
|
|
|
resize(860, 540);
|
|
|
|
|
|
|
|
|
|
auto vBox = new QVBoxLayout(center);
|
|
|
|
|
vBox->setContentsMargins(0,0,0,0);
|
|
|
|
|
|
|
|
|
|
vBox->addLayout(addBtns(new QHBoxLayout()));
|
|
|
|
|
|
|
|
|
|
QHBoxLayout *imgsBar = new QHBoxLayout();
|
2022-09-06 23:40:02 +08:00
|
|
|
|
auto btnImg = addImg(imgsBar, QPixmap(":/imgs/fast.png").scaledToWidth(128, Qt::SmoothTransformation), "快速调屏");
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
|
|
|
|
(new Fast(this))->show();
|
|
|
|
|
});
|
2022-12-16 15:08:53 +08:00
|
|
|
|
btnImg = addImg(imgsBar, QPixmap(":/imgs/expert.png").scaledToWidth(128, Qt::SmoothTransformation), tr("专家调屏"));
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
|
|
|
|
(new ExpertWin(this))->show();
|
|
|
|
|
});
|
2022-12-16 15:08:53 +08:00
|
|
|
|
btnImg = addImg(imgsBar, QPixmap(":/imgs/bright.png").scaledToWidth(128, Qt::SmoothTransformation), tr("亮度控制"));
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
|
|
|
|
(new BrightWin(this))->show();
|
|
|
|
|
});
|
2022-12-16 15:08:53 +08:00
|
|
|
|
btnImg = addImg(imgsBar, QPixmap(":/imgs/correct.png").scaledToWidth(128, Qt::SmoothTransformation), tr("相机矫正"));
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
|
|
|
|
|
|
|
|
|
});
|
2022-12-16 15:08:53 +08:00
|
|
|
|
btnImg = addImg(imgsBar, QPixmap(":/imgs/monitor.png").scaledToWidth(128, Qt::SmoothTransformation), tr("屏体监控"));
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
|
|
|
|
|
|
|
|
|
});
|
2022-12-16 15:08:53 +08:00
|
|
|
|
btnImg = addImg(imgsBar, QPixmap(":/imgs/multi.png").scaledToWidth(128, Qt::SmoothTransformation), tr("多功能卡"));
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
|
|
|
|
//win->move(win->x()-1, win->y());
|
|
|
|
|
});
|
2022-12-16 15:08:53 +08:00
|
|
|
|
btnImg = addImg(imgsBar, QPixmap(":/imgs/video.png").scaledToWidth(128, Qt::SmoothTransformation), tr("协议调试"));
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
2022-12-16 15:08:53 +08:00
|
|
|
|
if(pcapRe != 0 && pcapSend != 0)
|
|
|
|
|
{
|
|
|
|
|
auto ins = new PcapWin(pcapRe, pcapSend, this);
|
|
|
|
|
if(ins) ins->show();
|
|
|
|
|
}
|
2022-08-25 18:43:03 +08:00
|
|
|
|
});
|
2022-12-16 15:08:53 +08:00
|
|
|
|
btnImg = addImg(imgsBar, QPixmap(":/imgs/idea.png").scaledToWidth(128, Qt::SmoothTransformation), tr("模拟同步"));
|
2022-08-25 18:43:03 +08:00
|
|
|
|
connect(btnImg, &ImgBtn::clicked, this, [=](){
|
2022-12-16 15:08:53 +08:00
|
|
|
|
auto ins = VideoWin::newIns(net_name, this);
|
|
|
|
|
if(ins) ins->show();
|
2022-08-25 18:43:03 +08:00
|
|
|
|
});
|
|
|
|
|
vBox->addLayout(imgsBar);
|
2022-12-16 15:08:53 +08:00
|
|
|
|
vBox->addSpacing(9);
|
2022-08-25 18:43:03 +08:00
|
|
|
|
vBox->addWidget(new QLabel(" 硬件信息"));
|
|
|
|
|
|
2022-12-16 15:08:53 +08:00
|
|
|
|
table = new Table{
|
|
|
|
|
{"type", "发送卡型号"},
|
|
|
|
|
{"name", "名称"},
|
|
|
|
|
{"link", "连接方式"},
|
|
|
|
|
{"vcs", "接收卡数量"},
|
|
|
|
|
{"Pinfo", "网口统计P1~Pn"},
|
|
|
|
|
{"Oinfo", "其他信息", QHeaderView::Stretch},
|
|
|
|
|
};
|
|
|
|
|
vBox->addWidget(table);
|
|
|
|
|
|
|
|
|
|
auto hstatus = new QHBoxLayout;
|
|
|
|
|
hstatus->addWidget(new QLabel(tr("版本:221114")));
|
|
|
|
|
hstatus->addStretch();
|
2022-08-25 18:43:03 +08:00
|
|
|
|
|
2022-12-16 15:08:53 +08:00
|
|
|
|
auto btnNetSelect = new QPushButton("通讯选择");
|
|
|
|
|
btnNetSelect->setMinimumWidth(80);
|
|
|
|
|
connect(btnNetSelect, &QPushButton::clicked, this, [this] {
|
|
|
|
|
auto name = getNetDev(this, "");
|
|
|
|
|
if(name.isEmpty()) return;
|
|
|
|
|
//PCAP_OPENFLAG_DATATX_UDP:2,它定义了数据传输(假如是远程抓包)是否用UDP协议来处理。
|
|
|
|
|
//PCAP_OPENFLAG_NOCAPTURE_RPCAP:4,它定义了远程探测器是否捕获它自己产生的数据包。
|
|
|
|
|
char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
|
|
|
|
|
auto pcapR = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS|4|8|16, 50, errbuf);
|
|
|
|
|
if(pcapR == 0) {
|
|
|
|
|
QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
auto pcapS = pcap_open_live(name.data(), 65536, 0, 50, errbuf);
|
|
|
|
|
if(pcapS == 0) {
|
|
|
|
|
QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(pcapRe) pcap_close(pcapRe);
|
|
|
|
|
if(pcapSend) pcap_close(pcapSend);
|
|
|
|
|
pcapRe = pcapR;
|
|
|
|
|
pcapSend = pcapS;
|
|
|
|
|
QSettings config(QApplication::applicationDirPath()+"/ledset.config", QSettings::IniFormat);//QDir::currentPath()为exe位置
|
|
|
|
|
config.beginGroup("GLOBAL");
|
|
|
|
|
config.setValue("net_name", net_name = name);
|
|
|
|
|
config.endGroup();
|
|
|
|
|
});
|
|
|
|
|
hstatus->addWidget(btnNetSelect);
|
|
|
|
|
|
|
|
|
|
auto btnRefresh = new QPushButton(tr("刷新"));
|
|
|
|
|
btnRefresh->setMinimumWidth(80);
|
|
|
|
|
connect(btnRefresh, &QPushButton::clicked, this, [this] {
|
|
|
|
|
auto bytes = QByteArray::fromHex("55 55 01 AD 00 01 FF FF FF FF 00 00 00 00 B0 00 01 00 00 00 3B 11 0A 6C 00 00 00 00 21 44 DF 1C");
|
|
|
|
|
if(pcap_sendpacket(pcapSend, (u_char*)bytes.data(), bytes.size())) {
|
|
|
|
|
QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcapSend));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
hstatus->addWidget(btnRefresh);
|
|
|
|
|
|
|
|
|
|
vBox->addLayout(hstatus);
|
|
|
|
|
|
|
|
|
|
QSettings config(QApplication::applicationDirPath()+"/ledset.config", QSettings::IniFormat);
|
|
|
|
|
config.beginGroup("GLOBAL");//保存数据
|
|
|
|
|
auto name = config.value("net_name").toByteArray();
|
|
|
|
|
name = getNetDev(this, name);
|
|
|
|
|
if(! name.isEmpty()) {
|
|
|
|
|
char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
|
|
|
|
|
pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS|4|8|16, 50, errbuf);
|
|
|
|
|
if(pcapRe == 0) QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
|
|
|
|
|
else {
|
|
|
|
|
pcapSend = pcap_open_live(name.data(), 65536, 0, 50, errbuf);
|
|
|
|
|
if(pcapSend == 0) QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
|
|
|
|
|
else config.setValue("net_name", net_name = name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
config.endGroup();
|
2022-08-25 18:43:03 +08:00
|
|
|
|
}
|
2022-12-16 15:08:53 +08:00
|
|
|
|
|
|
|
|
|
MainPcapThread::MainPcapThread(pcap_t *pcap) : pcap(pcap) {
|
|
|
|
|
connect(this, &QThread::finished, this, &QThread::deleteLater);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainPcapThread::run() {
|
|
|
|
|
pcap_pkthdr *header;
|
|
|
|
|
const u_char *data;
|
|
|
|
|
int res;
|
|
|
|
|
while((res = pcap_next_ex(pcap, &header, &data)) >= 0) {
|
|
|
|
|
if(status==2) return;
|
|
|
|
|
if(status==1 || res == 0) continue; //超时
|
|
|
|
|
//if(data[0]!=0x55 || data[1]!=0x55 || (data[6] ==0xff && data[7] ==0xff && data[8] == 0xff && data[9] == 0xff)) continue;
|
|
|
|
|
if(data[0]!=0x55 || data[1]!=0x55 )
|
|
|
|
|
continue;
|
|
|
|
|
emit onMsg(data,header->caplen);
|
|
|
|
|
}
|
|
|
|
|
emit onError(pcap_geterr(pcap));
|
|
|
|
|
}
|
|
|
|
|
void MainWin::ProNetData(const u_char *data,int len)
|
|
|
|
|
{
|
|
|
|
|
if(table != nullptr)
|
|
|
|
|
{
|
|
|
|
|
uint32_t pio=data[14] << 24 | data[15] <<16 | data[16] <<8 | data[17] ;
|
|
|
|
|
uint8_t srv = data[3];
|
|
|
|
|
if(srv == 0xEA && pio == 0xB0000101 )
|
|
|
|
|
{
|
|
|
|
|
table->setRowCount(1);
|
|
|
|
|
uint16_t pIndex = data[10]<<8 | data[11];
|
|
|
|
|
uint32_t virtualVCM = pIndex ;
|
|
|
|
|
uint32_t vcsNum = data[24] << 24 | data[25] <<16 | data[26] <<8 | data[27] ;
|
|
|
|
|
table->setValue(0, "type", tr("虚拟设备"));
|
|
|
|
|
table->setValue(0, "name", tr("网口:")+QString::number(virtualVCM));
|
|
|
|
|
table->setValue(0, "link", "千兆网直连");
|
|
|
|
|
table->setValue(0, "vcs", QString::number(vcsNum));
|
|
|
|
|
table->setValue(0, "Pinfo", "P:"+QString::number(virtualVCM));
|
|
|
|
|
table->setValue(0, "Oinfo", "备注:可直接配屏,无需发送卡");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
QString data_str;
|
|
|
|
|
for(uint i=0; i<len; i++) {
|
|
|
|
|
data_str.append(QString::asprintf("%.2x ", data[i]));
|
|
|
|
|
}
|
|
|
|
|
// QMessageBox::critical(this, "net data", data_str);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|