ledset增加地址映射

This commit is contained in:
gangphon 2022-12-16 15:08:53 +08:00
parent bdfb6273d2
commit 5f89e6d8b8
30 changed files with 2042 additions and 703 deletions

View File

@ -20,12 +20,18 @@ BaseWinBase::BaseWinBase(QWidget *that) : that(that) {
QBoxLayout *BaseWinBase::addBtns(QBoxLayout *hBox) { QBoxLayout *BaseWinBase::addBtns(QBoxLayout *hBox) {
if(hBox->count()==0) hBox->addStretch(); if(hBox->count()==0) hBox->addStretch();
auto btn = new QPushButton("--"); auto btn = new QPushButton("");
btn->setProperty("ss", "min"); btn->setIcon(QIcon(":/imgs/macos-minimize.png"));
btn->setIconSize(QSize(20,20));
btn->setStyleSheet("padding: 1;border:none;");
//btn->setProperty("ss", "min");
that->connect(btn, &QPushButton::clicked, that, &BaseWin::showMinimized); that->connect(btn, &QPushButton::clicked, that, &BaseWin::showMinimized);
hBox->addWidget(btn); hBox->addWidget(btn);
btn = new QPushButton("X"); btn = new QPushButton("");
btn->setProperty("ss", "close"); btn->setIcon(QIcon(":/imgs/close.png"));
btn->setIconSize(QSize(20,20));
btn->setStyleSheet("padding: 1;border:none;");
//btn->setProperty("ss", "close");
that->connect(btn, &QPushButton::clicked, that, &BaseWin::close); that->connect(btn, &QPushButton::clicked, that, &BaseWin::close);
hBox->addWidget(btn); hBox->addWidget(btn);
return hBox; return hBox;

View File

@ -12,7 +12,7 @@
BrightWin::BrightWin(QWidget *parent) : BaseWin{parent} { BrightWin::BrightWin(QWidget *parent) : BaseWin{parent} {
setWindowModality(Qt::WindowModal); setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle("亮度控制"); setWindowTitle(tr("亮度控制"));
resize(620, 700); resize(620, 700);
auto vBox = new QVBoxLayout(center); auto vBox = new QVBoxLayout(center);
@ -74,7 +74,7 @@ BrightWin::BrightWin(QWidget *parent) : BaseWin{parent} {
hBox = new QHBoxLayout(); hBox = new QHBoxLayout();
hBox->addStretch(); hBox->addStretch();
auto btnSave = new QPushButton("固化"); auto btnSave = new QPushButton(tr("固化"));
btnSave->setMinimumWidth(80); btnSave->setMinimumWidth(80);
hBox->addWidget(btnSave); hBox->addWidget(btnSave);
@ -157,7 +157,7 @@ BrightWin::BrightWin(QWidget *parent) : BaseWin{parent} {
hBox = new QHBoxLayout(); hBox = new QHBoxLayout();
hBox->addStretch(); hBox->addStretch();
btnSave = new QPushButton("固化"); btnSave = new QPushButton(tr("固化"));
btnSave->setMinimumWidth(80); btnSave->setMinimumWidth(80);
hBox->addWidget(btnSave); hBox->addWidget(btnSave);

View File

@ -9,7 +9,8 @@
#include <QHeaderView> #include <QHeaderView>
#include <QMouseEvent> #include <QMouseEvent>
#include <QDebug> #include <QDebug>
#include <math.h>
#define M_PI 3.14159265358979323846
QColor cardColors[] {QColor(0xff2222), QColor(0xffaa00), QColor(0x00bb00), QColor(0x00bbcc), QColor(0x0044ff), QColor(0xffffff), QColor(0xffff00)}; QColor cardColors[] {QColor(0xff2222), QColor(0xffaa00), QColor(0x00bb00), QColor(0x00bbcc), QColor(0x0044ff), QColor(0xffffff), QColor(0xffff00)};
ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} { ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
@ -28,7 +29,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
auto vvv = new QVBoxLayout(leftWgt); auto vvv = new QVBoxLayout(leftWgt);
vvv->setContentsMargins(0,0,0,0); vvv->setContentsMargins(0,0,0,0);
auto gBox = new QGroupBox("起始位置"); auto gBox = new QGroupBox(tr("起始位置"));
vvv->addWidget(gBox); vvv->addWidget(gBox);
auto fdX = new QSpinBox; auto fdX = new QSpinBox;
@ -36,14 +37,14 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
{ {
auto hhh = new QHBoxLayout(gBox); auto hhh = new QHBoxLayout(gBox);
auto lb = new QLabel("X坐标: "); auto lb = new QLabel(tr("X坐标: "));
hhh->addWidget(lb); hhh->addWidget(lb);
fdX->setRange(0, 99999); fdX->setRange(0, 99999);
fdX->setValue(0); fdX->setValue(0);
hhh->addWidget(fdX); hhh->addWidget(fdX);
lb = new QLabel("Y坐标: "); lb = new QLabel(tr("Y坐标: "));
hhh->addWidget(lb); hhh->addWidget(lb);
fdY->setRange(0, 99999); fdY->setRange(0, 99999);
@ -51,7 +52,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
hhh->addWidget(fdY); hhh->addWidget(fdY);
} }
gBox = new QGroupBox("接收卡设置"); gBox = new QGroupBox(tr("接收卡设置"));
vvv->addWidget(gBox); vvv->addWidget(gBox);
auto fdCardColNum = new QSpinBox; auto fdCardColNum = new QSpinBox;
@ -61,7 +62,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
auto hhh = new QHBoxLayout; auto hhh = new QHBoxLayout;
vBox->addLayout(hhh); vBox->addLayout(hhh);
auto lb = new QLabel("卡列数: "); auto lb = new QLabel(tr("卡列数: "));
hhh->addWidget(lb); hhh->addWidget(lb);
fdCardColNum->setRange(0, 9999); fdCardColNum->setRange(0, 9999);
@ -71,7 +72,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
// }); // });
hhh->addWidget(fdCardColNum); hhh->addWidget(fdCardColNum);
lb = new QLabel("卡行数: "); lb = new QLabel(tr("卡行数: "));
hhh->addWidget(lb); hhh->addWidget(lb);
fdCardRowNum->setRange(0, 9999); fdCardRowNum->setRange(0, 9999);
@ -81,7 +82,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
vBox->addLayout(hhh = new QHBoxLayout); vBox->addLayout(hhh = new QHBoxLayout);
lb = new QLabel("卡宽度: "); lb = new QLabel(tr("卡宽度: "));
hhh->addWidget(lb); hhh->addWidget(lb);
fdCardWidth = new QSpinBox; fdCardWidth = new QSpinBox;
@ -89,7 +90,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
fdCardWidth->setValue(128); fdCardWidth->setValue(128);
hhh->addWidget(fdCardWidth); hhh->addWidget(fdCardWidth);
lb = new QLabel("卡高度: "); lb = new QLabel(tr("卡高度: "));
hhh->addWidget(lb); hhh->addWidget(lb);
fdCardHeight = new QSpinBox; fdCardHeight = new QSpinBox;
@ -98,7 +99,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
hhh->addWidget(fdCardHeight); hhh->addWidget(fdCardHeight);
} }
gBox = new QGroupBox("网口选择"); gBox = new QGroupBox(tr("网口选择"));
vvv->addWidget(gBox); vvv->addWidget(gBox);
auto hhh = new QHBoxLayout(gBox); auto hhh = new QHBoxLayout(gBox);
@ -115,7 +116,7 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
fdNet->addButton(bn, i); fdNet->addButton(bn, i);
} }
gBox = new QGroupBox("快速串线:"); gBox = new QGroupBox(tr("快速串线:"));
gBox->setStyleSheet("QToolButton {border: none; }"); gBox->setStyleSheet("QToolButton {border: none; }");
vvv->addWidget(gBox); vvv->addWidget(gBox);
{ {
@ -169,14 +170,14 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
vvv->addLayout(hhh = new QHBoxLayout); vvv->addLayout(hhh = new QHBoxLayout);
auto bnRefresh = new QPushButton("重新开始"); auto bnRefresh = new QPushButton(tr("重新开始"));
connect(bnRefresh, &QPushButton::clicked, this, [this] { connect(bnRefresh, &QPushButton::clicked, this, [this] {
table->clearContents(); table->clearContents();
for(int i=0; i<netss.size(); i++) if(! netss[i].isEmpty()) netss[i].clear(); for(int i=0; i<netss.size(); i++) if(! netss[i].isEmpty()) netss[i].clear();
}); });
hhh->addWidget(bnRefresh); hhh->addWidget(bnRefresh);
auto bnBack = new QPushButton("后退"); auto bnBack = new QPushButton(tr("后退"));
connect(bnBack, &QPushButton::clicked, this, &ExpertScreenConnWin::connBack); connect(bnBack, &QPushButton::clicked, this, &ExpertScreenConnWin::connBack);
hhh->addWidget(bnBack); hhh->addWidget(bnBack);
@ -189,8 +190,10 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} {
table->setEditTriggers(QAbstractItemView::NoEditTriggers); table->setEditTriggers(QAbstractItemView::NoEditTriggers);
table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
table->horizontalHeader()->setDefaultSectionSize(90); table->horizontalHeader()->setDefaultSectionSize(90);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
table->verticalHeader()->setDefaultAlignment(Qt::AlignCenter); table->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
table->verticalHeader()->setDefaultSectionSize(90); table->verticalHeader()->setDefaultSectionSize(90);
table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
table->verticalHeader()->setMinimumWidth(30); table->verticalHeader()->setMinimumWidth(30);
table->setSelectionMode(QTableWidget::NoSelection); table->setSelectionMode(QTableWidget::NoSelection);
connect(table, &QTableWidget::currentCellChanged, this, &ExpertScreenConnWin::conn); connect(table, &QTableWidget::currentCellChanged, this, &ExpertScreenConnWin::conn);
@ -205,9 +208,11 @@ void ExpertScreenConnWin::conn(int row, int column) {
if(item) return; if(item) return;
auto netIdx = fdNet->checkedId(); auto netIdx = fdNet->checkedId();
netss[netIdx].append(QPoint(column, row)); netss[netIdx].append(QPoint(column, row));
item = new QTableWidgetItem("网口: "+QString::number(netIdx+1)+"\n接收卡: "+QString::number(netss[netIdx].size())+"\n宽度: "+QString::number(fdCardWidth->value())+"\n高度: "+QString::number(fdCardHeight->value())); item = new QTableWidgetItem("网口: "+QString::number(netIdx+1)+"\n"+tr("接收卡: ")+QString::number(netss[netIdx].size())+"\n"+tr("宽度: ")+QString::number(fdCardWidth->value())+"\n高度: "+QString::number(fdCardHeight->value()));
auto color = cardColors[netIdx % (sizeof(cardColors)/sizeof(cardColors[0]))]; auto color = cardColors[netIdx % (sizeof(cardColors)/sizeof(cardColors[0]))];
item->setForeground(color); item->setForeground(QColor(255,255,255));
color.setAlpha(100);
item->setBackground(color);
item->setData(Qt::UserRole, netIdx); item->setData(Qt::UserRole, netIdx);
table->setItem(row, column, item); table->setItem(row, column, item);
table->update(); table->update();
@ -227,12 +232,17 @@ void CardTable::paintEvent(QPaintEvent *event) {
for(int i=0; i<win->netss.size(); i++) { for(int i=0; i<win->netss.size(); i++) {
auto size = win->netss[i].size(); auto size = win->netss[i].size();
if(size < 2) continue; if(size < 2) continue;
painter.setPen(QPen(cardColors[i % (sizeof(cardColors)/sizeof(cardColors[0]))], 2)); QColor a=cardColors[i % (sizeof(cardColors)/sizeof(cardColors[0]))];
//QColor b=QColor(255-a.red(),255-a.green(),255-a.blue(),200);
QColor b=QColor(a.red(),a.green(),a.blue(),255);
QPen pen=QPen(b);
int off = 45 + (i+1)/2 * (i%2 ? -4 : 4); int off = 45 + (i+1)/2 * (i%2 ? -4 : 4);
for(int j=1; j<size; j++) { for(int j=1; j<size; j++) {
auto point1 = win->netss[i][j-1]; auto point1 = win->netss[i][j-1];
auto point2 = win->netss[i][j]; auto point2 = win->netss[i][j];
painter.drawLine(point1.x()*90+off, point1.y()*90+off, point2.x()*90+off, point2.y()*90+off); DrawLineWithArrow(painter,pen,QPoint(point1.x()*90+off, point1.y()*90+off), QPoint(point2.x()*90+off, point2.y()*90+off));
} }
} }
} }
@ -243,3 +253,27 @@ void CardTable::mouseReleaseEvent(QMouseEvent *event) {
QTableWidget::mouseReleaseEvent(event); QTableWidget::mouseReleaseEvent(event);
if(event->button() == Qt::RightButton) win->connBack(); if(event->button() == Qt::RightButton) win->connBack();
} }
void CardTable::DrawLineWithArrow(QPainter& painter, QPen pen, QPoint start, QPoint end)
{
painter.setRenderHint(QPainter::Antialiasing, true);
qreal arrowSize = 15;
pen.setWidth(2);
painter.setPen(pen);
painter.setBrush(pen.color());
QLineF line(end, start);
double angle = atan2(-line.dy(), line.dx());
QPointF arrowP1 = line.p1() + QPointF(sin(angle + M_PI / 3) * arrowSize,
cos(angle + M_PI / 3) * arrowSize);
QPointF arrowP2 = line.p1() + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize,
cos(angle + M_PI - M_PI / 3) * arrowSize);
QPolygonF arrowHead;
arrowHead.clear();
arrowHead << line.p1() << arrowP1 << arrowP2;
painter.drawLine(line);
painter.drawPolygon(arrowHead);
}

View File

@ -24,6 +24,9 @@ public:
explicit CardTable(QWidget *parent = nullptr) : QTableWidget{parent} {} explicit CardTable(QWidget *parent = nullptr) : QTableWidget{parent} {}
CardTable(int rows, int columns, QWidget *parent = nullptr) : QTableWidget{rows, columns, parent} {} CardTable(int rows, int columns, QWidget *parent = nullptr) : QTableWidget{rows, columns, parent} {}
ExpertScreenConnWin *win; ExpertScreenConnWin *win;
private:
void DrawLineWithArrow(QPainter& painter, QPen pen, QPoint start, QPoint end);
protected: protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;

View File

@ -14,12 +14,20 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent} { ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{expertWin}, expertWin(expertWin) {
setWindowModality(Qt::WindowModal); setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle("智能走点参数配置"); setWindowTitle(tr("智能走点参数配置"));
resize(900, 600); resize(900, 600);
ModuleWidth = expertWin->mModule["ModuleWidth"].toInt();
ModuleHeight = expertWin->mModule["ModuleHeight"].toInt();
GroupNum = expertWin->mModule["GroupNum"].toInt();
ScanNum = expertWin->mModule["ScanNum"].toInt();
ChipType = expertWin->mModule["ChipType"].toString();
DecodeMode = expertWin->mModule["DecodeMode"].toString();
GroupMode = expertWin->mModule["GroupMode"].toString();
auto vBox = new QVBoxLayout(center); auto vBox = new QVBoxLayout(center);
vBox->setContentsMargins(0,0,0,0); vBox->setContentsMargins(0,0,0,0);
vBox->setSpacing(3); vBox->setSpacing(3);
@ -35,7 +43,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
auto vBox = new QVBoxLayout(page); auto vBox = new QVBoxLayout(page);
vBox->setContentsMargins(50, 50, 6, 6); vBox->setContentsMargins(50, 50, 6, 6);
auto lb = new QLabel("基本参数"); auto lb = new QLabel(tr("基本参数"));
bkBlue = lb->palette(); bkBlue = lb->palette();
bkBlue.setColor(QPalette::WindowText, QColor(0x5599ff)); bkBlue.setColor(QPalette::WindowText, QColor(0x5599ff));
lb->setPalette(bkBlue); lb->setPalette(bkBlue);
@ -48,7 +56,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
auto vvv = new QVBoxLayout; auto vvv = new QVBoxLayout;
auto hhhh = new QHBoxLayout; auto hhhh = new QHBoxLayout;
lb = new QLabel("模组宽度: "); lb = new QLabel(tr("模组宽度: "));
hhhh->addWidget(lb); hhhh->addWidget(lb);
fdModuleWidth = new QSpinBox; fdModuleWidth = new QSpinBox;
@ -60,7 +68,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
vvv->addSpacing(30); vvv->addSpacing(30);
hhhh = new QHBoxLayout; hhhh = new QHBoxLayout;
lb = new QLabel("模组高度: "); lb = new QLabel(tr("模组高度: "));
hhhh->addWidget(lb); hhhh->addWidget(lb);
fdModuleHeight = new QSpinBox; fdModuleHeight = new QSpinBox;
@ -72,7 +80,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
vvv->addSpacing(30); vvv->addSpacing(30);
hhhh = new QHBoxLayout; hhhh = new QHBoxLayout;
lb = new QLabel("数据组数: "); lb = new QLabel(tr("数据组数: "));
hhhh->addWidget(lb); hhhh->addWidget(lb);
fdGroupNum = new QSpinBox; fdGroupNum = new QSpinBox;
@ -90,7 +98,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
auto vvv = new QVBoxLayout; auto vvv = new QVBoxLayout;
auto hhhh = new QHBoxLayout; auto hhhh = new QHBoxLayout;
lb = new QLabel("驱动芯片: "); lb = new QLabel(tr("驱动芯片: "));
hhhh->addWidget(lb); hhhh->addWidget(lb);
fdChipType = new QComboBox; fdChipType = new QComboBox;
@ -101,25 +109,25 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
vvv->addSpacing(30); vvv->addSpacing(30);
hhhh = new QHBoxLayout; hhhh = new QHBoxLayout;
lb = new QLabel("译码方式: "); lb = new QLabel(tr("译码方式: "));
hhhh->addWidget(lb); hhhh->addWidget(lb);
fdDecodeMode = new QComboBox; fdDecodeMode = new QComboBox;
fdDecodeMode->addItem("138译码"); fdDecodeMode->addItem(tr("138译码"));
hhhh->addWidget(fdDecodeMode); hhhh->addWidget(fdDecodeMode);
vvv->addLayout(hhhh); vvv->addLayout(hhhh);
vvv->addSpacing(30); vvv->addSpacing(30);
hhhh = new QHBoxLayout; hhhh = new QHBoxLayout;
lb = new QLabel("分组方式: "); lb = new QLabel(tr("分组方式: "));
hhhh->addWidget(lb); hhhh->addWidget(lb);
fdGroupMode = new QComboBox; fdGroupMode = new QComboBox;
fdGroupMode->addItem("三线并行"); fdGroupMode->addItem(tr("三线并行"));
fdGroupMode->addItem("三色1点串"); fdGroupMode->addItem(tr("三色1点串"));
fdGroupMode->addItem("三色8点串"); fdGroupMode->addItem(tr("三色8点串"));
fdGroupMode->addItem("三色16点串"); fdGroupMode->addItem(tr("三色16点串"));
hhhh->addWidget(fdGroupMode); hhhh->addWidget(fdGroupMode);
vvv->addLayout(hhhh); vvv->addLayout(hhhh);
@ -137,7 +145,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
auto vBox = new QVBoxLayout(page); auto vBox = new QVBoxLayout(page);
vBox->setContentsMargins(50, 50, 6, 6); vBox->setContentsMargins(50, 50, 6, 6);
auto lb = new QLabel("扫描行数"); auto lb = new QLabel(tr("扫描行数"));
lb->setPalette(bkBlue); lb->setPalette(bkBlue);
vBox->addWidget(lb); vBox->addWidget(lb);
vBox->addSpacing(50); vBox->addSpacing(50);
@ -149,16 +157,16 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
auto vvv = new QVBoxLayout; auto vvv = new QVBoxLayout;
hBox->addLayout(vvv); hBox->addLayout(vvv);
lb = new QLabel("根据亮线的行/列数确定扫描行/列数: "); lb = new QLabel(tr("根据亮线的行/列数确定扫描行/列数: "));
vvv->addWidget(lb); vvv->addWidget(lb);
vvv->addSpacing(30); vvv->addSpacing(30);
auto hhhh = new QHBoxLayout; auto hhhh = new QHBoxLayout;
hhhh->addStretch(); hhhh->addStretch();
auto fdRow = new QRadioButton(""); auto fdRow = new QRadioButton(tr(""));
hhhh->addWidget(fdRow); hhhh->addWidget(fdRow);
hhhh->addStretch(); hhhh->addStretch();
auto fdCol = new QRadioButton(""); auto fdCol = new QRadioButton(tr(""));
hhhh->addWidget(fdCol); hhhh->addWidget(fdCol);
hhhh->addStretch(); hhhh->addStretch();
vvv->addLayout(hhhh); vvv->addLayout(hhhh);
@ -167,7 +175,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
hhhh = new QHBoxLayout; hhhh = new QHBoxLayout;
hhhh->addStretch(); hhhh->addStretch();
lb = new QLabel("亮线的行/列数: "); lb = new QLabel(tr("亮线的行/列数: "));
hhhh->addWidget(lb); hhhh->addWidget(lb);
auto fdNum = new QSpinBox; auto fdNum = new QSpinBox;
@ -185,7 +193,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
vvv = new QVBoxLayout; vvv = new QVBoxLayout;
hBox->addLayout(vvv); hBox->addLayout(vvv);
lb = new QLabel("芯片245版本: "); lb = new QLabel(tr("芯片245版本: "));
vvv->addWidget(lb); vvv->addWidget(lb);
vvv->addSpacing(30); vvv->addSpacing(30);
@ -209,36 +217,36 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
auto vBox = new QVBoxLayout(page); auto vBox = new QVBoxLayout(page);
vBox->setContentsMargins(50, 50, 6, 6); vBox->setContentsMargins(50, 50, 6, 6);
auto lb = new QLabel("数据线颜色"); auto lb = new QLabel(tr("数据线颜色"));
lb->setPalette(bkBlue); lb->setPalette(bkBlue);
vBox->addWidget(lb); vBox->addWidget(lb);
vBox->addSpacing(50); vBox->addSpacing(50);
lb = new QLabel("依次点击以下状态, 根据模组颜色选择对应颜色"); lb = new QLabel(tr("依次点击以下状态, 根据模组颜色选择对应颜色"));
vBox->addWidget(lb, 0, Qt::AlignCenter); vBox->addWidget(lb, 0, Qt::AlignCenter);
vBox->addSpacing(30); vBox->addSpacing(30);
auto hhhh = new QHBoxLayout; auto hhhh = new QHBoxLayout;
hhhh->addStretch(); hhhh->addStretch();
auto fdSta1 = new QRadioButton("状态1"); auto fdSta1 = new QRadioButton(tr("状态1"));
fdSta1->setChecked(true); fdSta1->setChecked(true);
hhhh->addWidget(fdSta1); hhhh->addWidget(fdSta1);
hhhh->addStretch(); hhhh->addStretch();
auto fdR1 = new QRadioButton(""); auto fdR1 = new QRadioButton(tr(""));
fdR1->setChecked(true); fdR1->setChecked(true);
hhhh->addWidget(fdR1); hhhh->addWidget(fdR1);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdG1 = new QRadioButton("绿"); auto fdG1 = new QRadioButton(tr("绿"));
hhhh->addWidget(fdG1); hhhh->addWidget(fdG1);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdB1 = new QRadioButton(""); auto fdB1 = new QRadioButton(tr(""));
hhhh->addWidget(fdB1); hhhh->addWidget(fdB1);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdNo1 = new QRadioButton(""); auto fdNo1 = new QRadioButton(tr(""));
hhhh->addWidget(fdNo1); hhhh->addWidget(fdNo1);
hhhh->addStretch(); hhhh->addStretch();
@ -247,24 +255,24 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
hhhh = new QHBoxLayout; hhhh = new QHBoxLayout;
hhhh->addStretch(); hhhh->addStretch();
auto fdSta2 = new QRadioButton("状态2"); auto fdSta2 = new QRadioButton(tr("状态2"));
hhhh->addWidget(fdSta2); hhhh->addWidget(fdSta2);
hhhh->addStretch(); hhhh->addStretch();
auto fdR2 = new QRadioButton(""); auto fdR2 = new QRadioButton(tr(""));
hhhh->addWidget(fdR2); hhhh->addWidget(fdR2);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdG2 = new QRadioButton("绿"); auto fdG2 = new QRadioButton(tr("绿"));
fdG2->setChecked(true); fdG2->setChecked(true);
hhhh->addWidget(fdG2); hhhh->addWidget(fdG2);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdB2 = new QRadioButton(""); auto fdB2 = new QRadioButton(tr(""));
hhhh->addWidget(fdB2); hhhh->addWidget(fdB2);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdNo2 = new QRadioButton(""); auto fdNo2 = new QRadioButton(tr(""));
hhhh->addWidget(fdNo2); hhhh->addWidget(fdNo2);
hhhh->addStretch(); hhhh->addStretch();
@ -273,24 +281,24 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
hhhh = new QHBoxLayout; hhhh = new QHBoxLayout;
hhhh->addStretch(); hhhh->addStretch();
auto fdSta3 = new QRadioButton("状态3"); auto fdSta3 = new QRadioButton(tr("状态3"));
hhhh->addWidget(fdSta3); hhhh->addWidget(fdSta3);
hhhh->addStretch(); hhhh->addStretch();
auto fdR3 = new QRadioButton(""); auto fdR3 = new QRadioButton(tr(""));
hhhh->addWidget(fdR3); hhhh->addWidget(fdR3);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdG3 = new QRadioButton("绿"); auto fdG3 = new QRadioButton(tr("绿"));
hhhh->addWidget(fdG3); hhhh->addWidget(fdG3);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdB3 = new QRadioButton(""); auto fdB3 = new QRadioButton(tr(""));
fdB3->setChecked(true); fdB3->setChecked(true);
hhhh->addWidget(fdB3); hhhh->addWidget(fdB3);
hhhh->addSpacing(20); hhhh->addSpacing(20);
auto fdNo3 = new QRadioButton(""); auto fdNo3 = new QRadioButton(tr(""));
hhhh->addWidget(fdNo3); hhhh->addWidget(fdNo3);
hhhh->addStretch(); hhhh->addStretch();
@ -348,19 +356,18 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
}); });
hhh->addWidget(btnUndo); hhh->addWidget(btnUndo);
auto btnAddVoid = new QPushButton("插入虚点"); auto btnAddVoid = new QPushButton(tr("插入虚点"));
btnAddVoid->setMinimumSize(90, 30); btnAddVoid->setMinimumSize(90, 30);
connect(btnAddVoid, &QPushButton::clicked, this, [this] { connect(btnAddVoid, &QPushButton::clicked, this, [this] {
virtualCnt++; virtualCnt++;
auto cnt = tableRow->columnCount(); auto cnt = tableRow->columnCount();
tableRow->setColumnCount(cnt+1); tableRow->setColumnCount(cnt+1);
tableRow->setItem(0, cnt, new QTableWidgetItem(QString::number(cnt+1))); tableRow->setItem(0, cnt, new QTableWidgetItem(QString::number(cnt+1)));
auto item = new QTableWidgetItem("×"); tableRow->setItem(1, cnt, new QTableWidgetItem("×"));
tableRow->setItem(1, cnt, item);
}); });
hhh->addWidget(btnAddVoid); hhh->addWidget(btnAddVoid);
auto btnReset = new QPushButton("重新走点"); auto btnReset = new QPushButton(tr("重新走点"));
btnReset->setMinimumSize(90, 30); btnReset->setMinimumSize(90, 30);
connect(btnReset, &QPushButton::clicked, this, [this] { connect(btnReset, &QPushButton::clicked, this, [this] {
table->clearContents(); table->clearContents();
@ -369,7 +376,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
}); });
hhh->addWidget(btnReset); hhh->addWidget(btnReset);
auto btnOK = new QPushButton("完成"); auto btnOK = new QPushButton(tr("完成"));
btnOK->setMinimumSize(90, 30); btnOK->setMinimumSize(90, 30);
connect(btnOK, &QPushButton::clicked, this, &ExpertSmartPointSetWin::save); connect(btnOK, &QPushButton::clicked, this, &ExpertSmartPointSetWin::save);
hhh->addWidget(btnOK); hhh->addWidget(btnOK);
@ -384,7 +391,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
table->verticalHeader()->setMinimumWidth(40); table->verticalHeader()->setMinimumWidth(40);
table->verticalHeader()->setDefaultAlignment(Qt::AlignCenter); table->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
connect(table, &QTableWidget::currentCellChanged, this, [this](int row, int col) { connect(table, &QTableWidget::currentCellChanged, this, [=](int row, int col) {
if(row < 0) return; if(row < 0) return;
auto item = table->item(row, col); auto item = table->item(row, col);
if(item) return; if(item) return;
@ -400,19 +407,22 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
table->setItem(row, col, item); table->setItem(row, col, item);
if(realCnt==ModuleWidth) { if(realCnt==ModuleWidth) {
scans.append({col, row}); scans.append({col, row});
QMessageBox::information(this, "提示", "列走完"); QMessageBox::information(this, tr("提示"), tr("列走完"));
} }
} else if(scans.size() < ScanNum) { } else if(scans.size() < ScanNum) {
scans.append({col, row}); scans.append({col, row});
auto size = scans.size(); auto size = scans.size();
item = new QTableWidgetItem("S"+QString::number(size)); item = new QTableWidgetItem("S"+QString::number(size));
table->setItem(row, col, item); table->setItem(row, col, item);
if(size==ScanNum) { if(size==ScanNum) {
QMessageBox::information(this, "提示", "行走完"); QMessageBox::information(this, tr("提示"), tr("行走完"));
save(); save();
} }
} }
}); });
vBox->addWidget(table); vBox->addWidget(table);
tableRow = new PointTable(2, 0); tableRow = new PointTable(2, 0);
@ -425,10 +435,10 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
tableRow->setMaximumHeight(80); tableRow->setMaximumHeight(80);
auto item = tableRow->verticalHeaderItem(0); auto item = tableRow->verticalHeaderItem(0);
if(item==0) tableRow->setVerticalHeaderItem(0, item = new QTableWidgetItem()); if(item==0) tableRow->setVerticalHeaderItem(0, item = new QTableWidgetItem());
item->setText("第一扫灯数:"); item->setText(tr("第一扫灯数:"));
item = tableRow->verticalHeaderItem(1); item = tableRow->verticalHeaderItem(1);
if(item==0) tableRow->setVerticalHeaderItem(1, item = new QTableWidgetItem()); if(item==0) tableRow->setVerticalHeaderItem(1, item = new QTableWidgetItem());
item->setText("实: 虚:"); item->setText(tr("实: 虚:"));
vBox->addWidget(tableRow); vBox->addWidget(tableRow);
} }
@ -437,11 +447,11 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
hBox->addStretch(); hBox->addStretch();
auto btnPrev = new QPushButton("上一步"); auto btnPrev = new QPushButton(tr("上一步"));
btnPrev->setMinimumSize(90, 30); btnPrev->setMinimumSize(90, 30);
hBox->addWidget(btnPrev); hBox->addWidget(btnPrev);
auto btnNext = new QPushButton("下一步"); auto btnNext = new QPushButton(tr("下一步"));
btnNext->setMinimumSize(90, 30); btnNext->setMinimumSize(90, 30);
hBox->addWidget(btnNext); hBox->addWidget(btnNext);
@ -451,7 +461,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
btnPrev->setEnabled(idx > 0); btnPrev->setEnabled(idx > 0);
btnNext->setEnabled(idx < stack->count()-1); btnNext->setEnabled(idx < stack->count()-1);
}); });
connect(btnNext, &QPushButton::clicked, this, [this, stack, btnPrev, btnNext] { connect(btnNext, &QPushButton::clicked, this, [=] {
auto idx = stack->currentIndex(); auto idx = stack->currentIndex();
if(idx==0) { if(idx==0) {
ModuleWidth = fdModuleWidth->value(); ModuleWidth = fdModuleWidth->value();
@ -478,10 +488,12 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(QWidget *parent) : BaseWin{parent
} }
void ExpertSmartPointSetWin::save() { void ExpertSmartPointSetWin::save() {
auto file = QFileDialog::getSaveFileName(this, "保存文件", QApplication::applicationDirPath()+QString("/ModuleFiles/1X2_3扫.module").arg(ModuleWidth).arg(ModuleHeight).arg(ScanNum)); auto file = QApplication::applicationDirPath()+"/temp.module";
if(file.isEmpty()) return;
QFile qFile(file); QFile qFile(file);
if(! qFile.open(QFile::WriteOnly)) return; if(! qFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
return;
}
QJsonObject obj; QJsonObject obj;
obj.insert("ModuleWidth", ModuleWidth); obj.insert("ModuleWidth", ModuleWidth);
obj.insert("ModuleHeight", ModuleHeight); obj.insert("ModuleHeight", ModuleHeight);
@ -490,77 +502,54 @@ void ExpertSmartPointSetWin::save() {
obj.insert("ChipType", ChipType); obj.insert("ChipType", ChipType);
obj.insert("DecodeMode", DecodeMode); obj.insert("DecodeMode", DecodeMode);
obj.insert("GroupMode", GroupMode); obj.insert("GroupMode", GroupMode);
QJsonArray Points; QJsonArray points;
for(int i=0; i<tableRow->columnCount(); i++) { auto cnt = tableRow->columnCount();
auto data = tableRow->item(1, i)->data(Qt::UserRole); if(cnt > ModuleWidth) {
if(! data.isValid()) Points.append(-1); auto add = (cnt+ModuleWidth-1) / ModuleWidth * ModuleWidth - cnt;
Points.append(data.toPoint().x()); for(int i=0; i<add; i++) points.append(-1);
} }
obj.insert("Points", Points); for(int i=cnt-1; i>=0; i--) {
auto data = tableRow->item(1, i)->data(Qt::UserRole);
points.append(data.isValid() ? data.toPoint().x() : -1);
}
obj.insert("Points", points);
QJsonArray Scans; QJsonArray Scans;
foreach(QPoint scan, scans) Scans.append(scan.y()); foreach(QPoint scan, scans) Scans.append(scan.y());
obj.insert("Scans", Scans); obj.insert("Scans", Scans);
qFile.write(QJsonDocument(obj).toJson(QJsonDocument::Indented)); auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
auto res = qFile.write(data);
qFile.close(); qFile.close();
QMessageBox::information(this, "保存成功", "保存成功"); if(res < 0) {
} QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
return;
void ExpertSmartPointSetWin::save2() { }
auto dlg = new BaseDlg(this); expertWin->mModule = obj;
dlg->setWindowTitle("保存设置");
expertWin->fdModuleWidth->setText(QString::number(ModuleWidth));
auto vBox = new VBox(dlg->center); expertWin->fdModuleHeight->setText(QString::number(ModuleHeight));
vBox->setContentsMargins(0,0,0,0); expertWin->fdGroupNum->setText(QString::number(GroupNum));
expertWin->fdScanNum->setText(QString::number(ScanNum));
auto hBox = new HBox(vBox); expertWin->fdChipType->setText(ChipType);
dlg->addBtns(hBox); expertWin->fdDecodeMode->setText(DecodeMode);
vBox->addSpacing(20); expertWin->fdCardWidth->setValue(ModuleWidth);
hBox = new HBox(vBox); expertWin->fdCardHeight->setValue(ModuleHeight);
hBox->addWidget(new QLabel("文件名称: "));
hBox->addWidget(new QLineEdit(QString("1X2_3扫").arg(ModuleWidth).arg(ModuleHeight).arg(ScanNum))); auto appDir = QApplication::applicationDirPath();
QDir(appDir).mkdir("ModuleFiles");
vBox->addSpacing(20); file = QFileDialog::getSaveFileName(this, tr("保存文件"), appDir+QString("/ModuleFiles/%1X%2_%3扫.module").arg(ModuleWidth).arg(ModuleHeight).arg(ScanNum), tr("Module file (*.module)"));
hBox = new HBox(vBox); if(file.isEmpty()) return;
hBox->addWidget(new QLabel("保存路径: ")); QFile qFile2(file);
if(! qFile2.open(QFile::WriteOnly)) {
auto dir = QApplication::applicationDirPath()+"/ModuleFiles"; QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
QDir(dir).mkpath("."); return;
auto fdDir = new QLineEdit(dir); }
fdDir->setMinimumWidth(400); res = qFile2.write(data);
hBox->addWidget(fdDir); qFile2.close();
if(res < 0) {
auto btnChoose = new QPushButton("选择路径"); QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
connect(btnChoose, &QPushButton::clicked, this, [this, fdDir] { return;
QFileInfo info(fdDir->text()); }
QFileDialog dlg(this, "选择存储文件的目录", info.path()); QMessageBox::information(this, tr("保存成功"), tr("保存成功"));
auto font = dlg.font(); close();
font.setPixelSize(12);
dlg.setFont(font);
dlg.setFileMode(QFileDialog::Directory);
dlg.setOptions(QFileDialog::ShowDirsOnly);
dlg.selectFile(info.fileName());
dlg.exec();
auto dir = dlg.selectedFiles();
if(! dir.isEmpty()) fdDir->setText(dir[0]);
//auto dir = QFileDialog::getExistingDirectory(this, "选择存储文件的目录", fdDir->text());
//if(! dir.isEmpty()) fdDir->setText(dir);
});
hBox->addWidget(btnChoose);
vBox->addSpacing(20);
hBox = new HBox(vBox);
hBox->addStretch();
auto btnOK = new QPushButton("完成");
btnOK->setMinimumSize(90, 30);
connect(btnOK, &QPushButton::clicked, dlg, &BaseDlg::accept);
hBox->addWidget(btnOK);
auto btnBack = new QPushButton("返回");
btnBack->setMinimumSize(90, 30);
connect(btnBack, &QPushButton::clicked, dlg, &BaseDlg::reject);
hBox->addWidget(btnBack);
dlg->exec();
} }

View File

@ -2,6 +2,7 @@
#define EXPERTSMARTPOINTSETWIN_H #define EXPERTSMARTPOINTSETWIN_H
#include "basewin.h" #include "basewin.h"
#include "expertwin.h"
#include <QSpinBox> #include <QSpinBox>
#include <QTableWidget> #include <QTableWidget>
#include <QComboBox> #include <QComboBox>
@ -19,9 +20,10 @@ public:
class ExpertSmartPointSetWin : public BaseWin { class ExpertSmartPointSetWin : public BaseWin {
Q_OBJECT Q_OBJECT
public: public:
explicit ExpertSmartPointSetWin(QWidget *parent = nullptr); explicit ExpertSmartPointSetWin(ExpertWin *parent = nullptr);
void save(); void save();
void save2();
ExpertWin *expertWin;
PointTable *table, *tableRow; PointTable *table, *tableRow;
int virtualCnt = 0; int virtualCnt = 0;
@ -29,7 +31,6 @@ public:
QSpinBox *fdModuleWidth, *fdModuleHeight, *fdGroupNum; QSpinBox *fdModuleWidth, *fdModuleHeight, *fdGroupNum;
QComboBox *fdChipType, *fdDecodeMode, *fdGroupMode; QComboBox *fdChipType, *fdDecodeMode, *fdGroupMode;
int ModuleWidth{16}, ModuleHeight{8}, GroupNum{2}, ScanNum{4}; int ModuleWidth{16}, ModuleHeight{8}, GroupNum{2}, ScanNum{4};
QString ChipType, DecodeMode, GroupMode; QString ChipType, DecodeMode, GroupMode;
}; };

View File

@ -1,17 +1,24 @@
#include "expertwin.h" #include "expertwin.h"
#include "gqt.h" #include "gqt.h"
#include "table.h" #include "table.h"
#include "crc.h"
#include "screenunit.h" #include "screenunit.h"
#include "expertsmartpointsetwin.h" #include "expertsmartpointsetwin.h"
#include "expertscreenconnwin.h" #include "expertscreenconnwin.h"
#include <QTabWidget> #include <QTabWidget>
#include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include <QPushButton> #include <QPushButton>
#include <QGroupBox> #include <QGroupBox>
#include <QStackedWidget> #include <QStackedWidget>
#include <QStackedLayout> #include <QStackedLayout>
#include <QRadioButton> #include <QRadioButton>
#include <QCheckBox>
#include <QApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QMessageBox>
#include <QFileDialog>
QColor colors[] {QColor(0xdd0000), QColor(0xdd6600), QColor(0x008800), QColor(0x008888), QColor(0x0000ff), QColor(0x777777), QColor(0xaaaaaa)}; QColor colors[] {QColor(0xdd0000), QColor(0xdd6600), QColor(0x008800), QColor(0x008888), QColor(0x0000ff), QColor(0x777777), QColor(0xaaaaaa)};
@ -78,12 +85,12 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
auto table = new Table{ auto table = new Table{
{"face", "网口", 40}, {"face", "网口", 40},
{"x", "X", Table::Stretch}, {"x", "X", 0, QHeaderView::Stretch},
{"y", "Y", Table::Stretch}, {"y", "Y", 0, QHeaderView::Stretch},
{"w", "宽度", Table::Stretch}, {"w", "宽度", 0, QHeaderView::Stretch},
{"h", "高度", Table::Stretch}, {"h", "高度", 0, QHeaderView::Stretch},
{"audio", "音频开关", Table::Stretch}, {"audio", "音频开关", 0, QHeaderView::Stretch},
{"backup", "备份开关", Table::Stretch} {"backup", "备份开关", 0, QHeaderView::Stretch}
}; };
table->setDefs(); table->setDefs();
vLeft->addWidget(table); vLeft->addWidget(table);
@ -128,7 +135,30 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
} }
{
auto file = QApplication::applicationDirPath()+"/temp.screen";
QFile qFile(file);
if(qFile.open(QFile::ReadOnly)) {
auto data = qFile.readAll();
qFile.close();
QJsonParseError err;
auto json = QJsonDocument::fromJson(data, &err);
if(err.error==QJsonParseError::NoError && json.isObject() && ! json.isEmpty()) {
mBox = json["ModuleConnectionInfo"].toObject();
mModule = mBox["ModuleInfo"].toObject();
}
} else {
auto file = QApplication::applicationDirPath()+"/temp.module";
QFile qFile(file);
if(qFile.open(QFile::ReadOnly)) {
auto data = qFile.readAll();
qFile.close();
QJsonParseError err;
auto json = QJsonDocument::fromJson(data, &err);
if(err.error==QJsonParseError::NoError && json.isObject() && ! json.isEmpty()) mModule = json.object();
}
}
}
auto receivePanel = new QWidget; auto receivePanel = new QWidget;
tab->addTab(receivePanel, "接收卡"); tab->addTab(receivePanel, "接收卡");
@ -136,8 +166,9 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
auto vBox = new VBox(receivePanel); auto vBox = new VBox(receivePanel);
auto gBox = new QGroupBox("模组信息"); auto gBox = new QGroupBox("模组信息");
vBox->addWidget(gBox); vBox->addWidget(gBox);
{
auto hh = new HBox(gBox); auto hh = new HBox(gBox);
hh->addSpacing(20);
auto vvv = new VBox(hh); auto vvv = new VBox(hh);
auto lb = new QLabel("驱动芯片: "); auto lb = new QLabel("驱动芯片: ");
@ -148,11 +179,11 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
vvv = new VBox(hh); vvv = new VBox(hh);
lb = new QLabel("驱动芯片"); fdChipType = new QLabel(mModule["ChipType"].toString());
vvv->addWidget(lb); vvv->addWidget(fdChipType);
lb = new QLabel("译码方式"); fdDecodeMode = new QLabel(mModule["DecodeMode"].toString());//译码方式
vvv->addWidget(lb); vvv->addWidget(fdDecodeMode);
hh->addSpacing(20); hh->addSpacing(20);
vvv = new VBox(hh); vvv = new VBox(hh);
@ -165,11 +196,11 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
vvv = new VBox(hh); vvv = new VBox(hh);
lb = new QLabel("模组宽度"); fdModuleWidth = new QLabel(QString::number(mModule["ModuleWidth"].toInt()));
vvv->addWidget(lb); vvv->addWidget(fdModuleWidth);
lb = new QLabel("模组高度"); fdModuleHeight = new QLabel(QString::number(mModule["ModuleHeight"].toInt()));
vvv->addWidget(lb); vvv->addWidget(fdModuleHeight);
hh->addSpacing(20); hh->addSpacing(20);
vvv = new VBox(hh); vvv = new VBox(hh);
@ -182,48 +213,53 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
vvv = new VBox(hh); vvv = new VBox(hh);
lb = new QLabel("扫描数"); fdScanNum = new QLabel(QString::number(mModule["ScanNum"].toInt()));
vvv->addWidget(lb); vvv->addWidget(fdScanNum);
lb = new QLabel("数据数组"); fdGroupNum = new QLabel(QString::number(mModule["GroupNum"].toInt()));
vvv->addWidget(lb); vvv->addWidget(fdGroupNum);
hh->addSpacing(20); hh->addSpacing(20);
vvv = new VBox(hh); vvv = new VBox(hh);
lb = new QLabel("数据线颜色: "); auto btn = new QPushButton(tr("数据线颜色"));
vvv->addWidget(lb); btn->setStyleSheet("QPushButton {border: none; }");
vvv->addWidget(btn);
lb = new QLabel("模组抽行设置"); btn = new QPushButton(tr("模组抽行设置"));
vvv->addWidget(lb); btn->setStyleSheet("QPushButton {border: none; }");
vvv->addWidget(btn);
vvv = new VBox(hh);
lb = new QLabel("数据线颜色");
vvv->addWidget(lb);
hh->addStretch(); hh->addStretch();
vvv = new VBox(hh); vvv = new VBox(hh);
auto btn = new QPushButton("模组选择"); btn = new QPushButton("模组选择");
btn->setProperty("ss","blue");
vvv->addWidget(btn); vvv->addWidget(btn);
btn = new QPushButton("智能设置"); btn = new QPushButton("智能设置");
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [this] { connect(btn, &QPushButton::clicked, this, [this] {
(new ExpertSmartPointSetWin(this))->show(); (new ExpertSmartPointSetWin(this))->show();
}); });
vvv->addWidget(btn); vvv->addWidget(btn);
}
gBox = new QGroupBox("单卡带载"); gBox = new QGroupBox("单卡带载");
vBox->addWidget(gBox); vBox->addWidget(gBox);
{
auto hh = new HBox(gBox);
hh->addSpacing(20);
auto vvv = new VBox(hh);
hh = new HBox(gBox); auto fdNormal = new QRadioButton("常规设计");
vvv = new VBox(hh); fdNormal->setChecked(true);
vvv->addWidget(fdNormal);
vvv->addWidget(new QRadioButton("常规设计")); auto fdAdvacned = new QRadioButton("高级设计");
vvv->addWidget(new QRadioButton("高级设计")); vvv->addWidget(fdAdvacned);
hh->addSpacing(20); hh->addSpacing(20);
@ -242,73 +278,294 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
stack->addWidget(normalPanel); stack->addWidget(normalPanel);
{ {
auto hh = new HBox(normalPanel); auto hh = new HBox(normalPanel);
hh->setContentsMargins(0,0,0,0);
auto vvv = new VBox(hh); auto vvv = new VBox(hh);
lb = new QLabel("宽度"); auto lb = new QLabel(tr("宽度"));
vvv->addWidget(lb); vvv->addWidget(lb);
lb = new QLabel("高度"); lb = new QLabel(tr("高度"));
vvv->addWidget(lb); vvv->addWidget(lb);
vvv = new VBox(hh); vvv = new VBox(hh);
auto fdCardWidth = new QSpinBox; fdCardWidth = new QSpinBox;
fdCardWidth->setRange(0, 99999); fdCardWidth->setRange(0, 99999);
fdCardWidth->setValue(mBox["ModuleRow"].toInt() * mModule["ModuleWidth"].toInt());
vvv->addWidget(fdCardWidth); vvv->addWidget(fdCardWidth);
auto fdCardHeight = new QSpinBox; fdCardHeight = new QSpinBox;
fdCardHeight->setRange(0, 99999); fdCardHeight->setRange(0, 99999);
fdCardHeight->setValue(mBox["ModuleCol"].toInt() * mModule["ModuleHeight"].toInt());
vvv->addWidget(fdCardHeight); vvv->addWidget(fdCardHeight);
hh->addSpacing(20);
vvv = new VBox(hh); vvv = new VBox(hh);
lb = new QLabel("多开宽度"); lb = new QLabel(tr("多开设置"));
vvv->addWidget(lb); vvv->addWidget(lb);
lb = new QLabel("级联方向"); lb = new QLabel(tr("级联方向"));
vvv->addWidget(lb); vvv->addWidget(lb);
vvv = new VBox(hh); vvv = new VBox(hh);
auto fdMulti = new QComboBox(); fdSectorCount = new QComboBox;
fdMulti->addItem(""); fdSectorCount->addItem(tr(""), 1);
fdMulti->addItem("双开"); fdSectorCount->addItem(tr("双开"), 2);
fdMulti->addItem("三开"); fdSectorCount->addItem(tr("三开"), 3);
fdMulti->addItem("四开"); fdSectorCount->addItem(tr("四开"), 4);
vvv->addWidget(fdMulti); fdSectorCount->addItem(tr("五开"), 5);
fdSectorCount->addItem(tr("六开"), 6);
fdSectorCount->addItem(tr("七开"), 7);
fdSectorCount->addItem(tr("八开"), 8);
select(fdSectorCount, mBox["SectorCount"].toInt());
vvv->addWidget(fdSectorCount);
auto fdDirection = new QComboBox(); fdDirection = new QComboBox();
fdDirection->addItem("从左到右"); fdDirection->addItem(tr("从左到右"));
fdDirection->addItem("从右到左"); fdDirection->addItem(tr("从右到左"));
fdDirection->addItem("从上到下"); fdDirection->addItem(tr("从上到下"));
fdDirection->addItem("从下到上"); fdDirection->addItem(tr("从下到上"));
fdDirection->setCurrentIndex(mBox["ModuleDirection"].toInt());
vvv->addWidget(fdDirection); vvv->addWidget(fdDirection);
vvv = new VBox(hh);
lb = new QLabel("插头顺序");
vvv->addWidget(lb);
vvv->addStretch();
vvv = new VBox(hh);
auto fdSord = new QComboBox();
fdSord->addItem("正序");
fdSord->addItem("逆序");
vvv->addWidget(fdSord);
vvv->addStretch();
hh->addStretch(); hh->addStretch();
vvv = new VBox(hh);
auto cb = new QCheckBox(tr("旋转180°"));
vvv->addWidget(cb);
auto btn = new QPushButton(tr("数据交换"));
btn->setProperty("ss","blue");
vvv->addWidget(btn);
} }
auto advacnedPanel = new QWidget; auto advacnedPanel = new QWidget;
stack->addWidget(advacnedPanel); stack->addWidget(advacnedPanel);
{
auto hh = new HBox(advacnedPanel);
hh->setContentsMargins(0,0,0,0);
vvv = new VBox(hh);
auto btn = new QPushButton(tr("平面造型"));
btn->setProperty("ss","blue");
btn->setMaximumWidth(100);
vvv->addWidget(btn);
}
connect(fdNormal, &QRadioButton::toggled, this, [=](bool checked) {
stack->setCurrentWidget(checked ? normalPanel : advacnedPanel);
});
}
gBox = new QGroupBox(tr("效果测试"));
vBox->addWidget(gBox);
{
auto hh = new HBox(gBox);
hh->addSpacing(20);
auto vvv = new VBox(hh);
auto hhh = new HBox(vvv);
auto lb = new QLabel(tr("视觉刷新率:"));
hhh->addWidget(lb);
auto cbFresh = new QComboBox();
cbFresh->addItem("960");
cbFresh->addItem("1920");
cbFresh->addItem("2880");
cbFresh->addItem("3840");
hhh->addWidget(cbFresh);
hhh = new HBox(vvv);
lb = new QLabel(tr("DCLK频率:"));
hhh->addWidget(lb);
auto cbDCLKf = new QComboBox();
cbDCLKf->addItem("25M");
cbDCLKf->addItem("20.83M");
cbDCLKf->addItem("17.86M");
cbDCLKf->addItem("15.63M");
cbDCLKf->addItem("13.89M");
cbDCLKf->addItem("12.5M");
cbDCLKf->addItem("11.36M");
cbDCLKf->addItem("10.42M");
cbDCLKf->addItem("9.62M");
hhh->addWidget(cbDCLKf);
hhh = new HBox(vvv);
lb = new QLabel(tr("DCLK相位:"));
hhh->addWidget(lb);
auto spinDclkXw = new QSpinBox;
spinDclkXw->setRange(0, 99999);
hhh->addWidget(spinDclkXw);
hhh = new HBox(vvv);
lb = new QLabel(tr("DCLK占空比:"));
hhh->addWidget(lb);
auto spinDclkZkb = new QSpinBox;
spinDclkZkb->setRange(20, 80);
hhh->addWidget(spinDclkZkb);
hhh = new HBox(vvv);
lb = new QLabel(tr("换行时间(ns):"));
hhh->addWidget(lb);
auto spinLineNs = new QSpinBox;
spinLineNs->setRange(2, 9999);
hhh->addWidget(spinLineNs);
hh->addSpacing(20);
vvv = new VBox(hh);
hhh = new HBox(vvv);
lb = new QLabel(tr("亮度有效率:"));
hhh->addWidget(lb);
lb = new QLabel(tr("100%"));
hhh->addWidget(lb);
hhh = new HBox(vvv);
lb = new QLabel(tr("GCLK频率:"));
hhh->addWidget(lb);
auto cbGCLKf = new QComboBox();
cbGCLKf->addItem("25M");
cbGCLKf->addItem("20.83M");
cbGCLKf->addItem("17.86M");
cbGCLKf->addItem("15.63M");
cbGCLKf->addItem("13.89M");
cbGCLKf->addItem("12.5M");
cbGCLKf->addItem("11.36M");
cbGCLKf->addItem("10.42M");
cbGCLKf->addItem("9.62M");
hhh->addWidget(cbGCLKf);
hhh = new HBox(vvv);
lb = new QLabel(tr("灰度级数:"));
hhh->addWidget(lb);
auto cbGryLevel = new QComboBox();
cbGryLevel->addItem("256");
cbGryLevel->addItem("1024");
cbGryLevel->addItem("4096");
cbGryLevel->addItem("8192");
cbGryLevel->addItem("16384");
cbGryLevel->addItem("32768");
cbGryLevel->addItem("65536");
hhh->addWidget(cbGryLevel);
hhh = new HBox(vvv);
lb = new QLabel(tr("GCLK占空比:"));
hhh->addWidget(lb);
auto spinGclkZkb = new QSpinBox;
spinGclkZkb->setRange(20, 80);
hhh->addWidget(spinGclkZkb);
hhh = new HBox(vvv);
lb = new QLabel(tr("换行位置(ns):"));
hhh->addWidget(lb);
auto spinLineWz = new QSpinBox;
spinLineWz->setRange(2, 9999);
hhh->addWidget(spinLineWz);
hh->addStretch();
vvv = new VBox(hh);
hhh = new HBox(vvv);
auto btn = new QPushButton(tr("更多设置"));
btn->setProperty("ss","blue");
hhh->addWidget(btn);
}
vBox->addStretch();
//保存,发送,固话,回读区
auto hBox = new HBox(vBox);
hBox->addSpacing(20);
auto btn = new QPushButton(tr("打开配置"));
btn->setProperty("ss","blue");
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("保存配置"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
auto dir = QApplication::applicationDirPath()+"/BoxFiles";
QDir(dir).mkdir(".");
auto file = QFileDialog::getSaveFileName(this, tr("保存文件"), dir, tr("Box file (*.box)"));
if(file.isEmpty()) return;
QFile qFile(file);
if(! qFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
return;
}
auto res = qFile.write(savedData());
qFile.close();
if(res < 0) {
QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
return;
}
QMessageBox::information(this, tr("保存成功"), tr("保存成功"));
});
hBox->addWidget(btn);
hBox->addStretch();
btn = new QPushButton(tr("保存Map"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
auto dir = QApplication::applicationDirPath();
auto file = QFileDialog::getSaveFileName(this, tr("保存文件"), dir);
if(file.isEmpty()) return;
QFile qFile(file);
if(! qFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
return;
}
QByteArray data;
addMapData(data);
auto res = qFile.write(data);
qFile.close();
if(res < 0) {
QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
return;
}
QMessageBox::information(this, tr("保存成功"), tr("保存成功"));
});
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("发送数据"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
QByteArray data;
addMapData(data);
QMessageBox::information(this, tr("发送成功"), tr("发送成功"));
});
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("固化数据"));
btn->setProperty("ss","blue");
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("回读数据"));
btn->setProperty("ss","blue");
hBox->addWidget(btn);
vBox->addStretch(); vBox->addStretch();
//状态栏
auto statusWgt = new QWidget;
statusWgt->setStyleSheet("QWidget{background-color:#222;}");
vBox->addWidget(statusWgt);
{
auto hh = new HBox(statusWgt);
auto lb = new QLabel(tr("状态:"));
hh->addWidget(lb);
}
} }
auto connPanel = new QWidget; auto connPanel = new QWidget;
tab->addTab(connPanel, "显示屏连接(正面看屏)"); tab->addTab(connPanel, tr("显示屏连接(正面看屏)"));
{ {
auto vBox = new QVBoxLayout(connPanel); auto vBox = new QVBoxLayout(connPanel);
vBox->setContentsMargins(4, 4, 4, 4); vBox->setContentsMargins(4, 4, 4, 4);
@ -335,3 +592,230 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
stack->addWidget(new ExpertScreenConnWin()); stack->addWidget(new ExpertScreenConnWin());
} }
} }
void ExpertWin::closeEvent(QCloseEvent *event) {
BaseWin::closeEvent(event);
QFile qFile(QApplication::applicationDirPath()+"/temp.screen");
if(! qFile.open(QFile::WriteOnly)) return;
qFile.write(savedData());
qFile.close();
}
QByteArray ExpertWin::savedData() {
mBox.insert("ModuleInfo", mModule);
auto ModuleWidth = mModule["ModuleWidth"].toInt();
auto ModuleHeight = mModule["ModuleHeight"].toInt();
mBox.insert("ModuleRow", (fdCardWidth->value() + ModuleWidth - 1) / ModuleWidth);
mBox.insert("ModuleCol", (fdCardHeight->value() + ModuleHeight - 1) / ModuleHeight);
mBox.insert("ModuleDirection", fdDirection->currentIndex());
mBox.insert("SectorCount", fdSectorCount->currentData().toInt());
QJsonObject obj{{"ModuleConnectionInfo", mBox}};
return QJsonDocument(obj).toJson(QJsonDocument::Indented);
}
void ExpertWin::addMapData(QByteArray &data) {
auto ModuleWidth = mModule["ModuleWidth"].toInt();
auto ModuleHeight = mModule["ModuleHeight"].toInt();
auto ModuleRow = (fdCardWidth->value() + ModuleWidth - 1) / ModuleWidth;
auto ModuleCol = (fdCardHeight->value() + ModuleHeight - 1) / ModuleHeight;
auto CardWidth = ModuleRow * ModuleWidth;
auto CardHeight = ModuleCol * ModuleHeight;
auto ModuleDirection = fdDirection->currentIndex();
//auto SectorCount = fdSectorCount->currentData().toInt();
QMap<uint, uint> map;
int memY = 0, memX = 0;
for(int boxY=0; boxY<CardHeight; boxY++) {
for(int boxX=0; boxX<CardWidth; boxX++) {
if(memX > 255) {
memX = 0;
memY++;
}
map.insert(boxY<<16|boxX, memY<<16|memX);
memX++;
}
memX = 0;
memY++;
}
auto points = mModule["Points"].toArray();
auto scans = mModule["Scans"].toArray();
auto GroupNum = mModule["GroupNum"].toInt();
auto jCnt = ModuleCol * GroupNum;
foreach(auto scan, scans) {
QList<QList<QByteArray>> chunkses;
for(int j=0; j<jCnt; j++) {
int lastMemY = INT_MIN;
int lastMemX = -1;
int cnt = 1, ttl = 1;
bool isAnti = false;
QList<QByteArray> chunks;
QByteArray chunk;
QString chstr;
for(int mm=0; mm<ModuleRow; mm++) {
int m = ModuleDirection==0 ? ModuleRow-1-mm : mm;
foreach(auto point, points) {
uint boxY = j * scans.size() + scan.toInt();
uint boxX = m * ModuleWidth + point.toInt();
if(boxX < 0) { //虚点
if(lastMemY==-1) memX = lastMemX + 1;
else {
memY = -1;
memX = 0;
}
} else {
auto mem = map[boxY<<16 | boxX];
memY = mem >> 16;
memX = mem & 0xffff;
}
if(memY==lastMemY && ttl < 64 && qAbs(memX-lastMemX)==1) {
if(cnt==1) {
isAnti = memX < lastMemX;
cnt++;
ttl++;
lastMemX = memX;
continue;
} else if(memX < lastMemX == isAnti) {
cnt++;
ttl++;
lastMemX = memX;
continue;
}
}
if(lastMemY > INT_MIN) {
uint y = lastMemY==-1 ? 0 : lastMemY;
uint x = isAnti ? lastMemX : lastMemX-cnt+1;
chunk.append((j << 2) + (y >> 8)).append(y).append(x).append((isAnti << 7)+cnt);
chstr += QString("j%1 行%2 列%3 序%4 长%5").arg(j).arg(y).arg(x).arg(isAnti).arg(cnt);
}
if(ttl>=64) {
chunks.append(chunk);
chunk = QByteArray();
qDebug() << chstr;
chstr.clear();
ttl = 1;
}
cnt = 1;
lastMemY = memY;
lastMemX = lastMemY==-1 ? 0 : memX;
}
}
uint y = lastMemY==-1 ? 0 : lastMemY;
uint x = isAnti ? lastMemX : lastMemX-cnt+1;
chunk.append((j << 2) + (y >> 8)).append(y).append(x).append((isAnti << 7)+cnt);
chstr += QString("j%1 行%2 列%3 序%4 长%5").arg(j).arg(y).arg(x).arg(isAnti).arg(cnt);
chunks.append(chunk);
chunkses.append(chunks);
qDebug() << chstr;
}
data.append(0xAA).append(scan.toInt()).append(2, 0);
auto chend = chunkses[0].size()-1;
auto start = data.size();
for(int ch=0; ch<=chend; ch++) {
data.append(0x55).append(ch==chend ? (char)(1<<7) : 0).append(2, 0);
auto start = data.size();
foreach(auto chunks, chunkses) data.append(chunks[ch]);
auto num = (data.size() - start) / 4;
data[start-2] = num;
data[start-3] = num>>8;
}
auto len = data.size() - start;
data[start-1] = len;
data[start-2] = len>>8;
}
}
#define MAX_ONCE 1482
void run() {
// quint32 idx = 0;
// while(2) {
// QByteArray bytes;
// bytes.append("\x55\x55\x9a\x3d"); //前导, 版本号, 服务类型
// bytes.append("\0\x4", 2); //数据长度
// bytes.append(4, '\xff'); //目的地址
// bytes.append(4, 0); //源地址
// bytes.append("\x35\0\xc\xbb", 4); //内存指针
// bytes.append(2, 0); //应答填充项
// auto crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-4, 4);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// //发送帧开始指令包
// auto queue = pcap_sendqueue_alloc(img.width()*img.height()*4);
// {
// struct pcap_pkthdr pktheader;
// pktheader.len = pktheader.caplen = bytes.size();
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
// onErr(QString("添加开始失败: ")+pcap_geterr(pcap));
// goto end;
// }
// idx = 0;
// //按行发送图像数据包
// for(int i=0; i<img.height(); i++) for(int j=0; j<lineLen; j+=once) {
// int dataLen = lineLen - j;
// if(dataLen > once) dataLen = once;
// dataLen += 4;
// bytes.clear();
// bytes.append("\x55\x55\x1\x33"); //前导, 版本号, 服务类型
// bytes.append(dataLen>>8).append(dataLen); //数据长度
// bytes.append(4, '\xff'); //目的地址
// bytes.append(4, 0); //源地址
// bytes.append(i>>8).append(i).append(j>>8).append(j); //内存指针
// bytes.append(2, 0); //应答填充项
// crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// bytes.append(idx>>24).append(idx>>16).append(idx>>8).append(idx);//包序号
// idx++;
// bytes.append((const char*)bits + i * bytesPerLine + j, dataLen - 4);
// crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// pktheader.len = pktheader.caplen = bytes.size();
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
// onErr(QString("添加数据失败: ")+pcap_geterr(pcap));
// goto end;
// }
// }
// bytes.clear();
// bytes.append("\x55\x55\x9a\x3d"); //前导, 版本号, 服务类型
// bytes.append(2, 0); //数据长度
// bytes.append(4, '\xff'); //目的地址
// bytes.append(4, 0); //源地址
// bytes.append("\x35\0\xc\xcc", 4); //内存指针
// bytes.append(2, 0); //应答填充项
// crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// pktheader.len = pktheader.caplen = bytes.size();
// //发送帧结束指令包
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
// onErr(QString("添加结束失败: ")+pcap_geterr(pcap));
// goto end;
// }
// u_int res;
// if((res = pcap_sendqueue_transmit(pcap, queue, 0)) < queue->len) {
// onErr(QString::asprintf("发送包出错: %s. 仅发了 %d / %d bytes", pcap_geterr(pcap), res, queue->len));
// goto end;
// }
// }
// end:
// pcap_sendqueue_destroy(queue);
// }
}
ReceThread::ReceThread(pcap_t *pcap) : pcap(pcap) {
connect(this, &QThread::finished, this, &QThread::deleteLater);
}
void ReceThread::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 || !showImg) continue; //超时
if(header->caplen<24) continue;
if(data[0]!=0x55 || data[1]!=0x55) continue;
if(data[2]==0x9a && data[3]==0x3d) {
// if(data[17]==0xBB) {
// emit onMsg(((int)data[24] << 8) + data[25], ((int)data[26] << 8) + data[27]);
// } else if(data[17]==0xCC) emit onMsg(img);
continue;
}
}
emit onErr(pcap_geterr(pcap));
}

