diff --git a/ledset/basewin.cpp b/ledset/basewin.cpp index d78557f..96a70c3 100644 --- a/ledset/basewin.cpp +++ b/ledset/basewin.cpp @@ -52,8 +52,7 @@ void BaseWinBase::paintEvent() { } QString title = that->windowTitle(); if(! title.isEmpty()) { - static const QPen penTitleUnact(Qt::gray); - painter.setPen(isActive ? pal.windowText().color() : penTitleUnact); + painter.setPen(isActive ? pal.windowText().color() : Qt::gray); isMax ? painter.drawText(titlePos.x()-8, titlePos.y()-8, title) : painter.drawText(titlePos, title); } auto icon = that->windowIcon(); diff --git a/ledset/expertboxlayoutwin.cpp b/ledset/expertboxlayoutwin.cpp index a938f92..6fda8f0 100644 --- a/ledset/expertboxlayoutwin.cpp +++ b/ledset/expertboxlayoutwin.cpp @@ -1,13 +1,15 @@ #include "expertboxlayoutwin.h" #include "moduleunit.h" #include "gutil/qgui.h" +#include "gutil/qjson.h" +#include "globalfunc.h" #include #include #include #include +#include ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} { - //setWindowModality(Qt::WindowModal); setAttribute(Qt::WA_DeleteOnClose); setWindowTitle("箱体高级布局"); resize(1024, 720); @@ -24,6 +26,23 @@ ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} { auto grid = new Grid(vBox); auto btnAdd = new QPushButton("添加"); + connect(btnAdd, &QPushButton::clicked, this, [this] { + auto file = QFileDialog::getOpenFileName(this, tr("打开单元板文件"), gFileHome, tr("单元板文件 (*.module)")); + if(file.isEmpty()) return; + QFile qFile(file); + if(! qFile.open(QFile::ReadOnly)) { + QMessageBox::critical(this, tr("打开单元板文件失败"), file); + return; + } + QString err; + auto json = JFrom(&qFile, &err).toObj(); + qFile.close(); + if(! err.isEmpty()) { + QMessageBox::critical(this, tr("解析 json 失败"), err+" "+file); + return; + } + new ModuleUnit(this, "J1", 0, 0, json["ModuleWidth"].toInt(), json["ModuleHeight"].toInt(), box); + }); grid->addWidget(btnAdd, 0, 0); auto btnDel = new QPushButton("删除"); grid->addWidget(btnDel, 0, 1); @@ -69,29 +88,13 @@ ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} { auto scroll = new QScrollArea; vBox->addWidget(scroll); - auto screen = new QWidget(scroll); - screen->setGeometry(0, 0, 1024, 1024); - screen->setAutoFillBackground(true); + box = new QWidget; + scroll->setWidget(box); + box->resize(1024, 1024); + box->setAutoFillBackground(true); auto pal = palette(); pal.setColor(QPalette::Window, QColor(0x222222)); - screen->setPalette(pal); + box->setPalette(pal); - int idx = 0; - for(int rr=0; rr<4; rr++) { - QString name = "P"+QString::number(rr+1); - - auto unit = new ModuleUnit(this, name, idx, 0, 128, 128, screen); - unit->setAutoFillBackground(true); - unit->setPalette(pal); - idx += 128; - } - -// connect(canvas, &ResizeEmitedWgt::resized, this, [this, canvas, screen] { -// screen->resize(qRound(screenWidth*rate), qRound(screenHeight*rate)); -// auto children = screen->children(); -// foreach(auto childObj, children) { -// auto unit = static_cast(childObj); -// unit->setGeometry(qRound(unit->mX*rate), qRound(unit->mY*rate), qRound(unit->mW*rate), qRound(unit->mH*rate)); -// } -// }); + new ModuleUnit(this, "J1", 0, 0, 128, 128, box); } diff --git a/ledset/expertboxlayoutwin.h b/ledset/expertboxlayoutwin.h index 8d89c54..19a288c 100644 --- a/ledset/expertboxlayoutwin.h +++ b/ledset/expertboxlayoutwin.h @@ -10,6 +10,8 @@ class ExpertBoxLayoutWin : public BaseWin { Q_OBJECT public: explicit ExpertBoxLayoutWin(QWidget *parent = 0); + double rate{1}; + QWidget *box; }; #endif // EXPERTBOXLAYOUTWIN_H diff --git a/ledset/expertscreenconnwin.cpp b/ledset/expertscreenconnwin.cpp index 658784c..05c9737 100644 --- a/ledset/expertscreenconnwin.cpp +++ b/ledset/expertscreenconnwin.cpp @@ -13,175 +13,161 @@ #define M_PI 3.14159265358979323846 QColor cardColors[] {QColor(0xff2222), QColor(0xffaa00), QColor(0x00bb00), QColor(0x00bbcc), QColor(0x0044ff), QColor(0xffffff), QColor(0xffff00)}; -ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} { - auto vv = new VBox(this); - vv->setContentsMargins(4, 4, 4, 4); - auto hh = new HBox(vv); - - auto leftWgt = new QWidget; - auto poli = leftWgt->sizePolicy(); - poli.setHorizontalPolicy(QSizePolicy::Maximum); - leftWgt->setSizePolicy(poli); - hh->addWidget(leftWgt); - - auto vvv = new QVBoxLayout(leftWgt); - vvv->setContentsMargins(0,0,0,0); +ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QSplitter{parent} { + auto vBox = new VBox(this); auto gBox = new QGroupBox(tr("起始位置")); - vvv->addWidget(gBox); + vBox->addWidget(gBox); + + auto hh = new HBox(gBox); + + auto lb = new QLabel(tr("X坐标: ")); + hh->addWidget(lb); auto fdX = new QSpinBox; + fdX->setRange(0, 99999); + fdX->setValue(0); + hh->addWidget(fdX); + + lb = new QLabel(tr("Y坐标: ")); + hh->addWidget(lb); + auto fdY = new QSpinBox; - { - auto hhh = new QHBoxLayout(gBox); + fdY->setRange(0, 99999); + fdY->setValue(0); + hh->addWidget(fdY); - auto lb = new QLabel(tr("X坐标: ")); - hhh->addWidget(lb); - - fdX->setRange(0, 99999); - fdX->setValue(0); - hhh->addWidget(fdX); - - lb = new QLabel(tr("Y坐标: ")); - hhh->addWidget(lb); - - fdY->setRange(0, 99999); - fdY->setValue(0); - hhh->addWidget(fdY); - } gBox = new QGroupBox(tr("接收卡设置")); - vvv->addWidget(gBox); + vBox->addWidget(gBox); + + + auto vv = new VBox(gBox); + hh = new HBox(vv); + + lb = new QLabel(tr("卡列数: ")); + hh->addWidget(lb); auto fdCardColNum = new QSpinBox; - auto fdCardRowNum = new QSpinBox; - { - auto vBox = new QVBoxLayout(gBox); - auto hhh = new QHBoxLayout; - vBox->addLayout(hhh); - - auto lb = new QLabel(tr("卡列数: ")); - hhh->addWidget(lb); - - fdCardColNum->setRange(0, 9999); - fdCardColNum->setValue(2); + fdCardColNum->setRange(0, 9999); + fdCardColNum->setValue(2); // connect(fdCardColNum, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { // table->setColumnCount(value); // }); - hhh->addWidget(fdCardColNum); + hh->addWidget(fdCardColNum); - lb = new QLabel(tr("卡行数: ")); - hhh->addWidget(lb); + lb = new QLabel(tr("卡行数: ")); + hh->addWidget(lb); - fdCardRowNum->setRange(0, 9999); - fdCardRowNum->setValue(2); + auto fdCardRowNum = new QSpinBox; + fdCardRowNum->setRange(0, 9999); + fdCardRowNum->setValue(2); + hh->addWidget(fdCardRowNum); - hhh->addWidget(fdCardRowNum); + hh = new HBox(vv); - vBox->addLayout(hhh = new QHBoxLayout); + lb = new QLabel(tr("卡宽度: ")); + hh->addWidget(lb); - lb = new QLabel(tr("卡宽度: ")); - hhh->addWidget(lb); + fdCardWidth = new QSpinBox; + fdCardWidth->setRange(0, 9999); + fdCardWidth->setValue(128); + hh->addWidget(fdCardWidth); - fdCardWidth = new QSpinBox; - fdCardWidth->setRange(0, 9999); - fdCardWidth->setValue(128); - hhh->addWidget(fdCardWidth); + lb = new QLabel(tr("卡高度: ")); + hh->addWidget(lb); - lb = new QLabel(tr("卡高度: ")); - hhh->addWidget(lb); + fdCardHeight = new QSpinBox; + fdCardHeight->setRange(0, 9999); + fdCardHeight->setValue(128); + hh->addWidget(fdCardHeight); - fdCardHeight = new QSpinBox; - fdCardHeight->setRange(0, 9999); - fdCardHeight->setValue(128); - hhh->addWidget(fdCardHeight); - } gBox = new QGroupBox(tr("网口选择")); - vvv->addWidget(gBox); - auto hhh = new QHBoxLayout(gBox); + vBox->addWidget(gBox); + hh = new HBox(gBox); auto pal = palette(); fdNet = new QButtonGroup(gBox); for(int i=0; isetMaximumWidth(30); + bn->setMinimumHeight(30); bn->setCheckable(true); if(i==0) bn->setChecked(true); - bn->setMinimumHeight(30); pal.setColor(QPalette::ButtonText, cardColors[i%(sizeof(cardColors)/sizeof(cardColors[0]))]); bn->setPalette(pal); - hhh->addWidget(bn); + hh->addWidget(bn); fdNet->addButton(bn, i); } gBox = new QGroupBox(tr("快速串线:")); gBox->setStyleSheet("QToolButton {border: none; }"); - vvv->addWidget(gBox); - { - auto vvv = new QVBoxLayout(gBox); - hhh = new QHBoxLayout; - vvv->addLayout(hhh); + vBox->addWidget(gBox); - auto bnConn1 = new QToolButton; - bnConn1->setIconSize(QSize(48,48)); - bnConn1->setIcon(QIcon(":/imgs/conn1.png")); - hhh->addWidget(bnConn1); + vv = new VBox(gBox); + hh = new HBox(vv); - auto bnConn2 = new QToolButton; - bnConn2->setIconSize(QSize(48,48)); - bnConn2->setIcon(QIcon(":/imgs/conn2.png")); - hhh->addWidget(bnConn2); + auto bnConn1 = new QToolButton; + bnConn1->setIconSize(QSize(48,48)); + bnConn1->setIcon(QIcon(":/imgs/conn1.png")); + hh->addWidget(bnConn1); - auto bnConn3 = new QToolButton; - bnConn3->setIconSize(QSize(48,48)); - bnConn3->setIcon(QIcon(":/imgs/conn3.png")); - hhh->addWidget(bnConn3); + auto bnConn2 = new QToolButton; + bnConn2->setIconSize(QSize(48,48)); + bnConn2->setIcon(QIcon(":/imgs/conn2.png")); + hh->addWidget(bnConn2); - auto bnConn4 = new QToolButton; - bnConn4->setIconSize(QSize(48,48)); - bnConn4->setIcon(QIcon(":/imgs/conn4.png")); - hhh->addWidget(bnConn4); + auto bnConn3 = new QToolButton; + bnConn3->setIconSize(QSize(48,48)); + bnConn3->setIcon(QIcon(":/imgs/conn3.png")); + hh->addWidget(bnConn3); - hhh = new QHBoxLayout; - vvv->addLayout(hhh); + auto bnConn4 = new QToolButton; + bnConn4->setIconSize(QSize(48,48)); + bnConn4->setIcon(QIcon(":/imgs/conn4.png")); + hh->addWidget(bnConn4); - auto bnConn5 = new QToolButton; - bnConn5->setIconSize(QSize(48,48)); - bnConn5->setIcon(QIcon(":/imgs/conn5.png")); - hhh->addWidget(bnConn5); + hh = new HBox(vv); - auto bnConn6 = new QToolButton; - bnConn6->setIconSize(QSize(48,48)); - bnConn6->setIcon(QIcon(":/imgs/conn6.png")); - hhh->addWidget(bnConn6); + auto bnConn5 = new QToolButton; + bnConn5->setIconSize(QSize(48,48)); + bnConn5->setIcon(QIcon(":/imgs/conn5.png")); + hh->addWidget(bnConn5); - auto bnConn7 = new QToolButton; - bnConn7->setIconSize(QSize(48,48)); - bnConn7->setIcon(QIcon(":/imgs/conn7.png")); - hhh->addWidget(bnConn7); + auto bnConn6 = new QToolButton; + bnConn6->setIconSize(QSize(48,48)); + bnConn6->setIcon(QIcon(":/imgs/conn6.png")); + hh->addWidget(bnConn6); - auto bnConn8 = new QToolButton; - bnConn8->setIconSize(QSize(48,48)); - bnConn8->setIcon(QIcon(":/imgs/conn8.png")); - hhh->addWidget(bnConn8); - } + auto bnConn7 = new QToolButton; + bnConn7->setIconSize(QSize(48,48)); + bnConn7->setIcon(QIcon(":/imgs/conn7.png")); + hh->addWidget(bnConn7); - vvv->addLayout(hhh = new QHBoxLayout); + auto bnConn8 = new QToolButton; + bnConn8->setIconSize(QSize(48,48)); + bnConn8->setIcon(QIcon(":/imgs/conn8.png")); + hh->addWidget(bnConn8); + + + auto hBox = new HBox(vBox); auto bnRefresh = new QPushButton(tr("重新开始")); connect(bnRefresh, &QPushButton::clicked, this, [this] { table->clearContents(); for(int i=0; iaddWidget(bnRefresh); + hBox->addWidget(bnRefresh); auto bnBack = new QPushButton(tr("后退")); connect(bnBack, &QPushButton::clicked, this, &ExpertScreenConnWin::connBack); - hhh->addWidget(bnBack); + hBox->addWidget(bnBack); - hhh->addStretch(); + hBox->addStretch(); + + vBox->addStretch(); - vvv->addStretch(); table = new CardTable(fdCardRowNum->value(), fdCardColNum->value()); table->win = this; @@ -197,7 +183,11 @@ ExpertScreenConnWin::ExpertScreenConnWin(QWidget *parent) : QWidget{parent} { connect(table, &QTableWidget::currentCellChanged, this, &ExpertScreenConnWin::conn); connect(fdCardColNum, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, table, &QTableWidget::setColumnCount); connect(fdCardRowNum, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, table, &QTableWidget::setRowCount); - hh->addWidget(table); + addWidget(table); + + setStretchFactor(0,0); + setStretchFactor(1,1); + setSizes({280, 1}); } void ExpertScreenConnWin::conn(int row, int column) { diff --git a/ledset/expertscreenconnwin.h b/ledset/expertscreenconnwin.h index f9ec6b1..74579ec 100644 --- a/ledset/expertscreenconnwin.h +++ b/ledset/expertscreenconnwin.h @@ -1,12 +1,13 @@ #ifndef EXPERTSCREENCONNWIN_H #define EXPERTSCREENCONNWIN_H +#include #include #include #include class CardTable; -class ExpertScreenConnWin : public QWidget { +class ExpertScreenConnWin : public QSplitter { Q_OBJECT public: explicit ExpertScreenConnWin(QWidget *parent = nullptr); diff --git a/ledset/expertsmartpointsetwin.cpp b/ledset/expertsmartpointsetwin.cpp index 41f088d..e1939eb 100644 --- a/ledset/expertsmartpointsetwin.cpp +++ b/ledset/expertsmartpointsetwin.cpp @@ -67,9 +67,9 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e 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(); + ChipType = expertWin->mModule["ChipType"].toStr(); + DecodeMode = expertWin->mModule["DecodeMode"].toStr(); + GroupMode = expertWin->mModule["GroupMode"].toStr(); auto vBox = new VBox(center); vBox->setContentsMargins(0,0,0,0); @@ -482,10 +482,10 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e hhhh->addWidget(fdPolaStat2); hhhh->addStretch(); - auto fdPolaStat = new QButtonGroup(fdPolaStat1); - fdPolaStat->addButton(fdPolaStat1, 0); - fdPolaStat->addButton(fdPolaStat2, 1); - connect(fdPolaStat, &QButtonGroup::idClicked, this, [this] (int id) { + auto fdDataPolarity = new QButtonGroup(fdPolaStat1); + fdDataPolarity->addButton(fdPolaStat1, 1); + fdDataPolarity->addButton(fdPolaStat2, 0); + connect(fdDataPolarity, &QButtonGroup::idClicked, this, [this] (int id) { send(0x11, {0x01000000u | id}); }); @@ -522,10 +522,10 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e hhhh->addWidget(fdOEStat2); hhhh->addStretch(); - auto fdOEStat = new QButtonGroup(fdOEStat1); - fdOEStat->addButton(fdOEStat1, 0); - fdOEStat->addButton(fdOEStat2, 1); - connect(fdOEStat, &QButtonGroup::idClicked, this, [this] (int id) { + auto fdOePolarity = new QButtonGroup(fdOEStat1); + fdOePolarity->addButton(fdOEStat1, 0); + fdOePolarity->addButton(fdOEStat2, 1); + connect(fdOePolarity, &QButtonGroup::idClicked, this, [this] (int id) { send(0x11, {0x01100000u | id}); }); @@ -577,7 +577,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e auto fdLightNum = new QSpinBox; fdLightNum->setRange(0, 9999); - fdLightNum->setValue(2); + fdLightNum->setValue(1); hhhh->addWidget(fdLightNum); hhhh->addStretch(); @@ -805,7 +805,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e *decodeMode = DecodeModeCode; auto smartset = unitptr+modUnitMap.smartset+3; - *smartset = fdPolaStat->checkedId(); + *smartset = fdDataPolarity->checkedId(); auto groupNum = unitptr+modUnitMap.smartsetRes + 1; *groupNum = GroupNum; @@ -825,19 +825,21 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e else if(res) {QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend))); return;} waitingDlg->close(); } else if(idx==1) { + DataPolarity = fdDataPolarity->checkedId(); res12 &= ~(1u<<31); - res12 |= (uint)fdPolaStat->checkedId()<<31; - if(send(0x11, {0x01100000u | fdOEStat->checkedId(), res12})) return; + res12 |= (uint)DataPolarity<<31; + if(send(0x11, {0x01100000u | fdOePolarity->checkedId(), res12})) return; } else if(idx==2) { + OePolarity = fdOePolarity->checkedId(); res12 &= ~(1u<<30); - res12 |= (uint)fdOEStat->checkedId()<<30; + res12 |= (uint)OePolarity<<30; if(send(0x11, {0x01300000u, res12})) return; } else if(idx==3) { - lightNum = fdLightNum->value(); + RowPerScan = fdLightNum->value(); res12 &= ~0xffffu; - res12 |= (uint)(lightNum / GroupNum - 1)<<8; //折返次数 - res12 |= (uint)(ModuleHeight / lightNum); //扫描类型 - if(send(0x11, {0x01200000u | fdRGBStat->checkedId(), res12, ((uint)ModuleWidth+15) / 16 * 16 * lightNum / GroupNum})) return; + res12 |= (uint)(RowPerScan - 1)<<8; //折返次数 + res12 |= (uint)(ModuleHeight / (RowPerScan*GroupNum)); //扫描类型 + if(send(0x11, {0x01200000u | fdRGBStat->checkedId(), res12, ((uint)ModuleWidth+15) / 16 * 16 * RowPerScan})) return; } else if(idx==4) { bool hases[4]{true,true,true,true}; uint ids[4]; @@ -850,7 +852,8 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e break; } res12 &= ~(0xffu<<22); - res12 |= (ids[0]<<6 | ids[1]<<4 | ids[2]<<2 | ids[3]) << 22; + ColorMap = ids[0]<<6 | ids[1]<<4 | ids[2]<<2 | ids[3]; + res12 |= (uint)ColorMap << 22; if(send(0x11, {0x01400000u, res12})) return; table->setColumnCount(ModuleWidth); table->setRowCount(ModuleHeight); @@ -912,7 +915,7 @@ void ExpertSmartPointSetWin::save() { QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file)); return; } - QJsonObject obj; + JObj obj; obj.insert("ModuleWidth", ModuleWidth); obj.insert("ModuleHeight", ModuleHeight); obj.insert("GroupNum", GroupNum); @@ -920,7 +923,11 @@ void ExpertSmartPointSetWin::save() { obj.insert("ChipType", ChipType); obj.insert("DecodeMode", DecodeMode); obj.insert("GroupMode", GroupMode); - QJsonArray points; + obj.insert("DataPolarity", DataPolarity); + obj.insert("OePolarity", OePolarity); + obj.insert("ColorMap", ColorMap); + obj.insert("RowPerScan", RowPerScan); + JArray points; auto cnt = tableRow->columnCount(); if(cnt > ModuleWidth) { auto add = (cnt+ModuleWidth-1) / ModuleWidth * ModuleWidth - cnt; @@ -931,10 +938,10 @@ void ExpertSmartPointSetWin::save() { points.append(data.isValid() ? data.toPoint().x() : -1); } obj.insert("Points", points); - QJsonArray Scans; - foreach(QPoint scan, scans) Scans.append(scan.y()); + JArray Scans; + for(QPoint scan : scans) Scans.append(scan.y()); obj.insert("Scans", Scans); - auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented); + auto data = JToBytes(obj, " "); auto res = qFile.write(data); qFile.close(); if(res < 0) { diff --git a/ledset/expertsmartpointsetwin.h b/ledset/expertsmartpointsetwin.h index 9c55c65..7ce5ccd 100644 --- a/ledset/expertsmartpointsetwin.h +++ b/ledset/expertsmartpointsetwin.h @@ -29,9 +29,11 @@ public: QComboBox *fdGroupMode; int ModuleWidth{32}, ModuleHeight{16}, GroupNum{2}, ScanNum{4}; int ChipTypeCode, DecodeModeCode; + bool DataPolarity{true}, OePolarity{false}; + int ColorMap; QString ChipType, DecodeMode, GroupMode; - int lightNum{2}; + int RowPerScan{1}; uint res12; }; diff --git a/ledset/expertwin.cpp b/ledset/expertwin.cpp index a12939e..ebc0ef6 100644 --- a/ledset/expertwin.cpp +++ b/ledset/expertwin.cpp @@ -1,6 +1,5 @@ #include "expertwin.h" #include "gutil/qgui.h" -#include "crc.h" #include "screenunit.h" #include "expertboxlayoutwin.h" #include "expertsmartpointsetwin.h" @@ -18,14 +17,14 @@ #include #include #include +#include QColor colors[] {QColor(0xdd0000), QColor(0xdd6600), QColor(0x008800), QColor(0x008888), QColor(0x0000ff), QColor(0x777777), QColor(0xaaaaaa)}; ExpertWin::ExpertWin(QWidget *parent) : BaseWin{parent} { - //setWindowModality(Qt::WindowModal); setAttribute(Qt::WA_DeleteOnClose); setWindowTitle("专家调屏"); - resize(1024, 720); + resize(900, 720); auto vBox = new QVBoxLayout(center); vBox->setContentsMargins(0,0,0,0); @@ -40,20 +39,12 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou )rrr"); vBox->addWidget(tab); - auto sendPanel = new QWidget; - tab->addTab(sendPanel, "发送设备"); + auto splitter = new QSplitter; + tab->addTab(splitter, "发送设备"); { - auto hhh = new QHBoxLayout(sendPanel); - hhh->setContentsMargins(6,6,6,6); + auto vLeft = new VBox(splitter); - auto wgtLeft = new QWidget; - wgtLeft->setMaximumWidth(400); - hhh->addWidget(wgtLeft); - - auto vLeft = new QVBoxLayout(wgtLeft); - vLeft->setContentsMargins(0,0,0,0); - - auto hBox = new QHBoxLayout; + auto hBox = new HBox(vLeft); hBox->addWidget(new QLabel("分辨率: ")); auto fdW = new QLineEdit(QString::number(screenWidth)); @@ -64,9 +55,8 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou auto fdH = new QLineEdit(QString::number(screenHeight)); hBox->addWidget(fdH); - vLeft->addLayout(hBox); - hBox = new QHBoxLayout; + hBox = new HBox(vLeft); hBox->addStretch(); auto btnGet = new QPushButton("刷新"); @@ -80,7 +70,6 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou hBox->addWidget(btnSet); hBox->addStretch(); - vLeft->addLayout(hBox); auto table = new Table{ {"face", "网口", 40}, @@ -112,7 +101,12 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou unit->setGeometry(qRound(unit->mX*rate), qRound(unit->mY*rate), qRound(unit->mW*rate), qRound(unit->mH*rate)); } }); - hhh->addWidget(canvas); + splitter->addWidget(canvas); + + splitter->setStretchFactor(0,0); + splitter->setStretchFactor(1,1); + splitter->setSizes({320, 1}); + int idx = 0; for(int rr=0; rr<4; rr++) { @@ -131,8 +125,6 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou unit->setPalette(pal); idx += 128; } - - } { auto file = QApplication::applicationDirPath()+"/temp.screen"; @@ -140,11 +132,10 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou 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(); + auto json = JFrom(data).toObj(); + if(! json.empty()) { + mBox = json["ModuleConnectionInfo"].toObj(); + mModule = mBox["ModuleInfo"].toObj(); } } else { auto file = QApplication::applicationDirPath()+"/temp.module"; @@ -152,9 +143,8 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou 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 json = JFrom(data).toObj(); + if(! json.empty()) mModule = json; } } } @@ -178,10 +168,10 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou vvv = new VBox(hh); - fdChipType = new QLabel(mModule["ChipType"].toString()); + fdChipType = new QLabel(mModule["ChipType"].toStr()); vvv->addWidget(fdChipType); - fdDecodeMode = new QLabel(mModule["DecodeMode"].toString());//译码方式 + fdDecodeMode = new QLabel(mModule["DecodeMode"].toStr());//译码方式 vvv->addWidget(fdDecodeMode); hh->addSpacing(20); @@ -612,8 +602,8 @@ QByteArray ExpertWin::savedData() { 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); + JObj obj{{"ModuleConnectionInfo", mBox}}; + return JToBytes(obj, " "); } void ExpertWin::addMapData(QByteArray &data) { auto ModuleWidth = mModule["ModuleWidth"].toInt(); @@ -644,7 +634,7 @@ void ExpertWin::addMapData(QByteArray &data) { auto GroupNum = mModule["GroupNum"].toInt(); auto jCnt = ModuleCol * GroupNum; - foreach(auto scan, scans) { + for(auto scan : scans) { QList> chunkses; for(int j=0; j #include #include @@ -20,7 +21,7 @@ public: QLabel *fdModuleWidth, *fdModuleHeight, *fdGroupNum, *fdScanNum; QLabel *fdChipType, *fdDecodeMode; - QJsonObject mModule { + JObj mModule { {"ModuleWidth", 32}, {"ModuleHeight", 16}, {"GroupNum", 2}, @@ -29,7 +30,7 @@ public: {"DecodeMode", "138译码"}, {"GroupMode", "三线并行"} }; - QJsonObject mBox { + JObj mBox { {"ModuleRow", 1}, {"ModuleCol", 1}, {"Direction", 1}, diff --git a/ledset/globalfunc.cpp b/ledset/globalfunc.cpp index 6d5a2b7..bd56377 100644 --- a/ledset/globalfunc.cpp +++ b/ledset/globalfunc.cpp @@ -6,6 +6,8 @@ #include #include +QString gFileHome; + HeadMap headMap; byte *getSepas() { diff --git a/ledset/globalfunc.h b/ledset/globalfunc.h index 09be0b4..d8e937d 100644 --- a/ledset/globalfunc.h +++ b/ledset/globalfunc.h @@ -50,6 +50,7 @@ extern byte *sepas; extern pcap *pcapSend; class PcapReThread; extern PcapReThread *reThd; +extern QString gFileHome; QByteArray getNetDev(QWidget *parent, QByteArray, bool); diff --git a/ledset/gutil/cu.cpp b/ledset/gutil/cu.cpp new file mode 100644 index 0000000..989710e --- /dev/null +++ b/ledset/gutil/cu.cpp @@ -0,0 +1,2 @@ +//#include "cu.h" + diff --git a/ledset/gutil/cu.h b/ledset/gutil/cu.h new file mode 100644 index 0000000..6455023 --- /dev/null +++ b/ledset/gutil/cu.h @@ -0,0 +1,217 @@ +#ifndef CU_H +#define CU_H + +#include +#include +#include + +inline long long steady_milli() { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); +} +inline long long system_milli() { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); +} +inline long long steady_micro() { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); +} +inline long long system_micro() { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); +} + + +template +struct SharedData { + T data; + uint64_t cnt{1}; +}; +template +class SharedPtr { +public: + SharedPtr(SharedData *ptr = 0) : ptr{ptr} {} + SharedPtr(const SharedPtr &other) : ptr{other.ptr} { + if(ptr) ptr->cnt++; + } + ~SharedPtr() { + if(ptr==0) return; + if(ptr->cnt > 1) ptr->cnt--; + else delete ptr; + } + + bool isNull() {return ptr==0;} + SharedPtr &operator=(const SharedPtr &other) { + this->~SharedPtr(); + new (this) SharedPtr(other); + return *this; + } + + T &operator*() { + if(ptr==0) ptr = new SharedData; + return ptr->data; + } + T *operator->() { + if(ptr==0) ptr = new SharedData; + return &ptr->data; + } + const T &operator*() const { + return ptr->data; + } + const T *operator->() const { + return &ptr->data; + } + SharedData *ptr{0}; +}; + + +template +class Vector : public SharedPtr> { +public: + using SharedPtr>::SharedPtr; + + using iterator = std::_Vector_iterator>>; + using const_iterator = std::_Vector_const_iterator>>; + + Vector(std::initializer_list _Ilist) { + this->ptr = new SharedData>{_Ilist, 1}; + } + uint64_t size() const noexcept { + return this->ptr ? this->ptr->data.size() : 0; + } + Vector &append(const V &val) { + (**this).push_back(val); + return *this; + } + V &operator[](const uint64_t pos) noexcept { + return (**this)[pos]; + } + const V &operator[](const uint64_t pos) const noexcept { + return this->ptr ? this->ptr->data[pos] : V(); + } + const const_iterator begin() const noexcept { + return this->ptr ? this->ptr->data.begin() : const_iterator(); + } + const const_iterator end() const noexcept { + return this->ptr ? this->ptr->data.end() : const_iterator(); + } +}; + + +struct NodeBase { + NodeBase *next{this}; + NodeBase *prev{this}; +}; +template +struct _Node : NodeBase { + V value; + ~_Node() { + if(next) delete (_Node*) next; + } +}; + +template +class LinkedMapIterator { +public: + LinkedMapIterator(_Node *node) : node(node) {} + bool operator==(const LinkedMapIterator& that) const { + return node == that.node; + } + bool operator!=(const LinkedMapIterator& that) const { + return node != that.node; + } + LinkedMapIterator& operator++() { + node = (_Node*) node->next; + return *this; + } + LinkedMapIterator& operator--() { + node = (_Node*) node->prev; + return *this; + } + V &operator*() const { + return node->value; + } + V *operator->() const { + return &node->value; + } + _Node *node{0}; +}; + +template +struct LinkedMapPri : NodeBase { + std::unordered_map>*> map; + uint64_t cnt{1}; + ~LinkedMapPri() { + if(prev) prev->next = 0; + if(next) delete (_Node>*) next; + } +}; +template +class LinkedMap { +public: + using Node = _Node>; + + using iterator = LinkedMapIterator>; + using const_iterator = LinkedMapIterator>; + + LinkedMap() {} + LinkedMap(std::initializer_list> pairs) : _pri{new LinkedMapPri} { + for(auto pair : pairs) insert(pair.first, pair.second); + } + LinkedMap(std::unordered_map &&map) : _pri{new LinkedMapPri{0, 0, map}} { + _pri->next = _pri->prev = _pri; + } + LinkedMap(const LinkedMap &other) : _pri{other._pri} { + if(_pri) _pri->cnt++; + } + ~LinkedMap() { + if(_pri==0) return; + if(_pri->cnt > 1) _pri->cnt--; + else delete _pri; + } + + LinkedMap &operator=(const LinkedMap &other) { + this->~LinkedMap(); + new (this) LinkedMap(other); + return *this; + } + const V operator[](const K &k) const { + if(_pri==0) return V(); + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return V(); + return it->second->value.second; + } + LinkedMap &insert(const K &k, const V &v) { + if(_pri==0) _pri = new LinkedMapPri; + auto pair = _pri->map.emplace(k, nullptr); + if(pair.second) { + auto node = new Node{_pri, _pri->prev, {k, v}}; + _pri->prev->next = node; + _pri->prev = node; + pair.first->second = node; + } else pair.first->second->value.second = v; + return *this; + } + void erase(const K& k) { + if(_pri==0) return; + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return; + auto node = it->second; + _pri->map.erase(it); + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + delete node; + } + inline bool empty() const { + return _pri==0 || _pri->map.empty(); + } + + const_iterator begin() const { + return const_iterator((Node*) (_pri ? _pri->next : 0)); + } + const_iterator end() const { + return const_iterator((Node*) _pri); + } + LinkedMapPri *_pri{0}; +}; + +#endif // CU_H diff --git a/ledset/gutil/qgui.h b/ledset/gutil/qgui.h index 818a268..d7f7978 100644 --- a/ledset/gutil/qgui.h +++ b/ledset/gutil/qgui.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -61,11 +62,13 @@ public: inline VBox(QBoxLayout *parent) : QBoxLayout(TopToBottom) { parent->addLayout(this); }; - inline VBox(QStackedLayout *parent) : QBoxLayout(TopToBottom) { + inline VBox(QStackedLayout *stack) : QBoxLayout(TopToBottom, new QWidget) { + stack->addWidget(parentWidget()); + setContentsMargins(0,0,0,0); + }; + inline VBox(QSplitter *splitter) : QBoxLayout(TopToBottom, new QWidget) { + splitter->addWidget(parentWidget()); setContentsMargins(0,0,0,0); - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); }; inline QLabel *addLabel(const QString &text) { auto lb = new QLabel(text); @@ -79,11 +82,13 @@ public: inline HBox(QBoxLayout *parent) : QBoxLayout(LeftToRight) { parent->addLayout(this); }; - inline HBox(QStackedLayout *parent) : QBoxLayout(LeftToRight) { + inline HBox(QStackedLayout *stack) : QBoxLayout(LeftToRight, new QWidget) { + stack->addWidget(parentWidget()); + setContentsMargins(0,0,0,0); + }; + inline HBox(QSplitter *splitter) : QBoxLayout(LeftToRight, new QWidget) { + splitter->addWidget(parentWidget()); setContentsMargins(0,0,0,0); - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); }; inline QLabel *addLabel(const QString &text) { auto lb = new QLabel(text); @@ -97,11 +102,17 @@ public: inline Grid(QBoxLayout *parent) { parent->addLayout(this); }; - inline Grid(QStackedLayout *parent) { - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); + inline Grid(QStackedLayout *stack) : QGridLayout(new QWidget) { + stack->addWidget(parentWidget()); }; + inline Grid(QSplitter *splitter) : QGridLayout(new QWidget) { + splitter->addWidget(parentWidget()); + }; + inline QLabel *addLabel(const QString &text) { + auto lb = new QLabel(text); + addWidget(lb); + return lb; + } }; class ListWgt : public QListWidget { diff --git a/ledset/gutil/qjson.cpp b/ledset/gutil/qjson.cpp new file mode 100644 index 0000000..a95075c --- /dev/null +++ b/ledset/gutil/qjson.cpp @@ -0,0 +1,183 @@ +#include "qjson.h" + +inline QChar readOne(QTextStream &in) { + QChar ch; + in >> ch; + return ch; +} +JValue JParser::readValue() { + if(ch=='{') { + JObj obj; + while(true) { + do skipSpace(); //ch有三种可能 + while(ch==','); + if(ch=='}') return obj; + QString key; + if(ch == '"') key = readStr(); + else if(ch!='n' || in.read(3)!="ull") throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting double-quote to start field name or null"; + skipSpace(); + if(ch != ':') throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting a colon to separate field name and value"; + skipSpace(); + obj.insert(key, readValue()); + skipSpace(); //ch有两种可能 + if(ch=='}') return obj; + if(ch!=',') throw QString("Unexpected char ")+ch+"' (code "+ch+"): was expecting } to end Object or comma to separate Object entries"; + } + } + if(ch=='[') { + JArray list; + while(true) { + do skipSpace(); //ch有三种可能 + while(ch==','); + if(ch==']') return list; + list->push_back(readValue()); + skipSpace(); //ch有两种可能 + if(ch==']') return list; + if(ch!=',') throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting ] to end Array or comma to separate Array entries"; + } + } + if(ch=='"') return readStr(); + if((ch>='0' && ch<='9') || ch=='-') { + QString buf; + buf += ch; + bool isInt = true; + while(0 != (ch = readOne(in))) { + if((ch>'*' && ch<':' && ch!=',' && ch!='/') || ch=='e' || ch=='E') { + buf.append(ch); + if(isInt && ch=='.') isInt = false; + } else { + bk = ch; + break; + } + } + bool ok; + if(isInt) { + auto num = buf.toLongLong(&ok); + if(! ok) throw "Illegal number: "+buf; + return num; + } else { + auto num = buf.toDouble(&ok); + if(! ok) throw "Illegal number: "+buf; + return num; + } + } + if(ch=='n') { + if(in.read(3)=="ull") return JValue(); + else throw "Unexpected char n: expected null"; + } + if(ch=='t') { + if(in.read(3)=="rue") return true; + else throw "Unexpected char t: expected true"; + } + if(ch=='f') { + if(in.read(4)=="alse") return false; + else throw "Unexpected char f: expected false"; + } + throw QString("Unexpected char ")+ch+" (code "+ch+"): expected {}, [], \"string\", number, null, true or false"; +} +QString JParser::readStr() { + QString buf; + while((ch = readOne(in)) != '"') { + if(ch==0) throw "Unexpected end-of-input: was expecting closing quote for string"; + if(ch=='\\') { + in>>ch; + if(ch==0) throw "Unexpected end-of-input in char escape sequence"; + if(ch=='"' || ch=='\\' || ch=='/') buf.append(ch); + else if(ch=='n') buf.append('\n'); + else if(ch=='r') buf.append('\r'); + else if(ch=='t') buf.append('\t'); + else if(ch=='f') buf.append('\f'); + else if(ch=='b') buf.append('\b'); + else if(ch=='u') { + auto hex = in.read(4); + if(hex.size()<4) throw "Unexpected end-of-input in char escape sequence"; + bool ok; + buf.append(hex.toUShort(&ok, 16)); + if(! ok) throw "Illegal hex-digits in char escape sequence: \\u"+hex; + } else throw QString("Unrecognized char-escape ")+ch+" (code "+ch+")"; + } else buf.append(ch); + } + return buf; +} +void JParser::skipSpace() { + if(bk.unicode()) { + bk = QChar::Null; + if(! ch.isSpace()) return; + } + in.skipWhiteSpace(); + in >> ch; + if(ch==0) throw "Unexpected end-of-input"; +} + +void JOut::write(const JValue &value) { + if(value.type==JValue::Null) out << "null"; + else if(value.type==JValue::Str) writeStr(value.toStr()); + else if(value.type==JValue::Obj) writeMap(value.toObj()); + else if(value.type==JValue::Array) writeList(value.toArray()); + else out << value.toStr(); + out.flush(); +} +void JOut::writeStr(const QString &str) { + out << '"'; + QChar ch; + for(int i=0; i + +class JValue; +using JObj = LinkedMap; +using JArray = Vector; + +class JValue { +public: + int data[2]{0}; + enum Type { + Null, Bool, Int, Long, Double, Obj, Array, Str + }; + Type type{Null}; + + JValue(Type = Null) {} + JValue(bool b) : type(Bool) {data[0] = b;} + JValue(int n) : type(Int) {data[0] = n;} + JValue(qint64 n) : type(Long) {*(qint64*) data = n;} + JValue(double d) : type(Double) {*(double*) data = d;} + JValue(const JObj &o) : type(Obj) {new (data) JObj(o);} + JValue(const JArray &a) : type(Array) {new (data) JArray(a);} + JValue(const QString &s) : type(Str) {*(SharedData**) data = new SharedData{s, 1};} + JValue(const char *s) : JValue(QString::fromUtf8(s)) {} + JValue(const JValue &other) { + type = other.type; + if(type==Obj) new (data) JObj(*(JObj*) other.data); + else if(type==Array) new (data) JArray(*(JArray*) other.data); + else { + data[0] = other.data[0]; + data[1] = other.data[1]; + if(type==Str) (*(SharedData**) data)->cnt++; + } + } + ~JValue() { + if(type < Obj) return; + else if(type==Obj) ((JObj*) data)->~JObj(); + else if(type==Array) ((JArray*) data)->~JArray(); + else if(type==Str) { + auto ptr = *(SharedData**) data; + if(ptr->cnt > 1) ptr->cnt--; + else delete ptr; + } + } + + JValue &operator=(const JValue &other) { + this->~JValue(); + new (this) JValue(other); + return *this; + } + + bool isNull() const {return type==Null;} + bool isObj() const {return type==Obj;} + bool isArray() const {return type==Array;} + + bool toBool(bool def = false) const { + return type==Null ? def : data[0] || data[1]; + } + int toInt(int def = 0) const { + if(type==Bool || type==Int) return data[0]; + if(type==Long) return *(qint64*) data; + if(type==Double) return *(double*) data; + return def; + } + qint64 toLong(qint64 def = 0) const { + if(type==Bool || type==Int) return data[0]; + if(type==Long) return *(qint64*) data; + if(type==Double) return *(double*) data; + return def; + } + double toDouble(double def = 0) const { + if(type==Bool || type==Int) return data[0]; + if(type==Long) return *(qint64*) data; + if(type==Double) return *(double*) data; + return def; + } + QString toStr(const QString &def = "") const { + if(type==Bool) return data[0] ? "true" : "false"; + if(type==Int) return QString::number(data[0]); + if(type==Long) return QString::number(*(qint64*) data); + if(type==Double) return QString::number(*(double*) data); + if(type==Str) return (*(SharedData**) data)->data; + return def; + } + JObj toObj() const { + if(type==Obj) return *(JObj*) data; + return JObj(); + } + JArray toArray() const { + if(type==Array) return *(JArray*) data; + return JArray(); + } +private: + JValue(const void *) = delete; // avoid implicit conversions from char * to bool +}; + +class JParser { +public: + JParser(QTextStream &in) : in(in) {} + + inline JValue read() { + skipSpace(); + return readValue(); + } +protected: + JValue readValue(); + QString readStr(); + void skipSpace(); + + QTextStream ∈ + QChar ch{0}, bk{0}; +}; + +inline JValue JFrom(const QByteArray &json, QString *err = 0) { + QTextStream in(json); + try { + return JParser(in).read(); + } catch (QString anerr) { + if(err) *err = anerr; + } catch (const char *anerr) { + if(err) *err = anerr; + } catch (...) { + if(err) *err = "unknow error"; + } + return JValue(); +} +inline JValue JFrom(QIODevice *device, QString *err = 0) { + QTextStream in(device); + try { + return JParser(in).read(); + } catch (QString anerr) { + if(err) *err = anerr; + } catch (const char *anerr) { + if(err) *err = anerr; + } catch (...) { + if(err) *err = "unknow error"; + } + return JValue(); +} + +class JOut { +public: + JOut(QTextStream &out, QString indent = "") : out(out), indent(indent) {} + + void write(const JValue &obj); + void writeStr(const QString &str); + void writeMap(const JObj &map); + void writeList(const JArray &objs); +protected: + QTextStream &out; + QString indent; + int cnt{0}; +}; + +inline QString JToStr(const JValue &obj, QString indent = "") { + QString json; + QTextStream out(&json); + JOut(out, indent).write(obj); + return json; +} +inline QByteArray JToBytes(const JValue &obj, QString indent = "") { + QByteArray json; + QTextStream out(&json); + JOut(out, indent).write(obj); + return json; +} +inline QTextStream::Status JWrite(const JValue &obj, QIODevice *device, QString indent = "") { + QTextStream out(device); + JOut(out, indent).write(obj); + return out.status(); +} + +#endif // QJSON_H diff --git a/ledset/ledset.pro b/ledset/ledset.pro index ab51294..eda0657 100644 --- a/ledset/ledset.pro +++ b/ledset/ledset.pro @@ -46,7 +46,9 @@ SOURCES += \ expertwin.cpp \ fast.cpp \ globalfunc.cpp \ + gutil/cu.cpp \ gutil/qgui.cpp \ + gutil/qjson.cpp \ main.cpp \ mainwin.cpp \ moduleunit.cpp \ @@ -66,7 +68,9 @@ HEADERS += \ expertwin.h \ fast.h \ globalfunc.h \ + gutil/cu.h \ gutil/qgui.h \ + gutil/qjson.h \ mainwin.h \ moduleunit.h \ pcaprethread.h \ diff --git a/ledset/mainwin.cpp b/ledset/mainwin.cpp index 9fbd963..efcb0c0 100644 --- a/ledset/mainwin.cpp +++ b/ledset/mainwin.cpp @@ -20,6 +20,7 @@ #include #include #include +#include class ImgBtn : public QToolButton { public: @@ -170,6 +171,8 @@ MainWin::MainWin() { show(); QSettings config; + gFileHome = config.value("FileHome").toString(); + if(gFileHome.isEmpty() || ! QFileInfo(gFileHome).isDir()) gFileHome = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); auto name = config.value("net_name").toByteArray(); name = getNetDev(this, name, true); if(! name.isEmpty()) { @@ -189,6 +192,10 @@ MainWin::MainWin() { getCard(); } +MainWin::~MainWin() { + QSettings config; + config.setValue("FileHome", gFileHome); +} void MainWin::getCard() { table->setRowCount(0); diff --git a/ledset/mainwin.h b/ledset/mainwin.h index bb89531..21b52e9 100644 --- a/ledset/mainwin.h +++ b/ledset/mainwin.h @@ -8,6 +8,7 @@ class MainWin : public BaseWin { Q_OBJECT public: MainWin(); + ~MainWin(); QWidget *win{0}; QByteArray net_name; Table *table{0}; diff --git a/ledset/moduleunit.cpp b/ledset/moduleunit.cpp index 6728997..205fbb3 100644 --- a/ledset/moduleunit.cpp +++ b/ledset/moduleunit.cpp @@ -91,219 +91,93 @@ void ModuleUnit::mouseReleaseEvent(QMouseEvent *event) { } #define SnapSpace 6 void ModuleUnit::mouseMoveEvent(QMouseEvent *e){ -// if(! (e->buttons() & Qt::LeftButton)) { -// setFrmSec(e->pos()); -// return; -// } -// if(mFrmSec==Qt::NoSection || mPressRel.x()==INT_MIN) return; -// auto mousePos = e->globalPos(); -// auto dstHor = mPressRel.x() + mousePos.x(); -// auto dstVer = mPressRel.y() + mousePos.y(); -// mLRSnap = mTBSnap = 0; -// foreach(auto ele, mOtherEles) ele->clearSnap(); -// if(mFrmSec==Qt::TitleBarArea) { -// dstHor = qBound(0, dstHor, expertWin->screenWidth - width()); -// dstVer = qBound(0, dstVer, expertWin->screenHeight - height()); -// if(dstHor==0) mLRSnap = 1; -// else if(dstHor==expertWin->screenWidth - width()) mLRSnap = 2; -// if(dstVer==0) mTBSnap = 1; -// else if(dstVer==expertWin->screenHeight - height()) mTBSnap = 2; -// if(mLRSnap==0) foreach(ModuleUnit *ele, mOtherEles) {//左右 -// if(abs(dstHor - ele->x()) < SnapSpace && ele->x() <= expertWin->screenWidth - width()) { -// dstHor = ele->x(); -// mLRSnap = 1; -// ele->mLRSnap = 1; -// ele->update(); -// break; -// } -// auto eleRight = ele->x() + ele->width(); -// if(abs(dstHor - eleRight) < SnapSpace && eleRight <= expertWin->screenWidth - width()) { -// dstHor = eleRight; -// mLRSnap = 1; -// ele->mLRSnap = 2; -// ele->update(); -// break; -// } -// auto right = dstHor + width(); -// if(abs(right - ele->x()) < SnapSpace && ele->x() - width() >= 0) { -// dstHor = ele->x() - width(); -// mLRSnap = 2; -// ele->mLRSnap = 1; -// ele->update(); -// break; -// } -// if(abs(right - eleRight) < SnapSpace && eleRight - width() >= 0) { -// dstHor = eleRight - width(); -// mLRSnap = 2; -// ele->mLRSnap = 2; -// ele->update(); -// break; -// } -// } -// if(mTBSnap==0) foreach(ModuleUnit *ele, mOtherEles) {//上下 -// if(abs(dstVer-ele->y()) < SnapSpace && ele->y() <= expertWin->screenHeight - height()) { -// dstVer = ele->y(); -// mTBSnap = 1; -// ele->mTBSnap = 1; -// ele->update(); -// break; -// } -// auto eleBtm = ele->y() + ele->height(); -// if(abs(dstVer - eleBtm) < SnapSpace && eleBtm <= expertWin->screenHeight - height()) { -// dstVer = eleBtm; -// mTBSnap = 1; -// ele->mTBSnap = 2; -// ele->update(); -// break; -// } -// auto btm = dstVer + height(); -// if(abs(btm - ele->y()) < SnapSpace && ele->y() - height() >= 0) { -// dstVer = ele->y() - height(); -// mTBSnap = 2; -// ele->mTBSnap = 1; -// ele->update(); -// break; -// } -// if(abs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) { -// dstVer = eleBtm - height(); -// mTBSnap = 2; -// ele->mTBSnap = 2; -// ele->update(); -// break; -// } -// } -// move(dstHor, dstVer); -// mX = qRound(dstHor / expertWin->rate); -// mY = qRound(dstVer / expertWin->rate); -// update(); -// } else if(mFrmSec==Qt::BottomRightSection) { -// if(dstHor < m_handleLen) dstHor = m_handleLen; -// if(dstVer < m_handleLen) dstVer = m_handleLen; -// if(expertWin->screenWidth>0 && expertWin->screenHeight>0) { -// dstHor = qMin(dstHor, expertWin->screenWidth - x()); -// dstVer = qMin(dstVer, expertWin->screenHeight - y()); -// } -// resize(dstHor, dstVer); -// mW = qRound(dstHor / expertWin->rate); -// mH = qRound(dstVer / expertWin->rate); -// } else if(mFrmSec==Qt::RightSection) { -// if(dstHor < m_handleLen) dstHor = m_handleLen; -// if(expertWin->screenWidth>0 && expertWin->screenHeight>0) dstHor = qMin(dstHor, expertWin->screenWidth - x()); -// auto right = x() + dstHor; -// if(right < expertWin->screenWidth-8) foreach(ModuleUnit *ele, mOtherEles) {//左右 -// if(abs(right - ele->x()) < SnapSpace) { -// dstHor = ele->x() - x(); -// mLRSnap = 2; -// ele->mLRSnap = 1; -// ele->update(); -// break; -// } -// auto eleRight = ele->x() + ele->width(); -// if(abs(right - eleRight) < SnapSpace) { -// dstHor = eleRight - x(); -// mLRSnap = 2; -// ele->mLRSnap = 2; -// ele->update(); -// break; -// } -// } -// resize(dstHor, mPressRel.y()); -// mW = qRound(dstHor / expertWin->rate); -// } else if(mFrmSec==Qt::BottomSection) { -// if(dstVer < m_handleLen) dstVer = m_handleLen; -// if(expertWin->screenWidth>0 && expertWin->screenHeight>0) dstVer = qMin(dstVer, expertWin->screenHeight - y()); -// auto btm = y() + dstVer; -// if(btm < expertWin->screenHeight-8) foreach(ModuleUnit *ele, mOtherEles) {//上下 -// auto eleBtm = ele->y() + ele->height(); -// if(abs(btm - ele->y()) < SnapSpace) { -// dstVer = ele->y() - y(); -// mTBSnap = 2; -// ele->mTBSnap = 1; -// ele->update(); -// break; -// } -// if(abs(btm - eleBtm) < SnapSpace) { -// dstVer = eleBtm - y(); -// mTBSnap = 2; -// ele->mTBSnap = 2; -// ele->update(); -// break; -// } -// } -// resize(mPressRel.rx(), dstVer); -// mH = qRound(dstVer / expertWin->rate); -// } else { -// auto geo = geometry(); -// if(mFrmSec==Qt::LeftSection) { -// dstHor = qMin(dstHor, geo.right() - m_handleLen); -// if(dstHor < 0) dstHor = 0; -// if(dstHor > 8) foreach(ModuleUnit *ele, mOtherEles) {//左右 -// if(abs(dstHor - ele->x()) < SnapSpace) { -// dstHor = ele->x(); -// mLRSnap = 1; -// ele->mLRSnap = 1; -// ele->update(); -// break; -// } -// auto eleRight = ele->x() + ele->width(); -// if(abs(dstHor - eleRight) < SnapSpace) { -// dstHor = eleRight; -// mLRSnap = 1; -// ele->mLRSnap = 2; -// ele->update(); -// break; -// } -// } -// geo.setLeft(dstHor); -// } else if(mFrmSec==Qt::TopSection) { -// dstVer = qMin(dstVer, geo.bottom() - m_handleLen); -// if(dstVer < 0) dstVer = 0; -// if(dstVer > 8) foreach(ModuleUnit *ele, mOtherEles) {//上下 -// if(abs(dstVer - ele->y()) < SnapSpace) { -// dstVer = ele->y(); -// mTBSnap = 1; -// ele->mTBSnap = 1; -// ele->update(); -// break; -// } -// auto eleBtm = ele->y() + ele->height(); -// if(abs(dstVer - eleBtm) < SnapSpace) { -// dstVer = eleBtm; -// mTBSnap = 1; -// ele->mTBSnap = 2; -// ele->update(); -// break; -// } -// } -// geo.setTop(dstVer); -// } else if(mFrmSec==Qt::TopLeftSection) { -// dstHor = qMin(dstHor, geo.right() - m_handleLen); -// dstVer = qMin(dstVer, geo.bottom() - m_handleLen); -// if(dstHor < 0) dstHor = 0; -// if(dstVer < 0) dstVer = 0; -// geo.setLeft(dstHor); -// geo.setTop(dstVer); -// } else if(mFrmSec==Qt::TopRightSection) { -// dstHor = qMax(dstHor, geo.x() + m_handleLen); -// dstVer = qMin(dstVer, geo.bottom() - m_handleLen); -// if(dstHor > expertWin->screenWidth) dstHor = expertWin->screenWidth; -// if(dstVer < 0) dstVer = 0; -// geo.setRight(dstHor); -// geo.setTop(dstVer); -// } else if(mFrmSec==Qt::BottomLeftSection) { -// dstHor = qMin(dstHor, geo.right() - m_handleLen); -// dstVer = qMax(dstVer, geo.y() + m_handleLen); -// if(dstHor < 0) dstHor = 0; -// if(dstVer > expertWin->screenHeight) dstVer = expertWin->screenHeight; -// geo.setLeft(dstHor); -// geo.setBottom(dstVer); -// } -// setGeometry(geo); -// mX = qRound(geo.x() / expertWin->rate); -// mY = qRound(geo.y() / expertWin->rate); -// mW = qRound(geo.width() / expertWin->rate); -// mH = qRound(geo.height() / expertWin->rate); -// } + if(! (e->buttons() & Qt::LeftButton)) { + setFrmSec(e->pos()); + return; + } + if(mFrmSec==Qt::NoSection || mPressRel.x()==INT_MIN) return; + auto mousePos = e->globalPos(); + auto dstHor = mPressRel.x() + mousePos.x(); + auto dstVer = mPressRel.y() + mousePos.y(); + mLRSnap = mTBSnap = 0; + foreach(auto ele, mOtherEles) ele->clearSnap(); + if(mFrmSec==Qt::TitleBarArea) { + dstHor = qMax(0, dstHor); + dstVer = qMax(0, dstVer); + auto needw = qMax(1024, dstHor+width()); + auto needh = qMax(1024, dstVer+height()); + if(needw != expertWin->box->width() || needh != expertWin->box->height()) expertWin->box->resize(needw, needh); + if(dstHor==0) mLRSnap = 1; + if(dstVer==0) mTBSnap = 1; + if(mLRSnap==0) foreach(ModuleUnit *ele, mOtherEles) {//左右 + if(abs(dstHor - ele->x()) < SnapSpace) { + dstHor = ele->x(); + mLRSnap = 1; + ele->mLRSnap = 1; + ele->update(); + break; + } + auto eleRight = ele->x() + ele->width(); + if(abs(dstHor - eleRight) < SnapSpace) { + dstHor = eleRight; + mLRSnap = 1; + ele->mLRSnap = 2; + ele->update(); + break; + } + auto right = dstHor + width(); + if(abs(right - ele->x()) < SnapSpace && ele->x() - width() >= 0) { + dstHor = ele->x() - width(); + mLRSnap = 2; + ele->mLRSnap = 1; + ele->update(); + break; + } + if(abs(right - eleRight) < SnapSpace && eleRight - width() >= 0) { + dstHor = eleRight - width(); + mLRSnap = 2; + ele->mLRSnap = 2; + ele->update(); + break; + } + } + if(mTBSnap==0) foreach(ModuleUnit *ele, mOtherEles) {//上下 + if(abs(dstVer-ele->y()) < SnapSpace) { + dstVer = ele->y(); + mTBSnap = 1; + ele->mTBSnap = 1; + ele->update(); + break; + } + auto eleBtm = ele->y() + ele->height(); + if(abs(dstVer - eleBtm) < SnapSpace) { + dstVer = eleBtm; + mTBSnap = 1; + ele->mTBSnap = 2; + ele->update(); + break; + } + auto btm = dstVer + height(); + if(abs(btm - ele->y()) < SnapSpace && ele->y() - height() >= 0) { + dstVer = ele->y() - height(); + mTBSnap = 2; + ele->mTBSnap = 1; + ele->update(); + break; + } + if(abs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) { + dstVer = eleBtm - height(); + mTBSnap = 2; + ele->mTBSnap = 2; + ele->update(); + break; + } + } + move(dstHor, dstVer); + mX = qRound(dstHor / expertWin->rate); + mY = qRound(dstVer / expertWin->rate); + update(); + } } void ModuleUnit::leaveEvent(QEvent *) { setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); diff --git a/ledset/pcaprethread.cpp b/ledset/pcaprethread.cpp index 8428de8..1a50d7c 100644 --- a/ledset/pcaprethread.cpp +++ b/ledset/pcaprethread.cpp @@ -43,7 +43,7 @@ int PcapReThread::sendMsgNet(const byte *msg, int size, int id, qint64 timeout, void PcapReThread::run() { pcap_pkthdr *header; - const u_char *data; + const uchar *data; int cnt; while((cnt = pcap_next_ex(pcap, &header, &data)) >= 0) { if(! resps.isEmpty()) { @@ -65,7 +65,8 @@ void PcapReThread::run() { } } if(status==1) { - if(cnt == 0 || data[0]!=0x55 || data[1]!=0x55) continue; + if(cnt == 0 || header->caplen < intro.size()) continue; + for(int i=0; its.tv_sec).toString("yy-MM-dd HH:mm:ss.")+QString::number(header->ts.tv_usec)) .append(" len:").append(QString::number(header->caplen)).append("/").append(QString::number(header->len)).append("\n"); @@ -98,6 +99,7 @@ void PcapReThread::run() { msg.append("\n\n"); emit onMsg(msg); } + conti:; } emit onError(pcap_geterr(pcap)); } diff --git a/ledset/pcaprethread.h b/ledset/pcaprethread.h index f9cadc5..299b518 100644 --- a/ledset/pcaprethread.h +++ b/ledset/pcaprethread.h @@ -25,6 +25,7 @@ public: std::mutex mtx; pcap *pcap; std::atomic status{0}; + QByteArray intro{"\x55\x55"}; char fmt{0}; signals: void onCallback(FuncIntByte callback, int code, const QByteArray data); diff --git a/ledset/testwin.cpp b/ledset/testwin.cpp index 97451fc..e3ed59b 100644 --- a/ledset/testwin.cpp +++ b/ledset/testwin.cpp @@ -42,7 +42,13 @@ TestWin::TestWin(QWidget *parent) : QWidget{parent, Qt::Window} { auto hh = new HBox(vv); - hh->addWidget(new QLabel(tr("接收:"))); + hh->addLabel(tr("接收:")); + auto fdIntro = new QLineEdit("55 55"); + connect(fdIntro, &QLineEdit::editingFinished, this, [=] { + reThd->intro = QByteArray::fromHex(fdIntro->text().toLatin1()); + }); + hh->addWidget(fdIntro); + hh->addStretch(); auto fdStart = new QRadioButton(tr("开始")); diff --git a/ledset/videowin.cpp b/ledset/videowin.cpp index d5b6f32..c3468dd 100644 --- a/ledset/videowin.cpp +++ b/ledset/videowin.cpp @@ -146,20 +146,20 @@ VideoWin::VideoWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWi connect(thdRece, &VideoRecThread::onMsg, fdCanvas, [this, fdCanvas](const QByteArray chars) { if(noReview) return; auto data = (uchar *)chars.data(); - if(data[14]==0x12) { + if(data[16]==0x12) { imgLines.append(chars); - int i = (data[18]<<8 | data[19]) + 1; + int i = (data[20]<<8 | data[21]) + 1; if(i > imgHeight) imgHeight = i; - i = (data[20]<<8 | data[21]) + (data[22]<<8 | data[23]); + i = (data[22]<<8 | data[23]) + (data[24]<<8 | data[25]); if(i > imgWidth) imgWidth = i; - } else if(data[14]==0x11 && imgWidth && imgHeight) { + } else if(data[16]==0x11 && imgWidth && imgHeight) { //qDebug()<<"imgWidth"<img = img; @@ -231,6 +231,7 @@ void VideoSendThread::run() { auto queue = pcap_sendqueue_alloc(img.width()*img.height()*4); if(useOldProto) { QByteArray bytes; + bytes.append("\x55\x55"); bytes.append("\x00\x11\x22\x33\x44\x55", 6); //目的地址 bytes.append("\x00\x11\x22\x33\x44\x55", 6); //源地址 bytes.append("\x10\x5A"); //协议标识 @@ -261,6 +262,7 @@ void VideoSendThread::run() { int dataLen = lineLen - j; if(dataLen > once) dataLen = once; bytes.clear(); + bytes.append("\x55\x55"); bytes.append("\x00\x11\x22\x33\x44\x55", 6); //目的地址 bytes.append("\x00\x11\x22\x33\x44\x55", 6); //源地址 bytes.append("\x10\x5A"); //协议标识 @@ -380,7 +382,7 @@ void VideoRecThread::run() { if(status==1 || res == 0 || noReview) continue; //超时 if(header->caplen<24) continue; if(useOldProto) { - if(data[0]!=0 || data[1]!=0x11 || data[2]!=0x22 || data[3]!=0x33 || data[12]!=0x10 || data[13]!=0x5A) continue; + if(data[0]!=0x55 || data[1]!=0x55 || data[14]!=0x10 || data[15]!=0x5A) continue; emit onMsg(QByteArray((char*)data, header->caplen)); } else { if(data[0]!=0x55 || data[1]!=0x55) continue;