View File

@ -2,14 +2,65 @@
#define EXPERTWIN_H #define EXPERTWIN_H
#include "basewin.h" #include "basewin.h"
#define HAVE_REMOTE
#include <winsock2.h>
#include "pcap.h"
#include <QThread>
#include <QLabel>
#include <QSpinBox>
#include <QComboBox>
#include <QJsonObject>
class ReceThread : public QThread {
Q_OBJECT
public:
explicit ReceThread(pcap *pcap);
~ReceThread() {
pcap_close(pcap);
}
pcap *pcap;
std::atomic<char> status{0};
bool showImg{true};
protected:
void run();
signals:
void onMsg(QByteArray);
void onErr(char *);
};
class ExpertWin : public BaseWin { class ExpertWin : public BaseWin {
Q_OBJECT Q_OBJECT
public: public:
explicit ExpertWin(QWidget *parent = nullptr); explicit ExpertWin(QWidget *parent = nullptr);
QByteArray savedData();
void addMapData(QByteArray &);
int screenWidth{1280}, screenHeight{720}; int screenWidth{1280}, screenHeight{720};
double rate{1}; double rate{1};
QLabel *fdModuleWidth, *fdModuleHeight, *fdGroupNum, *fdScanNum;
QLabel *fdChipType, *fdDecodeMode;
QJsonObject mModule {
{"ModuleWidth", 16},
{"ModuleHeight", 8},
{"GroupNum", 2},
{"ScanNum", 4},
{"ChipType", "通用"},
{"DecodeMode", "138译码"},
{"GroupMode", "三线并行"}
};
QJsonObject mBox {
{"ModuleRow", 1},
{"ModuleCol", 1},
{"Direction", 1},
{"SectorCount", 1}
};
QSpinBox *fdCardWidth, *fdCardHeight;
QComboBox *fdDirection, *fdSectorCount;
protected:
void closeEvent(QCloseEvent *) override;
}; };
#endif // EXPERTWIN_H #endif // EXPERTWIN_H

119
ledset/globalfunc.cpp Normal file
View File

@ -0,0 +1,119 @@
#include "globalfunc.h"
#include "table.h"
#include "basewin.h"
#define HAVE_REMOTE
#include "pcap.h"
#include <QMessageBox>
#include <QPushButton>
QByteArray getNetDev(QWidget *parent, QByteArray def) {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devs;
if(pcap_findalldevs(&devs, errbuf) == -1) {
QMessageBox::critical(parent, "Error", QString("寻找网卡失败")+errbuf);
return QByteArray();
}
auto table = new Table{
{"name", "网卡名称", 400},
{"desc", "网卡描述", 300},
{"loopback","Loopback"},
{"ip","IP"},
{"netmask","Netmask"},
{"broadaddr","Broad Addr"},
{"dstaddr","Dst Addr"}
};
pcap_if_t *device = 0;
for(pcap_if_t *dev = devs; dev; dev = dev->next) {
pcap_addr_t *a;
for(a=dev->addresses; a; a=a->next) {
auto sa_family = a->addr->sa_family;
if(sa_family==AF_INET) {
if(! def.isEmpty() && dev->name == def) {
pcap_freealldevs(devs);
table->deleteLater();
return def;
}
auto rr = table->rowCount();
table->setRowCount(rr+1);
table->setValue(rr, "name", dev->name);
table->setValue(rr, "desc", dev->description);
table->setValue(rr, "loopback", (dev->flags & PCAP_IF_LOOPBACK)?"True":"False");
auto ip = (u_char *) &((sockaddr_in *) a->addr)->sin_addr.s_addr;
table->setValue(rr, "ip", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
if(a->netmask) {
ip = (u_char *) &((sockaddr_in *) a->netmask)->sin_addr.s_addr;
table->setValue(rr, "netmask", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(a->broadaddr) {
ip = (u_char *) &((sockaddr_in *) a->broadaddr)->sin_addr.s_addr;
table->setValue(rr, "broadaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(a->dstaddr) {
ip = (u_char *) &((sockaddr_in *) a->dstaddr)->sin_addr.s_addr;
table->setValue(rr, "dstaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(device==0) device = dev;
}
}
}
pcap_freealldevs(devs);
auto rowCnt = table->rowCount();
if(rowCnt==0) {
table->deleteLater();
QMessageBox::critical(parent, "Error", "没找到 internet 设备");
return QByteArray();
} else if(rowCnt==1) {
table->deleteLater();
return table->item(0, "name")->text().toLocal8Bit();
} else {
auto dlg = new BaseDlg(parent);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setWindowTitle("选择网卡");
dlg->resize(900, 300);
auto vBox = new QVBoxLayout(dlg->center);
vBox->setContentsMargins(0,0,0,0);
vBox->setSpacing(3);
vBox->addSpacing(30);
table->setDefs();
table->setSelectionMode(QAbstractItemView::SingleSelection);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
table->selectRow(0);
QByteArray name;
dlg->connect(table, &Table::cellDoubleClicked, dlg, [dlg, table, &name](int row) {
name = table->item(row, "name")->text().toLocal8Bit();
dlg->accept();
});
vBox->addWidget(table);
auto hBox = new QHBoxLayout;
hBox->addStretch();
auto btnOk = new QPushButton("确定");
btnOk->setMinimumWidth(80);
dlg->connect(btnOk, &QPushButton::clicked, dlg, [dlg, table, &name] {
auto sels = table->selectedRanges();
if(sels.isEmpty()) {
QMessageBox::warning(dlg, "Warning", "请选择网卡");
return;
}
name = table->item(sels[0].topRow(), "name")->text().toLocal8Bit();
dlg->accept();
});
hBox->addWidget(btnOk);
hBox->addStretch();
auto btnClose = new QPushButton("关闭");
btnClose->setMinimumWidth(80);
dlg->connect(btnClose, &QPushButton::clicked, dlg, &QDialog::reject);
hBox->addWidget(btnClose);
hBox->addStretch();
vBox->addLayout(hBox);
dlg->exec();
return name;
}
}

9
ledset/globalfunc.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef GLOBALFUNC_H
#define GLOBALFUNC_H
#include <QWidget>
#include <QByteArray>
QByteArray getNetDev(QWidget *parent, QByteArray);
#endif // GLOBALFUNC_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

BIN
ledset/imgs/checkbox-un.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 B

BIN
ledset/imgs/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
ledset/imgs/xbox-menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -32,6 +32,7 @@ SOURCES += \
expertsmartpointsetwin.cpp \ expertsmartpointsetwin.cpp \
expertwin.cpp \ expertwin.cpp \
fast.cpp \ fast.cpp \
globalfunc.cpp \
gqt.cpp \ gqt.cpp \
main.cpp \ main.cpp \
mainwin.cpp \ mainwin.cpp \
@ -49,6 +50,7 @@ HEADERS += \
expertsmartpointsetwin.h \ expertsmartpointsetwin.h \
expertwin.h \ expertwin.h \
fast.h \ fast.h \
globalfunc.h \
gqt.h \ gqt.h \
mainwin.h \ mainwin.h \
pcapthread.h \ pcapthread.h \

View File

@ -36,6 +36,47 @@ int main(int argc, char *argv[]) {
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
QApplication a(argc, argv); QApplication a(argc, argv);
a.setWindowIcon(QIcon(":/128.ico"));
a.setStyleSheet(R"rrr(
QMessageBox {background: #333;}
QGroupBox {border: 1px solid #777; border-radius: 3px; margin-top: 0.5em; padding-top: 0.4em;}
QGroupBox::title {color: #fff; subcontrol-origin: margin; left: 0.5em;}
QLineEdit, QComboBox, QSpinBox, QPushButton, QAbstractScrollArea {border: 1px solid #888;}
QLineEdit, QComboBox, QSpinBox {border-radius: 2px; padding: 2px; background: #222;}
QPushButton {border-radius: 4px; padding: 2px 6px; background: #444;}
QPushButton:hover {background: #555;}
QPushButton:pressed {background: #666;}
QPushButton:checked {background: #026; border-color: #06f;}
QPushButton:!enabled {background: #666; color: #777;}
QPushButton[ss="min"]{border-radius: 4px; padding: 0; width: 30px; height: 25px; background: #07c;}
QPushButton[ss="close"]{border-radius: 4px; padding: 0; width: 30px; height: 25px; background: #e22;}
QPushButton[ss="blue"] {background: #07a; border: 1px solid #0080bb;}
QPushButton:hover[ss="blue"] {background: #069}
QPushButton:pressed[ss="blue"] {background: #058;}
QRadioButton::indicator {border-image: url(:/imgs/radio-un.png); width: 1em; height: 1em;}
QRadioButton::indicator:checked {border-image: url(:/imgs/radio-check.png);}
QCheckBox::indicator {border-image: url(:/imgs/checkbox-un.png); width: 1em; height: 1em;}
QCheckBox::indicator:checked {border-image: url(:/imgs/checkbox-check.png);}
QAbstractScrollArea QScrollBar {background: #222;}
QTableView {gridline-color:#777;}
QHeaderView::section, QTableCornerButton:section {background: #444;}
QSlider::horizontal {height: 16px;}
QSlider::groove {background: transparent;}
QSlider::sub-page:horizontal {background: #07c; margin: 5px 0; border-radius: 2px;}
QSlider::add-page:horizontal {background: #888; margin: 5px 0; border-radius: 2px;}
QSlider::handle {background: #eee; border-radius: 2px;}
QSlider::handle:hover {background: #fff;}
QSlider::handle:horizontal {width: 8px;}
)rrr");
QFont font; QFont font;
font.setFamilies(QStringList{"Arial","Microsoft YaHei UI"}); font.setFamilies(QStringList{"Arial","Microsoft YaHei UI"});
font.setPixelSize(14); font.setPixelSize(14);
@ -57,42 +98,6 @@ int main(int argc, char *argv[]) {
plt.setBrush(QPalette::BrightText, QColor(0,0,0)); plt.setBrush(QPalette::BrightText, QColor(0,0,0));
plt.setBrush(QPalette::Shadow, QColor(0xaaaaaa)); plt.setBrush(QPalette::Shadow, QColor(0xaaaaaa));
a.setPalette(plt); a.setPalette(plt);
a.setWindowIcon(QIcon(":/128.ico"));
a.setStyleSheet(R"rrr(
QMessageBox {background: #333;}
QGroupBox {border: 1px solid #777; border-radius: 3px; margin-top: 1.2ex; padding-top: 1ex;}
QGroupBox::title {color: #fff; subcontrol-origin: margin; position: relative; left: 1.4ex;}
QLineEdit, QComboBox, QSpinBox, QPushButton, QAbstractScrollArea {border: 1px solid #888;}
QLineEdit, QComboBox, QSpinBox {border-radius: 2px; padding: 2px; background: #222;}
QPushButton{border-radius: 4px; padding: 2px 6px; background: #444;}
QPushButton:hover {background: #555;}
QPushButton:pressed {background: #666;}
QPushButton:checked {background: #026; border-color: #06f;}
QPushButton:!enabled {background: #666; color: #777;}
QPushButton[ss="min"]{border-radius: 4px; padding: 0; width: 30px; height: 25px; background: #07c;}
QPushButton[ss="close"]{border-radius: 4px; padding: 0; width: 30px; height: 25px; background: #e22;}
QRadioButton::indicator {border-image: url(:/imgs/radio-un.png); width: 14px; height: 14px;}
QRadioButton::indicator:checked {border-image: url(:/imgs/radio-check.png);}
QAbstractScrollArea QScrollBar {background: #222;}
QTableView {gridline-color:#777;}
QHeaderView::section, QTableCornerButton:section {background: #444;}
QSlider::horizontal {height: 16px;}
QSlider::groove {background: transparent;}
QSlider::sub-page:horizontal {background: #07c; margin: 5px 0; border-radius: 2px;}
QSlider::add-page:horizontal {background: #888; margin: 5px 0; border-radius: 2px;}
QSlider::handle {background: #eee; border-radius: 2px;}
QSlider::handle:hover {background: #fff;}
QSlider::handle:horizontal {width: 8px;}
)rrr");
QTranslator translator; QTranslator translator;
if(translator.load(QLocale::system(), "app", "_", ":/i18n")) a.installTranslator(&translator); if(translator.load(QLocale::system(), "app", "_", ":/i18n")) a.installTranslator(&translator);

View File

@ -4,7 +4,6 @@
#include "brightwin.h" #include "brightwin.h"
#include "pcapwin.h" #include "pcapwin.h"
#include "videowin.h" #include "videowin.h"
#include "gqt.h"
#include <QLabel> #include <QLabel>
#include <QPushButton> #include <QPushButton>
#include <QToolButton> #include <QToolButton>
@ -15,6 +14,13 @@
#include <QTimer> #include <QTimer>
#include <QMessageBox> #include <QMessageBox>
#include <QDebug> #include <QDebug>
#include "table.h"
#include "globalfunc.h"
#include <QMessageBox>
#include "basewin.h"
#include <QSettings>
#include <QDir>
#include <QApplication>
class ImgBtn : public QToolButton { class ImgBtn : public QToolButton {
public: public:
@ -61,7 +67,7 @@ ImgBtn *addImg(QHBoxLayout *parent, const QIcon &icon, const QString &text) {
} }
MainWin::MainWin() { MainWin::MainWin() {
setWindowTitle("Led Set"); setWindowTitle("LedSet Express");
resize(860, 540); resize(860, 540);
auto vBox = new QVBoxLayout(center); auto vBox = new QVBoxLayout(center);
@ -73,50 +79,164 @@ MainWin::MainWin() {
auto btnImg = addImg(imgsBar, QPixmap(":/imgs/fast.png").scaledToWidth(128, Qt::SmoothTransformation), "快速调屏"); auto btnImg = addImg(imgsBar, QPixmap(":/imgs/fast.png").scaledToWidth(128, Qt::SmoothTransformation), "快速调屏");
connect(btnImg, &ImgBtn::clicked, this, [=](){ connect(btnImg, &ImgBtn::clicked, this, [=](){
(new Fast(this))->show(); (new Fast(this))->show();
// if(win==0) {
// win = new QWidget;
// win->setWindowFlag(Qt::FramelessWindowHint);
// win->resize(600,100);
// win->show();
// } else {
// win->move(win->x()-100, win->y());
// }
}); });
btnImg = addImg(imgsBar, QPixmap(":/imgs/expert.png").scaledToWidth(128, Qt::SmoothTransformation), "专家调屏"); btnImg = addImg(imgsBar, QPixmap(":/imgs/expert.png").scaledToWidth(128, Qt::SmoothTransformation), tr("专家调屏"));
connect(btnImg, &ImgBtn::clicked, this, [=](){ connect(btnImg, &ImgBtn::clicked, this, [=](){
(new ExpertWin(this))->show(); (new ExpertWin(this))->show();
}); });
btnImg = addImg(imgsBar, QPixmap(":/imgs/bright.png").scaledToWidth(128, Qt::SmoothTransformation), "亮度控制"); btnImg = addImg(imgsBar, QPixmap(":/imgs/bright.png").scaledToWidth(128, Qt::SmoothTransformation), tr("亮度控制"));
connect(btnImg, &ImgBtn::clicked, this, [=](){ connect(btnImg, &ImgBtn::clicked, this, [=](){
(new BrightWin(this))->show(); (new BrightWin(this))->show();
}); });
btnImg = addImg(imgsBar, QPixmap(":/imgs/correct.png").scaledToWidth(128, Qt::SmoothTransformation), "相机矫正"); btnImg = addImg(imgsBar, QPixmap(":/imgs/correct.png").scaledToWidth(128, Qt::SmoothTransformation), tr("相机矫正"));
connect(btnImg, &ImgBtn::clicked, this, [=](){ connect(btnImg, &ImgBtn::clicked, this, [=](){
}); });
btnImg = addImg(imgsBar, QPixmap(":/imgs/monitor.png").scaledToWidth(128, Qt::SmoothTransformation), "屏体监控"); btnImg = addImg(imgsBar, QPixmap(":/imgs/monitor.png").scaledToWidth(128, Qt::SmoothTransformation), tr("屏体监控"));
connect(btnImg, &ImgBtn::clicked, this, [=](){ connect(btnImg, &ImgBtn::clicked, this, [=](){
}); });
btnImg = addImg(imgsBar, QPixmap(":/imgs/multi.png").scaledToWidth(128, Qt::SmoothTransformation), "多功能卡"); btnImg = addImg(imgsBar, QPixmap(":/imgs/multi.png").scaledToWidth(128, Qt::SmoothTransformation), tr("多功能卡"));
connect(btnImg, &ImgBtn::clicked, this, [=](){ connect(btnImg, &ImgBtn::clicked, this, [=](){
//win->move(win->x()-1, win->y()); //win->move(win->x()-1, win->y());
}); });
btnImg = addImg(imgsBar, QPixmap(":/imgs/video.png").scaledToWidth(128, Qt::SmoothTransformation), "网口通信"); btnImg = addImg(imgsBar, QPixmap(":/imgs/video.png").scaledToWidth(128, Qt::SmoothTransformation), tr("协议调试"));
connect(btnImg, &ImgBtn::clicked, this, [=](){ connect(btnImg, &ImgBtn::clicked, this, [=](){
auto ins = PcapWin::newIns(this); if(pcapRe != 0 && pcapSend != 0)
{
auto ins = new PcapWin(pcapRe, pcapSend, this);
if(ins) ins->show();
}
});
btnImg = addImg(imgsBar, QPixmap(":/imgs/idea.png").scaledToWidth(128, Qt::SmoothTransformation), tr("模拟同步"));
connect(btnImg, &ImgBtn::clicked, this, [=](){
auto ins = VideoWin::newIns(net_name, this);
if(ins) ins->show(); if(ins) ins->show();
}); });
btnImg = addImg(imgsBar, QPixmap(":/imgs/idea.png").scaledToWidth(128, Qt::SmoothTransformation), "视频传输");
connect(btnImg, &ImgBtn::clicked, this, [=](){
auto ins = VideoWin::newIns(this);
ins->show();
});
vBox->addLayout(imgsBar); vBox->addLayout(imgsBar);
vBox->addSpacing(9);
vBox->addSpacing(16);
vBox->addWidget(new QLabel(" 硬件信息")); vBox->addWidget(new QLabel(" 硬件信息"));
table = new Table{
{"type", "发送卡型号"},
{"name", "名称"},
{"link", "连接方式"},
{"vcs", "接收卡数量"},
{"Pinfo", "网口统计P1~Pn"},
{"Oinfo", "其他信息", QHeaderView::Stretch},
};
vBox->addWidget(table);
vBox->addStretch(); auto hstatus = new QHBoxLayout;
hstatus->addWidget(new QLabel(tr("版本:221114")));
hstatus->addStretch();
auto btnNetSelect = new QPushButton("通讯选择");
btnNetSelect->setMinimumWidth(80);
connect(btnNetSelect, &QPushButton::clicked, this, [this] {
auto name = getNetDev(this, "");
if(name.isEmpty()) return;
//PCAP_OPENFLAG_DATATX_UDP2它定义了数据传输假如是远程抓包是否用UDP协议来处理。
//PCAP_OPENFLAG_NOCAPTURE_RPCAP4它定义了远程探测器是否捕获它自己产生的数据包。
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();
} }
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);
}
}
}

View File

@ -2,12 +2,39 @@
#define MAINWIN_H #define MAINWIN_H
#include "basewin.h" #include "basewin.h"
#define HAVE_REMOTE
#include "pcapthread.h"
#include "table.h"
class MainPcapThread : public QThread {
Q_OBJECT
public:
explicit MainPcapThread(pcap *pcap);
~MainPcapThread() {
pcap_close(pcap);
}
pcap *pcap;
std::atomic<char> status{0};
protected:
void run();
signals:
void onMsg(const u_char *data,int len);
void onError(char *);
};
class MainWin : public BaseWin { class MainWin : public BaseWin {
Q_OBJECT Q_OBJECT
public: public:
MainWin(); MainWin();
QWidget *win{0}; QWidget *win{0};
QByteArray net_name;
pcap_t *pcapRe{0};
pcap_t *pcapSend{0};
MainPcapThread *thd{0};
Table *table = nullptr;
protected slots:
void ProNetData(const u_char *data,int len);
}; };
#endif // MAINWIN_H #endif // MAINWIN_H

View File

@ -1,5 +1,4 @@
#include "pcapwin.h" #include "pcapwin.h"
#include "table.h"
#include <QTextEdit> #include <QTextEdit>
#include <QPushButton> #include <QPushButton>
#include <QMessageBox> #include <QMessageBox>
@ -7,150 +6,28 @@
#include <QDateTime> #include <QDateTime>
#include <QRadioButton> #include <QRadioButton>
#include <QDebug> #include <QDebug>
#include "globalfunc.h"
PcapWin *PcapWin::newIns(QWidget *parent) { //PcapWin *PcapWin::newIns(QWidget *parent) {
char errbuf[PCAP_ERRBUF_SIZE]; // auto name = getNetDev(parent);
pcap_if_t *devs; // if(name.isEmpty()) return 0;
if(pcap_findalldevs(&devs, errbuf) == -1) { // char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
QMessageBox::critical(parent, "Error", QString("寻找网卡失败")+errbuf); // auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS, 50, errbuf);
return 0; // if(pcapRe == 0) {
} // QMessageBox::critical(parent, "Error", QString(tr("打开网卡失败"))+errbuf);
auto table = new Table{ // return 0;
{"name", "网卡名称", 400}, // }
{"desc", "网卡描述", 300}, // auto pcapSend = pcap_open_live(name.data(), 65536, 0, 50, errbuf);
{"loopback","Loopback"}, // if(pcapSend == 0) {
{"ip","IP"}, // QMessageBox::critical(parent, "Error", QString(tr("打开网卡失败"))+errbuf);
{"netmask","Netmask"}, // return 0;
{"broadaddr","Broad Addr"}, // }
{"dstaddr","Dst Addr"} // return new PcapWin(pcapRe, pcapSend, parent);
}; //}
pcap_if_t *device = 0;
for(pcap_if_t *dev = devs; dev; dev = dev->next) {
pcap_addr_t *a;
for(a=dev->addresses; a; a=a->next) {
auto sa_family = a->addr->sa_family;
if(sa_family==AF_INET) {
auto rr = table->rowCount();
table->setRowCount(rr+1);
table->setValue(rr, "name", dev->name);
table->setValue(rr, "desc", dev->description);
table->setValue(rr, "loopback", (dev->flags & PCAP_IF_LOOPBACK)?"True":"False");
auto ip = (u_char *) &((sockaddr_in *) a->addr)->sin_addr.s_addr;
table->setValue(rr, "ip", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
if(a->netmask) {
ip = (u_char *) &((sockaddr_in *) a->netmask)->sin_addr.s_addr;
table->setValue(rr, "netmask", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(a->broadaddr) {
ip = (u_char *) &((sockaddr_in *) a->broadaddr)->sin_addr.s_addr;
table->setValue(rr, "broadaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(a->dstaddr) {
ip = (u_char *) &((sockaddr_in *) a->dstaddr)->sin_addr.s_addr;
table->setValue(rr, "dstaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(device==0) device = dev;
}
}
}
pcap_freealldevs(devs);
auto rowCnt = table->rowCount();
if(rowCnt==0) {
table->deleteLater();
QMessageBox::critical(parent, "Error", "没找到 internet 设备");
return 0;
} else if(rowCnt==1) {
table->deleteLater();
auto name = table->item(0, "name")->text().toLocal8Bit();
auto pcapRe = pcap_open(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, 0, errbuf);
if(pcapRe == 0) {
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
return 0;
}
auto pcapSe = pcap_open(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, 0, errbuf);
if(pcapSe == 0) {
QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);
return 0;
}
return new PcapWin(pcapRe, pcapSe, parent);
} else {
auto dlg = new BaseDlg(parent);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setWindowTitle("选择网卡");
dlg->resize(1200, 300);
auto vBox = new QVBoxLayout(dlg->center);
vBox->setContentsMargins(0,0,0,0);
vBox->setSpacing(3);
vBox->addSpacing(30);
table->setDefs();
table->setSelectionMode(QAbstractItemView::SingleSelection);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
table->selectRow(0);
pcap_t *pcapRece;
pcap_t *pcapSend;
connect(table, &Table::cellDoubleClicked, dlg, [dlg, table, &pcapRece, &pcapSend, &errbuf](int row) {
auto name = table->item(row, "name")->text().toLocal8Bit();
pcapRece = pcap_open(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, 0, errbuf);
if(pcapRece == 0) {
QMessageBox::critical(dlg, "Error", QString("打开网卡失败")+errbuf);
return;
}
pcapSend = pcap_open(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, 0, errbuf);
if(pcapSend == 0) {
QMessageBox::critical(dlg, "Error", QString("打开网卡失败")+errbuf);
return;
}
dlg->accept();
});
vBox->addWidget(table);
auto hBox = new QHBoxLayout;
hBox->addStretch();
auto btnOk = new QPushButton("确定");
btnOk->setMinimumWidth(80);
connect(btnOk, &QPushButton::clicked, dlg, [dlg, table, &pcapRece, &pcapSend, &errbuf] {
auto sels = table->selectedRanges();
if(sels.isEmpty()) {
QMessageBox::warning(dlg, "Warning", "请选择网卡");
return;
}
auto name = table->item(sels[0].topRow(), "name")->text().toLocal8Bit();
pcapRece = pcap_open(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, 0, errbuf);
if(pcapRece == 0) {
QMessageBox::critical(dlg, "Error", QString("打开网卡失败")+errbuf);
return;
}
pcapSend = pcap_open(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, 0, errbuf);
if(pcapSend == 0) {
QMessageBox::critical(dlg, "Error", QString("打开网卡失败")+errbuf);
return;
}
dlg->accept();
});
hBox->addWidget(btnOk);
hBox->addStretch();
auto btnClose = new QPushButton("关闭");
btnClose->setMinimumWidth(80);
connect(btnClose, &QPushButton::clicked, dlg, &QDialog::reject);
hBox->addWidget(btnClose);
hBox->addStretch();
vBox->addLayout(hBox);
if(QDialog::Accepted==dlg->exec()) return new PcapWin(pcapRece, pcapSend, parent);
return 0;
}
}
PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{parent}, pcap(pcapSend) { PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{parent}, pcap(pcapSend) {
setWindowModality(Qt::WindowModal); setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle("网口通信"); setWindowTitle(tr("网口通信"));
resize(1024, 720); resize(1024, 720);
auto vBox = new QVBoxLayout(center); auto vBox = new QVBoxLayout(center);
@ -161,17 +38,17 @@ PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{
auto fdReceive = new QTextEdit; auto fdReceive = new QTextEdit;
fdReceive->setFontFamily("Consolas"); fdReceive->setFontFamily("Consolas");
fdReceive->setReadOnly(true); fdReceive->setReadOnly(true);
fdReceive->document()->setMaximumBlockCount(1000); fdReceive->document()->setMaximumBlockCount(200);
auto hBox = new QHBoxLayout; auto hBox = new QHBoxLayout;
{ {
auto vBox = new QVBoxLayout; auto vBox = new QVBoxLayout;
auto hBox2 = new QHBoxLayout; auto hBox2 = new QHBoxLayout;
hBox2->addWidget(new QLabel("接收:")); hBox2->addWidget(new QLabel(tr("接收:")));
hBox2->addStretch(); hBox2->addStretch();
auto fdStart = new QRadioButton("开始"); auto fdStart = new QRadioButton(tr("开始"));
fdStart->setChecked(true); fdStart->setChecked(true);
connect(fdStart, &QPushButton::toggled, this, [this](bool checked) { connect(fdStart, &QPushButton::toggled, this, [this](bool checked) {
thd->status = checked ? 0 : 1; thd->status = checked ? 0 : 1;
@ -179,12 +56,12 @@ PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{
hBox2->addWidget(fdStart); hBox2->addWidget(fdStart);
hBox2->addSpacing(20); hBox2->addSpacing(20);
auto fdEnd = new QRadioButton("暂停"); auto fdEnd = new QRadioButton(tr("暂停"));
hBox2->addWidget(fdEnd); hBox2->addWidget(fdEnd);
hBox2->addStretch(); hBox2->addStretch();
auto btnClear = new QPushButton("清除"); auto btnClear = new QPushButton(tr("清除"));
btnClear->setMinimumWidth(120); btnClear->setMinimumWidth(120);
connect(btnClear, &QPushButton::clicked, fdReceive, &QTextEdit::clear); connect(btnClear, &QPushButton::clicked, fdReceive, &QTextEdit::clear);
hBox2->addWidget(btnClear); hBox2->addWidget(btnClear);
@ -208,13 +85,13 @@ PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{
auto hBox2 = new QHBoxLayout; auto hBox2 = new QHBoxLayout;
hBox2->addStretch(); hBox2->addStretch();
auto btnSend = new QPushButton("发送"); auto btnSend = new QPushButton(tr("发送"));
btnSend->setMinimumWidth(120); btnSend->setMinimumWidth(120);
hBox2->addWidget(btnSend); hBox2->addWidget(btnSend);
hBox2->addStretch(); hBox2->addStretch();
auto btnClear = new QPushButton("清除"); auto btnClear = new QPushButton(tr("清除"));
btnClear->setMinimumWidth(120); btnClear->setMinimumWidth(120);
hBox2->addWidget(btnClear); hBox2->addWidget(btnClear);
hBox2->addStretch(); hBox2->addStretch();
@ -236,7 +113,7 @@ PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{
if(bytes.size() % 2) bytes.append('0'); if(bytes.size() % 2) bytes.append('0');
bytes = QByteArray::fromHex(bytes); bytes = QByteArray::fromHex(bytes);
if(pcap_sendpacket(pcap, (u_char*)bytes.data(), bytes.size())) { if(pcap_sendpacket(pcap, (u_char*)bytes.data(), bytes.size())) {
QMessageBox::critical(this, "Error", QString("发送失败: ")+pcap_geterr(pcap)); QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcap));
return; return;
} }
}); });

View File

@ -10,7 +10,7 @@ class PcapThread : public QThread {
public: public:
explicit PcapThread(pcap *pcap); explicit PcapThread(pcap *pcap);
~PcapThread() { ~PcapThread() {
pcap_close(pcap); //pcap_close(pcap);
} }
pcap *pcap; pcap *pcap;
std::atomic<char> status{0}; std::atomic<char> status{0};
@ -24,11 +24,11 @@ signals:
class PcapWin : public BaseWin { class PcapWin : public BaseWin {
Q_OBJECT Q_OBJECT
public: public:
static PcapWin *newIns(QWidget *); // static PcapWin *newIns(QWidget *);
explicit PcapWin(pcap *, pcap *, QWidget *parent = nullptr); explicit PcapWin(pcap *, pcap *, QWidget *parent = nullptr);
~PcapWin() { ~PcapWin() {
pcap_close(pcap); //pcap_close(pcap);
thd->status = 2; thd->status = 2;
} }
PcapThread *thd{0}; PcapThread *thd{0};

View File

@ -1,8 +1,10 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>128.ico</file> <file>128.ico</file>
<file>imgs/radio-un.png</file> <file>imgs/checkbox-check.png</file>
<file>imgs/checkbox-un.png</file>
<file>imgs/radio-check.png</file> <file>imgs/radio-check.png</file>
<file>imgs/radio-un.png</file>
<file>imgs/bright.png</file> <file>imgs/bright.png</file>
<file>imgs/correct.png</file> <file>imgs/correct.png</file>
<file>imgs/expert.png</file> <file>imgs/expert.png</file>
@ -19,5 +21,7 @@
<file>imgs/conn6.png</file> <file>imgs/conn6.png</file>
<file>imgs/conn7.png</file> <file>imgs/conn7.png</file>
<file>imgs/conn8.png</file> <file>imgs/conn8.png</file>
<file>imgs/macos-minimize.png</file>
<file>imgs/close.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -8,10 +8,7 @@ Table::Table(std::initializer_list<ColAttr> colAttrs, QWidget *parent) : QTableW
item->setText(it->text); item->setText(it->text);
item->setData(0x99, it->width); item->setData(0x99, it->width);
if(it->width > 0) horizontalHeader()->resizeSection(i, it->width); if(it->width > 0) horizontalHeader()->resizeSection(i, it->width);
else if(it->width < 0) { if(it->resizeMode != QHeaderView::Interactive) horizontalHeader()->setSectionResizeMode(i, it->resizeMode);
if(it->width == Stretch) horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
if(it->width == ResizeToContents) horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
mFieldMap.insert(it->field, i++); mFieldMap.insert(it->field, i++);
} }
} }
@ -21,11 +18,11 @@ int Table::sizeHintForColumn(int column) const {
int width = item->data(0x99).toInt(); int width = item->data(0x99).toInt();
if(width==0) return QTableWidget::sizeHintForColumn(column); if(width==0) return QTableWidget::sizeHintForColumn(column);
auto header = horizontalHeader(); auto header = horizontalHeader();
if(header->sectionResizeMode(column)!=QHeaderView::ResizeToContents) return QTableWidget::sizeHintForColumn(column); if(header->sectionResizeMode(column) != QHeaderView::ResizeToContents) return QTableWidget::sizeHintForColumn(column);
int colCnt = columnCount(); int colCnt = columnCount();
int remainWidth = header->width(), stretchWidth = width; int remainWidth = header->width(), stretchWidth = width;
for(int cc=0; cc<colCnt; cc++) if(cc!=column && (item = horizontalHeaderItem(cc))) { for(int cc=0; cc<colCnt; cc++) if(cc!=column && (item = horizontalHeaderItem(cc))) {
if(header->sectionResizeMode(cc)==QHeaderView::ResizeToContents) stretchWidth += item->data(0x99).toInt(); if(header->sectionResizeMode(cc) == QHeaderView::ResizeToContents) stretchWidth += item->data(0x99).toInt();
else remainWidth -= item->data(0x99).toInt(); else remainWidth -= item->data(0x99).toInt();
} }
if(remainWidth<=0) return QTableWidget::sizeHintForColumn(column); if(remainWidth<=0) return QTableWidget::sizeHintForColumn(column);

View File

@ -5,17 +5,16 @@
#include <QHeaderView> #include <QHeaderView>
struct ColAttr { struct ColAttr {
ColAttr(QString field, QString text, int width = 0, QHeaderView::ResizeMode resizeMode = QHeaderView::Interactive) : field(field), text(text), width(width), resizeMode(resizeMode) {}
ColAttr(QString field, QString text, QHeaderView::ResizeMode resizeMode) : field(field), text(text), resizeMode(resizeMode) {}
QString field; QString field;
QString text; QString text;
int width{0}; int width{0};
QHeaderView::ResizeMode resizeMode{QHeaderView::Interactive};
}; };
class Table : public QTableWidget { class Table : public QTableWidget {
Q_OBJECT Q_OBJECT
public: public:
enum ResizeMode {
Stretch = -0x1000000,
ResizeToContents
};
explicit Table(QWidget *parent = nullptr) : QTableWidget{parent} {} explicit Table(QWidget *parent = nullptr) : QTableWidget{parent} {}
Table(std::initializer_list<ColAttr> colAttrs, QWidget *parent = nullptr); Table(std::initializer_list<ColAttr> colAttrs, QWidget *parent = nullptr);
@ -35,6 +34,13 @@ public:
return this; return this;
} }
void setHeaderText(QString column, QString text) {
auto col = mFieldMap[column];
auto item = horizontalHeaderItem(col);
if(item==0) setHorizontalHeaderItem(col, item = new QTableWidgetItem());
item->setText(text);
}
auto item(int row, QString column) { auto item(int row, QString column) {
auto col = mFieldMap[column]; auto col = mFieldMap[column];
return QTableWidget::item(row, col); return QTableWidget::item(row, col);

View File

@ -1,3 +1,677 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS> <!DOCTYPE TS>
<TS version="2.1" language="en_US"></TS> <TS version="2.1" language="en_US">
<context>
<name>BrightWin</name>
<message>
<location filename="../brightwin.cpp" line="15"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="23"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="33"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="54"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="77"/>
<location filename="../brightwin.cpp" line="160"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="85"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="95"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="116"/>
<source>绿</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="137"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../brightwin.cpp" line="169"/>
<source>Gamma </source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ExpertScreenConnWin</name>
<message>
<location filename="../expertscreenconnwin.cpp" line="32"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="40"/>
<source>X坐标: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="47"/>
<source>Y坐标: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="55"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="65"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="75"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="85"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="93"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="102"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="119"/>
<source>线:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="173"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="180"/>
<source>退</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="211"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertscreenconnwin.cpp" line="211"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ExpertSmartPointSetWin</name>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="20"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="38"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="51"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="63"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="75"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="93"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="104"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="108"/>
<source>138</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="115"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="119"/>
<source>线</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="120"/>
<source>1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="121"/>
<source>8</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="122"/>
<source>16</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="140"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="152"/>
<source>线//: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="158"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="161"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="170"/>
<source>线/: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="188"/>
<source>245: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="212"/>
<source>线</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="217"/>
<source>, </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="223"/>
<source>1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="228"/>
<location filename="../expertsmartpointsetwin.cpp" line="254"/>
<location filename="../expertsmartpointsetwin.cpp" line="280"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="233"/>
<location filename="../expertsmartpointsetwin.cpp" line="258"/>
<location filename="../expertsmartpointsetwin.cpp" line="284"/>
<source>绿</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="237"/>
<location filename="../expertsmartpointsetwin.cpp" line="263"/>
<location filename="../expertsmartpointsetwin.cpp" line="288"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="241"/>
<location filename="../expertsmartpointsetwin.cpp" line="267"/>
<location filename="../expertsmartpointsetwin.cpp" line="293"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="250"/>
<source>2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="276"/>
<source>3</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="351"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="362"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="371"/>
<location filename="../expertsmartpointsetwin.cpp" line="561"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="402"/>
<location filename="../expertsmartpointsetwin.cpp" line="411"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="402"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="411"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="430"/>
<source>:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="433"/>
<source>: :</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="442"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="446"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="483"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="511"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="516"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="526"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="527"/>
<source>1X2_3扫</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="531"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="539"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="542"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertsmartpointsetwin.cpp" line="566"/>
<source></source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ExpertWin</name>
<message>
<location filename="../expertwin.cpp" line="196"/>
<source>线</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="200"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="258"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="261"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="277"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="280"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="286"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="287"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="288"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="289"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="293"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="294"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="295"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="296"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="300"/>
<source>180</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="302"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="320"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="326"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="334"/>
<source>:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="344"/>
<source>DCLK频率:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="359"/>
<source>DCLK相位:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="366"/>
<source>DCLK占空比:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="373"/>
<source>(ns):</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="382"/>
<source>:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="384"/>
<source>100%</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="388"/>
<source>GCLK频率:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="403"/>
<source>:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="416"/>
<source>GCLK占空比:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="423"/>
<source>(ns):</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="434"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="445"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="450"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="455"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="460"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="465"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="477"/>
<source>:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../expertwin.cpp" line="483"/>
<source>()</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainWin</name>
<message>
<location filename="../mainwin.cpp" line="83"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="87"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="91"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="95"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="99"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="103"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="111"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="131"/>
<source>版本:221114</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="144"/>
<location filename="../mainwin.cpp" line="149"/>
<location filename="../mainwin.cpp" line="183"/>
<location filename="../mainwin.cpp" line="186"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="163"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="168"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="223"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwin.cpp" line="224"/>
<source>:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PcapWin</name>
<message>
<location filename="../pcapwin.cpp" line="30"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pcapwin.cpp" line="48"/>
<source>:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pcapwin.cpp" line="51"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pcapwin.cpp" line="59"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pcapwin.cpp" line="64"/>
<location filename="../pcapwin.cpp" line="94"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pcapwin.cpp" line="88"/>
<source></source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pcapwin.cpp" line="116"/>
<source>: </source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -1,5 +1,4 @@
#include "videowin.h" #include "videowin.h"
#include "table.h"
#include "gqt.h" #include "gqt.h"
#include "crc.h" #include "crc.h"
#include <QTextEdit> #include <QTextEdit>
@ -15,115 +14,7 @@
using namespace std; using namespace std;
QByteArray getNetDev(QWidget *parent) { VideoWin *VideoWin::newIns(QByteArray &name, QWidget *parent) {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devs;
if(pcap_findalldevs(&devs, errbuf) == -1) {
QMessageBox::critical(parent, "Error", QString("寻找网卡失败")+errbuf);
return QByteArray();
}
auto table = new Table{
{"name", "网卡名称", 400},
{"desc", "网卡描述", 300},
{"loopback","Loopback"},
{"ip","IP"},
{"netmask","Netmask"},
{"broadaddr","Broad Addr"},
{"dstaddr","Dst Addr"}
};
pcap_if_t *device = 0;
for(pcap_if_t *dev = devs; dev; dev = dev->next) {
pcap_addr_t *a;
for(a=dev->addresses; a; a=a->next) {
auto sa_family = a->addr->sa_family;
if(sa_family==AF_INET) {
auto rr = table->rowCount();
table->setRowCount(rr+1);
table->setValue(rr, "name", dev->name);
table->setValue(rr, "desc", dev->description);
table->setValue(rr, "loopback", (dev->flags & PCAP_IF_LOOPBACK)?"True":"False");
auto ip = (u_char *) &((sockaddr_in *) a->addr)->sin_addr.s_addr;
table->setValue(rr, "ip", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
if(a->netmask) {
ip = (u_char *) &((sockaddr_in *) a->netmask)->sin_addr.s_addr;
table->setValue(rr, "netmask", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(a->broadaddr) {
ip = (u_char *) &((sockaddr_in *) a->broadaddr)->sin_addr.s_addr;
table->setValue(rr, "broadaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(a->dstaddr) {
ip = (u_char *) &((sockaddr_in *) a->dstaddr)->sin_addr.s_addr;
table->setValue(rr, "dstaddr", QString::asprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]));
}
if(device==0) device = dev;
}
}
}
pcap_freealldevs(devs);
auto rowCnt = table->rowCount();
if(rowCnt==0) {
table->deleteLater();
QMessageBox::critical(parent, "Error", "没找到 internet 设备");
return QByteArray();
} else if(rowCnt==1) {
table->deleteLater();
return table->item(0, "name")->text().toLocal8Bit();
} else {
auto dlg = new BaseDlg(parent);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setWindowTitle("选择网卡");
dlg->resize(900, 300);
auto vBox = new QVBoxLayout(dlg->center);
vBox->setContentsMargins(0,0,0,0);
vBox->setSpacing(3);
vBox->addSpacing(30);
table->setDefs();
table->setSelectionMode(QAbstractItemView::SingleSelection);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
table->selectRow(0);
QByteArray name;
dlg->connect(table, &Table::cellDoubleClicked, dlg, [dlg, table, &name](int row) {
name = table->item(row, "name")->text().toLocal8Bit();
dlg->accept();
});
vBox->addWidget(table);
auto hBox = new QHBoxLayout;
hBox->addStretch();
auto btnOk = new QPushButton("确定");
btnOk->setMinimumWidth(80);
dlg->connect(btnOk, &QPushButton::clicked, dlg, [dlg, table, &name] {
auto sels = table->selectedRanges();
if(sels.isEmpty()) {
QMessageBox::warning(dlg, "Warning", "请选择网卡");
return;
}
name = table->item(sels[0].topRow(), "name")->text().toLocal8Bit();
dlg->accept();
});
hBox->addWidget(btnOk);
hBox->addStretch();
auto btnClose = new QPushButton("关闭");
btnClose->setMinimumWidth(80);
dlg->connect(btnClose, &QPushButton::clicked, dlg, &QDialog::reject);
hBox->addWidget(btnClose);
hBox->addStretch();
vBox->addLayout(hBox);
dlg->exec();
return name;
}
}
VideoWin *VideoWin::newIns(QWidget *parent) {
auto name = getNetDev(parent);
if(name.isEmpty()) return 0; if(name.isEmpty()) return 0;
char errbuf[PCAP_ERRBUF_SIZE]{'\0'}; char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS, 50, errbuf); auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS, 50, errbuf);
@ -164,13 +55,38 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi
fdHeight->setValue(360); fdHeight->setValue(360);
hBox->addWidget(fdHeight); hBox->addWidget(fdHeight);
hBox->addWidget(new QLabel("截图间隔(ms)"));
fdMsecCapScr = new QSpinBox;
fdMsecCapScr->setRange(1, 1000);
fdMsecCapScr->setValue(17);
hBox->addWidget(fdMsecCapScr);
hBox->addSpacing(20);
fdShowImg = new QRadioButton("关闭显示");
fdShowImg->setChecked(showImg);
hBox->addWidget(fdShowImg);
hBox->addSpacing(20);
hBox->addWidget(new QLabel("接收线程优先级"));
fdYxj = new QSpinBox;
fdYxj->setRange(0, 7);
fdYxj->setValue(6);
connect(fdYxj, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, [=](int value) {
if(thdRece) thdRece->setPriority(QThread::Priority(value));
});
hBox->addWidget(fdYxj);
hBox->addSpacing(20); hBox->addSpacing(20);
auto fdStart = new QRadioButton("发送"); auto fdStart = new QRadioButton("发送");
connect(fdStart, &QRadioButton::toggled, this, [this](bool checked) { connect(fdStart, &QRadioButton::toggled, this, [this](bool checked) {
if(! checked) return; if(! checked) return;
screen = QGuiApplication::primaryScreen(); screen = QGuiApplication::primaryScreen();
if(timerId==0) timerId = startTimer(17); if(timerId==0) timerId = startTimer(fdMsecCapScr->value());
}); });
hBox->addWidget(fdStart); hBox->addWidget(fdStart);
hBox->addSpacing(20); hBox->addSpacing(20);
@ -206,11 +122,22 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi
auto fdCanvas = new Canvas; auto fdCanvas = new Canvas;
vBox->addWidget(fdCanvas, 1); vBox->addWidget(fdCanvas, 1);
connect(fdShowImg, &QRadioButton::toggled, [=](bool checked) {
qDebug()<<"fdShowImg"<<checked;
showImg = checked;
if(thdRece) thdRece->showImg = checked;
if(! checked) {
fdCanvas->img = QImage();
fdCanvas->update();
}
});
thdRece = new VideoRecThread(pcapRece); thdRece = new VideoRecThread(pcapRece);
connect(thdRece, &QThread::finished, this, [this] { connect(thdRece, &QThread::finished, this, [this] {
thdRece = 0; thdRece = 0;
}); });
connect(thdRece, &VideoRecThread::onMsg, fdCanvas, [this, fdCanvas](QImage img, int lostTimes, int lostPkts) { connect(thdRece, &VideoRecThread::onMsg, fdCanvas, [this, fdCanvas](QImage img, int lostTimes, int lostPkts) {
if(! showImg) return;
fdCanvas->img = img; fdCanvas->img = img;
fdCanvas->update(); fdCanvas->update();
if(lostPkts==0) return; if(lostPkts==0) return;
@ -219,7 +146,7 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi
fdLostTimes->setText(QString::number(this->lostTimes)); fdLostTimes->setText(QString::number(this->lostTimes));
fdLostPkts->setText(QString::number(this->lostPkts)); fdLostPkts->setText(QString::number(this->lostPkts));
}); });
thdRece->start(QThread::TimeCriticalPriority); thdRece->start(QThread::Priority(fdYxj->value()));//HighestPriority //InheritPriority //TimeCriticalPriority
sendThd = new VideoSendThread(pcapSend); sendThd = new VideoSendThread(pcapSend);
connect(sendThd, &QThread::finished, this, [this] { connect(sendThd, &QThread::finished, this, [this] {
@ -283,6 +210,7 @@ void VideoSendThread::run() {
bytes.append(img.width()>>8).append(img.width()).append(img.height()>>8).append(img.height()); bytes.append(img.width()>>8).append(img.width()).append(img.height()>>8).append(img.height());
crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-4, 4); crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-4, 4);
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32); bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
//发送帧开始指令包
auto queue = pcap_sendqueue_alloc(img.width()*img.height()*4); auto queue = pcap_sendqueue_alloc(img.width()*img.height()*4);
{ {
struct pcap_pkthdr pktheader; struct pcap_pkthdr pktheader;
@ -300,6 +228,7 @@ void VideoSendThread::run() {
auto bytesPerLine = img.bytesPerLine(); auto bytesPerLine = img.bytesPerLine();
auto bits = img.constBits(); auto bits = img.constBits();
idx = 0; idx = 0;
//按行发送图像数据包
for(int i=0; i<img.height(); i++) for(int j=0; j<lineLen; j+=once) { for(int i=0; i<img.height(); i++) for(int j=0; j<lineLen; j+=once) {
int dataLen = lineLen - j; int dataLen = lineLen - j;
if(dataLen > once) dataLen = once; if(dataLen > once) dataLen = once;
@ -313,7 +242,7 @@ void VideoSendThread::run() {
bytes.append(2, 0); //应答填充项 bytes.append(2, 0); //应答填充项
crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2); crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32); bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
bytes.append(idx>>24).append(idx>>16).append(idx>>8).append(idx); bytes.append(idx>>24).append(idx>>16).append(idx>>8).append(idx);//包序号
idx++; idx++;
bytes.append((const char*)bits + i * bytesPerLine + j, dataLen - 4); bytes.append((const char*)bits + i * bytesPerLine + j, dataLen - 4);
crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen); crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen);
@ -334,6 +263,7 @@ void VideoSendThread::run() {
crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2); crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32); bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
pktheader.len = pktheader.caplen = bytes.size(); pktheader.len = pktheader.caplen = bytes.size();
//发送帧结束指令包
if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) { if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
onErr(QString("添加结束失败: ")+pcap_geterr(pcap)); onErr(QString("添加结束失败: ")+pcap_geterr(pcap));
goto end; goto end;
@ -348,11 +278,10 @@ void VideoSendThread::run() {
pcap_sendqueue_destroy(queue); pcap_sendqueue_destroy(queue);
} }
} }
/* Callback function invoked by libpcap for every incoming packet */ /* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { //void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {
} //}
VideoRecThread::VideoRecThread(pcap_t *pcap) : pcap(pcap) { VideoRecThread::VideoRecThread(pcap_t *pcap) : pcap(pcap) {
connect(this, &QThread::finished, this, &QThread::deleteLater); connect(this, &QThread::finished, this, &QThread::deleteLater);
@ -366,7 +295,7 @@ void VideoRecThread::run() {
int lostTimes{0}, lostPkts{0}; int lostTimes{0}, lostPkts{0};
while((res = pcap_next_ex(pcap, &header, &data)) >= 0) { while((res = pcap_next_ex(pcap, &header, &data)) >= 0) {
if(status==2) return; if(status==2) return;
if(status==1 || res == 0) continue; //超时 if(status==1 || res == 0 || !showImg) continue; //超时
if(header->caplen<24) continue; if(header->caplen<24) continue;
if(data[0]!=0x55 || data[1]!=0x55) continue; if(data[0]!=0x55 || data[1]!=0x55) continue;
if(data[2]==0x9a && data[3]==0x3d) { if(data[2]==0x9a && data[3]==0x3d) {
@ -396,7 +325,7 @@ void VideoRecThread::run() {
emit onErr(pcap_geterr(pcap)); emit onErr(pcap_geterr(pcap));
} }
void Canvas::paintEvent(QPaintEvent *event) { void Canvas::paintEvent(QPaintEvent *) {
QPainter painter(this); QPainter painter(this);
painter.drawImage(0, 0, img); painter.drawImage(0, 0, img);
} }

View File

@ -9,13 +9,12 @@
#include <QSpinBox> #include <QSpinBox>
#include <QLabel> #include <QLabel>
#include <QRadioButton> #include <QRadioButton>
#include <QCheckBox>
#include "Win32-Extensions.h" #include "Win32-Extensions.h"
#pragma comment(lib, "wpcap.lib") #pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "Ws2_32.lib")
QByteArray getNetDev(QWidget *parent);
class VideoSendThread : public QThread { class VideoSendThread : public QThread {
Q_OBJECT Q_OBJECT
public: public:
@ -41,6 +40,7 @@ public:
} }
pcap *pcap; pcap *pcap;
std::atomic<char> status{0}; std::atomic<char> status{0};
bool showImg{true};
protected: protected:
void run(); void run();
signals: signals:
@ -58,9 +58,8 @@ protected:
class VideoWin : public BaseWin { class VideoWin : public BaseWin {
Q_OBJECT Q_OBJECT
public: public:
static VideoWin *newIns(QWidget *); static VideoWin *newIns(QByteArray &, QWidget *);
explicit VideoWin(pcap *, pcap *, QWidget *parent = nullptr);
~VideoWin() { ~VideoWin() {
if(thdRece) thdRece->status = 2; if(thdRece) thdRece->status = 2;
if(sendThd) sendThd->status = 2; if(sendThd) sendThd->status = 2;
@ -70,13 +69,16 @@ public:
VideoSendThread *sendThd{0}; VideoSendThread *sendThd{0};
QScreen *screen; QScreen *screen;
int timerId{0}; int timerId{0};
QSpinBox *fdWidth, *fdHeight; QSpinBox *fdWidth, *fdHeight, *fdMsecCapScr,*fdYxj;
QRadioButton *fdShowImg;
bool showImg{true};
QRadioButton *fdEnd; QRadioButton *fdEnd;
QLabel *fdInfo, *fdLostTimes, *fdLostPkts; QLabel *fdInfo, *fdLostTimes, *fdLostPkts;
QString info; QString info;
qint64 last_epoch{0}; qint64 last_epoch{0};
int lostTimes{0}, lostPkts{0}; int lostTimes{0}, lostPkts{0};
protected: protected:
explicit VideoWin(pcap *, pcap *, QWidget *parent = nullptr);
void timerEvent(QTimerEvent *event) override; void timerEvent(QTimerEvent *event) override;
}; };