ledset
|
@ -24,6 +24,6 @@ build-*
|
|||
|
||||
*.autosave
|
||||
|
||||
*-old/*
|
||||
*-leyide/*
|
||||
*OK-*/*
|
||||
|
||||
*.DS_Store
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "expertboxlayoutwin.h"
|
||||
#include "moduleunit.h"
|
||||
#include "expertwin.h"
|
||||
#include "gutil/qgui.h"
|
||||
#include "gutil/qjson.h"
|
||||
#include "globalfunc.h"
|
||||
|
@ -8,16 +8,21 @@
|
|||
#include <QMessageBox>
|
||||
#include <QScrollArea>
|
||||
#include <QFileDialog>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include <QToolButton>
|
||||
#include <QPainterPath>
|
||||
|
||||
ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} {
|
||||
ExpertBoxLayoutWin::ExpertBoxLayoutWin(ExpertWin *parent) : BaseWin{parent} {
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowTitle("箱体高级布局");
|
||||
resize(1024, 720);
|
||||
setStyleSheet("QToolButton {border: none; }");
|
||||
|
||||
auto vBox = new VBox(center);
|
||||
vBox->setContentsMargins(0,0,0,0);
|
||||
vBox->setSpacing(3);
|
||||
vBox->addLayout(addBtns(new QHBoxLayout()));
|
||||
vBox->addLayout(addBtns(new QHBoxLayout));
|
||||
|
||||
auto hBox = new HBox(vBox);
|
||||
vBox = new VBox(hBox);
|
||||
|
@ -26,22 +31,53 @@ ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} {
|
|||
|
||||
auto grid = new Grid(vBox);
|
||||
auto btnAdd = new QPushButton("添加");
|
||||
connect(btnAdd, &QPushButton::clicked, this, [this] {
|
||||
connect(btnAdd, &QPushButton::clicked, this, [=] {
|
||||
auto file = QFileDialog::getOpenFileName(this, tr("打开单元板文件"), gFileHome, tr("单元板文件 (*.module)"));
|
||||
if(file.isEmpty()) return;
|
||||
gFileHome = QFileInfo(file).absolutePath();
|
||||
QFile qFile(file);
|
||||
if(! qFile.open(QFile::ReadOnly)) {
|
||||
QMessageBox::critical(this, tr("打开单元板文件失败"), file);
|
||||
return;
|
||||
}
|
||||
QString err;
|
||||
auto json = JFrom(&qFile, &err).toObj();
|
||||
auto json = JFrom(&qFile, &err);
|
||||
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);
|
||||
QDialog dlg(this);
|
||||
dlg.setWindowTitle(tr("添加模组"));
|
||||
auto vBox = new VBox(&dlg);
|
||||
auto hBox = new HBox(vBox);
|
||||
hBox->addLabel(tr("横向数量"));
|
||||
auto fdHNum = new QSpinBox;
|
||||
fdHNum->setRange(1, 999);
|
||||
fdHNum->setValue(1);
|
||||
hBox->addWidget(fdHNum);
|
||||
hBox->addStretch();
|
||||
|
||||
hBox = new HBox(vBox);
|
||||
hBox->addLabel(tr("纵向数量"));
|
||||
auto fdVNum = new QSpinBox;
|
||||
fdVNum->setRange(1, 999);
|
||||
fdVNum->setValue(1);
|
||||
hBox->addWidget(fdVNum);
|
||||
hBox->addStretch();
|
||||
vBox->addStretch();
|
||||
connect(vBox->addBtnBox(&dlg), &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
|
||||
if(dlg.exec()!=QDialog::Accepted) return;
|
||||
auto hNum = fdHNum->value();
|
||||
auto vNum = fdVNum->value();
|
||||
auto width = json["ModuleWidth"].toInt();
|
||||
auto height = json["ModuleHeight"].toInt();
|
||||
for(int vv=0; vv < vNum; ++vv) for(int hh=0; hh < hNum; ++hh) {
|
||||
auto unit = new ModuleUnit(width*hh, height*vv, width, height, json.toObj(), "", box);
|
||||
unit->show();
|
||||
}
|
||||
fdModNum->setNum(box->children().size());
|
||||
box->fitSize();
|
||||
});
|
||||
grid->addWidget(btnAdd, 0, 0);
|
||||
auto btnDel = new QPushButton("删除");
|
||||
|
@ -51,50 +87,532 @@ ExpertBoxLayoutWin::ExpertBoxLayoutWin(QWidget *parent) : BaseWin{parent} {
|
|||
auto btnRotate = new QPushButton("旋转");
|
||||
grid->addWidget(btnRotate, 1, 1);
|
||||
|
||||
vBox->addWidget(new QLabel("HUB口编辑"));
|
||||
auto btnDraw = new QPushButton("开始走线");
|
||||
btnDraw->setCheckable(true);
|
||||
connect(btnDraw, &QPushButton::clicked, this, [=](bool checked) {
|
||||
box->isDrawing = checked;
|
||||
btnDraw->setText(checked ? "结束走线" : "开始走线");
|
||||
});
|
||||
grid->addWidget(btnDraw, 2, 0);
|
||||
|
||||
auto btnClearLines = new QPushButton("清空所有走线");
|
||||
connect(btnClearLines, &QPushButton::clicked, this, [=] {
|
||||
for(auto btn : grpGrp->buttons()) if(btn->property("mods").isValid()) btn->setProperty("mods", QVariant());
|
||||
for(auto child : box->children()) ((ModuleUnit*)child)->name = QString();
|
||||
box->update();
|
||||
});
|
||||
grid->addWidget(btnClearLines, 3, 0);
|
||||
|
||||
auto btnClearLine = new QPushButton("清空当前走线");
|
||||
connect(btnClearLine, &QPushButton::clicked, this, [=] {
|
||||
for(auto btn : grpGrp->buttons()) {
|
||||
auto mods = btn->property("mods").toList();
|
||||
for(auto mod : mods) if(((ModuleUnit*) mod.value<void*>())->isSel) {
|
||||
btn->setProperty("mods", QVariant());
|
||||
for(auto mod : mods) ((ModuleUnit*) mod.value<void*>())->name = QString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
box->update();
|
||||
});
|
||||
grid->addWidget(btnClearLine, 3, 1);
|
||||
|
||||
vBox->addLabel("数据组数设置");
|
||||
auto hh = new HBox(vBox);
|
||||
|
||||
hh->addLabel("组数:");
|
||||
auto fdGNum = new QSpinBox;
|
||||
fdGNum->setRange(1, 128);
|
||||
fdGNum->setValue(16);
|
||||
hh->addWidget(fdGNum);
|
||||
|
||||
auto btnSet = new QPushButton("设置");
|
||||
hh->addWidget(btnSet);
|
||||
|
||||
grid = new Grid(vBox);
|
||||
auto btnPort = new QPushButton("端口");
|
||||
grid->addWidget(btnPort, 0, 0);
|
||||
auto btnManual = new QPushButton("手动");
|
||||
grid->addWidget(btnManual, 0, 1);
|
||||
auto btnUp = new QPushButton("上移");
|
||||
grid->addWidget(btnUp, 1, 0);
|
||||
auto btnDown = new QPushButton("下移");
|
||||
grid->addWidget(btnDown, 1, 1);
|
||||
grpGrp = new QButtonGroup(fdGNum);
|
||||
connect(btnSet, &QPushButton::clicked, this, [=] {
|
||||
auto newCnt = fdGNum->value();
|
||||
auto oldCnt = grpGrp->buttons().size();
|
||||
if(newCnt>oldCnt) for(int i=oldCnt; i<newCnt; ++i) {
|
||||
auto btn = new QPushButton("G"+QString::number(i+1));
|
||||
btn->setCheckable(true);
|
||||
btn->setMaximumWidth(40);
|
||||
btn->setFixedHeight(24);
|
||||
grpGrp->addButton(btn, i);
|
||||
grid->addWidget(btn, i / 4, i % 4);
|
||||
} else if(newCnt<oldCnt) for(int i=oldCnt-1; i>=newCnt; --i) {
|
||||
auto btn = grpGrp->button(i);
|
||||
grpGrp->removeButton(btn);
|
||||
grid->removeWidget(btn);
|
||||
delete btn;
|
||||
}
|
||||
if(grpGrp->checkedButton()==0) grpGrp->buttons()[0]->setChecked(true);
|
||||
});
|
||||
emit btnSet->clicked();
|
||||
|
||||
vBox->addWidget(new QLabel("HUB口编辑"));
|
||||
|
||||
vBox->addWidget(new QLabel("显示"));
|
||||
|
||||
grid = new Grid(vBox);
|
||||
auto fdHasPos = new QCheckBox("位置");
|
||||
fdHasPos = new QCheckBox("位置");
|
||||
fdHasPos->setChecked(true);
|
||||
grid->addWidget(fdHasPos, 0, 0);
|
||||
auto fdHasSize = new QCheckBox("大小");
|
||||
fdHasSize = new QCheckBox("大小");
|
||||
fdHasSize->setChecked(true);
|
||||
grid->addWidget(fdHasSize, 0, 1);
|
||||
auto fdHasConn = new QCheckBox("连接");
|
||||
fdHasConn = new QCheckBox("连接");
|
||||
fdHasConn->setChecked(true);
|
||||
grid->addWidget(fdHasConn, 1, 0);
|
||||
auto fdHasName = new QCheckBox("名称");
|
||||
fdHasName = new QCheckBox("名称");
|
||||
fdHasName->setChecked(true);
|
||||
grid->addWidget(fdHasName, 1, 1);
|
||||
auto fdHasOutline = new QCheckBox("轮廓");
|
||||
fdHasOutline = new QCheckBox("轮廓");
|
||||
fdHasOutline->setChecked(true);
|
||||
grid->addWidget(fdHasOutline, 2, 0);
|
||||
auto fdHasRotate = new QCheckBox("旋转");
|
||||
grid->addWidget(fdHasRotate, 2, 1);
|
||||
|
||||
vBox->addWidget(new QLabel("对齐"));
|
||||
hh = new HBox(vBox);
|
||||
|
||||
QSize imgSize(32,32);
|
||||
|
||||
auto bnAlignLeft = new QToolButton;
|
||||
bnAlignLeft->setIconSize(imgSize);
|
||||
bnAlignLeft->setIcon(QIcon(":/imgs/align-left.png"));
|
||||
connect(bnAlignLeft, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MAX;
|
||||
ModuleUnit* mod;
|
||||
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->x() < bound) bound = mod->x();
|
||||
bool needFit = false;
|
||||
if(bound != INT_MAX) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->x() != bound) {
|
||||
mod->move(bound, mod->y());
|
||||
mod->mX = qRound(mod->x() / box->rate);
|
||||
needFit = true;
|
||||
}
|
||||
if(needFit) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnAlignLeft);
|
||||
|
||||
auto bnAlignRight = new QToolButton;
|
||||
bnAlignRight->setIconSize(imgSize);
|
||||
bnAlignRight->setIcon(QIcon(":/imgs/align-right.png"));
|
||||
connect(bnAlignRight, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MIN, temp;
|
||||
ModuleUnit* mod;
|
||||
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && (temp = mod->x()+mod->width()) > bound) bound = temp;
|
||||
bool needFit = false;
|
||||
if(bound != INT_MIN) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->x() != (temp = bound-mod->width())) {
|
||||
mod->move(temp, mod->y());
|
||||
mod->mX = qRound(mod->x() / box->rate);
|
||||
needFit = true;
|
||||
}
|
||||
if(needFit) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnAlignRight);
|
||||
|
||||
auto bnAlignTop = new QToolButton;
|
||||
bnAlignTop->setIconSize(imgSize);
|
||||
bnAlignTop->setIcon(QIcon(":/imgs/align-top.png"));
|
||||
connect(bnAlignTop, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MAX;
|
||||
ModuleUnit* mod;
|
||||
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->y() < bound) bound = mod->y();
|
||||
bool needFit = false;
|
||||
if(bound != INT_MAX) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->y() != bound) {
|
||||
mod->move(mod->x(), bound);
|
||||
mod->mY = qRound(mod->y() / box->rate);
|
||||
needFit = true;
|
||||
}
|
||||
if(needFit) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnAlignTop);
|
||||
|
||||
auto bnAlignBottom = new QToolButton;
|
||||
bnAlignBottom->setIconSize(imgSize);
|
||||
bnAlignBottom->setIcon(QIcon(":/imgs/align-bottom.png"));
|
||||
connect(bnAlignBottom, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MIN, temp;
|
||||
ModuleUnit* mod;
|
||||
for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && (temp = mod->y()+mod->height()) > bound) bound = temp;
|
||||
bool needFit = false;
|
||||
if(bound != INT_MIN) for(auto child : box->children()) if((mod = (ModuleUnit*)child)->isSel && mod->y() != (temp = bound-mod->height())) {
|
||||
mod->move(mod->x(), temp);
|
||||
mod->mY = qRound(mod->y() / box->rate);
|
||||
needFit = true;
|
||||
}
|
||||
if(needFit) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnAlignBottom);
|
||||
|
||||
vBox->addWidget(new QLabel("排列"));
|
||||
hh = new HBox(vBox);
|
||||
|
||||
auto bnArrangeLeft = new QToolButton;
|
||||
bnArrangeLeft->setIconSize(imgSize);
|
||||
bnArrangeLeft->setIcon(QIcon(":/imgs/arrange-left.png"));
|
||||
connect(bnArrangeLeft, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MAX;
|
||||
ModuleUnit* tmod;
|
||||
std::vector<ModuleUnit*> mods;
|
||||
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||
auto it = mods.begin();
|
||||
while(it!=mods.end() && (*it)->y() <= tmod->y()) it++;
|
||||
mods.insert(it, tmod);
|
||||
if(tmod->x() < bound) bound = tmod->x();
|
||||
}
|
||||
tmod = 0;
|
||||
for(auto mod : mods) {
|
||||
mod->move(bound, tmod ? tmod->y()+tmod->height() : mod->y());
|
||||
tmod = mod;
|
||||
mod->mX = qRound(mod->x() / box->rate);
|
||||
mod->mY = qRound(mod->y() / box->rate);
|
||||
}
|
||||
if(! mods.empty()) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnArrangeLeft);
|
||||
|
||||
auto bnArrangeRight = new QToolButton;
|
||||
bnArrangeRight->setIconSize(imgSize);
|
||||
bnArrangeRight->setIcon(QIcon(":/imgs/arrange-right.png"));
|
||||
connect(bnArrangeRight, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MIN;
|
||||
ModuleUnit* tmod;
|
||||
std::vector<ModuleUnit*> mods;
|
||||
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||
auto it = mods.begin();
|
||||
while(it!=mods.end() && (*it)->y() <= tmod->y()) it++;
|
||||
mods.insert(it, tmod);
|
||||
if(tmod->x()+tmod->width() > bound) bound = tmod->x()+tmod->width();
|
||||
}
|
||||
tmod = 0;
|
||||
for(auto mod : mods) {
|
||||
mod->move(bound-mod->width(), tmod ? tmod->y()+tmod->height() : mod->y());
|
||||
tmod = mod;
|
||||
mod->mX = qRound(mod->x() / box->rate);
|
||||
mod->mY = qRound(mod->y() / box->rate);
|
||||
}
|
||||
if(! mods.empty()) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnArrangeRight);
|
||||
|
||||
auto bnArrangeTop = new QToolButton;
|
||||
bnArrangeTop->setIconSize(imgSize);
|
||||
bnArrangeTop->setIcon(QIcon(":/imgs/arrange-top.png"));
|
||||
connect(bnArrangeTop, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MAX;
|
||||
ModuleUnit* tmod;
|
||||
std::vector<ModuleUnit*> mods;
|
||||
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||
auto it = mods.begin();
|
||||
while(it!=mods.end() && (*it)->x() <= tmod->x()) it++;
|
||||
mods.insert(it, tmod);
|
||||
if(tmod->y() < bound) bound = tmod->y();
|
||||
}
|
||||
tmod = 0;
|
||||
for(auto mod : mods) {
|
||||
mod->move(tmod ? tmod->x()+tmod->width() : mod->x(), bound);
|
||||
tmod = mod;
|
||||
mod->mX = qRound(mod->x() / box->rate);
|
||||
mod->mY = qRound(mod->y() / box->rate);
|
||||
}
|
||||
if(! mods.empty()) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnArrangeTop);
|
||||
|
||||
auto bnArrangeBottom = new QToolButton;
|
||||
bnArrangeBottom->setIconSize(imgSize);
|
||||
bnArrangeBottom->setIcon(QIcon(":/imgs/arrange-bottom.png"));
|
||||
connect(bnArrangeBottom, &QToolButton::clicked, this, [=] {
|
||||
int bound = INT_MIN;
|
||||
ModuleUnit* tmod;
|
||||
std::vector<ModuleUnit*> mods;
|
||||
for(auto child : box->children()) if((tmod = (ModuleUnit*)child)->isSel) {
|
||||
auto it = mods.begin();
|
||||
while(it!=mods.end() && (*it)->x() <= tmod->x()) it++;
|
||||
mods.insert(it, tmod);
|
||||
if(tmod->y()+tmod->height() > bound) bound = tmod->y()+tmod->height();
|
||||
}
|
||||
tmod = 0;
|
||||
for(auto mod : mods) {
|
||||
mod->move(tmod ? tmod->x()+tmod->width() : mod->x(), bound-mod->height());
|
||||
tmod = mod;
|
||||
mod->mX = qRound(mod->x() / box->rate);
|
||||
mod->mY = qRound(mod->y() / box->rate);
|
||||
}
|
||||
if(! mods.empty()) box->fitSize();
|
||||
});
|
||||
hh->addWidget(bnArrangeBottom);
|
||||
|
||||
vBox->addStretch();
|
||||
|
||||
vBox = new VBox(hBox);
|
||||
hBox = new HBox(vBox);
|
||||
auto fdRoom = new QComboBox;
|
||||
fdRoom->setEditable(true);
|
||||
fdRoom->addItem("1600%");
|
||||
fdRoom->addItem("800%");
|
||||
fdRoom->addItem("400%");
|
||||
fdRoom->addItem("200%");
|
||||
fdRoom->addItem("100%");
|
||||
fdRoom->addItem("50%");
|
||||
fdRoom->addItem("25%");
|
||||
connect(fdRoom, &QComboBox::currentTextChanged, this, [=](const QString &text) {
|
||||
if(box==0) return;
|
||||
box->rate = text.trimmed().replace('%',"").toInt() / 100.0;
|
||||
auto childs = box->children();
|
||||
foreach(auto child, childs) {
|
||||
auto mod = (ModuleUnit*)child;
|
||||
mod->setGeometry(mod->mX*box->rate, mod->mY*box->rate, mod->mW*box->rate, mod->mH*box->rate);
|
||||
}
|
||||
box->fitSize();
|
||||
});
|
||||
hBox->addWidget(fdRoom);
|
||||
|
||||
hBox->addLabel("模组数量: ");
|
||||
fdModNum = hBox->addLabel();
|
||||
hBox->addSpacing(20);
|
||||
|
||||
hBox->addLabel("箱体大小: ");
|
||||
fdBoxSize = hBox->addLabel();
|
||||
|
||||
hBox->addStretch();
|
||||
|
||||
auto scroll = new QScrollArea;
|
||||
vBox->addWidget(scroll);
|
||||
|
||||
box = new QWidget;
|
||||
box = new BoxPanel(this);
|
||||
scroll->setWidget(box);
|
||||
box->resize(1024, 1024);
|
||||
box->setAutoFillBackground(true);
|
||||
auto pal = palette();
|
||||
pal.setColor(QPalette::Window, QColor(0x222222));
|
||||
box->setPalette(pal);
|
||||
SetCurText(fdRoom, "200%");
|
||||
|
||||
new ModuleUnit(this, "J1", 0, 0, 128, 128, box);
|
||||
connect(fdHasPos, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||
connect(fdHasSize, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||
connect(fdHasConn, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||
connect(fdHasName, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||
connect(fdHasOutline, &QCheckBox::stateChanged, box, (void(QWidget::*)())&QWidget::update);
|
||||
|
||||
auto ModuleWidth = parent->mModule["ModuleWidth"].toInt();
|
||||
auto ModuleHeight = parent->mModule["ModuleHeight"].toInt();
|
||||
new ModuleUnit(0, 0, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||
new ModuleUnit(ModuleWidth, 0, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||
new ModuleUnit(0, ModuleHeight, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||
new ModuleUnit(ModuleWidth, ModuleHeight, ModuleWidth, ModuleHeight, parent->mModule, "", box);
|
||||
fdModNum->setNum(4);
|
||||
box->fitSize();
|
||||
}
|
||||
|
||||
|
||||
void BoxPanel::mousePressEvent(QMouseEvent *event) {
|
||||
if(event->button() != Qt::LeftButton) return;
|
||||
if(isDrawing) return;
|
||||
rect = QRectF(event->localPos(), event->localPos());
|
||||
for(auto child : children()) ((ModuleUnit*) child)->isSel = false;
|
||||
update();
|
||||
}
|
||||
void BoxPanel::mouseReleaseEvent(QMouseEvent *event) {
|
||||
if(event->button() != Qt::LeftButton) return;
|
||||
if(rect.isNull()) return;
|
||||
rect = QRectF();
|
||||
update();
|
||||
}
|
||||
void BoxPanel::mouseMoveEvent(QMouseEvent *event) {
|
||||
if(! (event->buttons() & Qt::LeftButton)) return;
|
||||
if(isDrawing) {
|
||||
auto mod = (ModuleUnit*) childAt(event->pos());
|
||||
if(mod && mod->name.isEmpty()) mod->drawed();
|
||||
return;
|
||||
}
|
||||
rect.setBottomRight(event->localPos());
|
||||
for(auto child : children()) {
|
||||
auto mod = (ModuleUnit*) child;
|
||||
mod->isSel = rect.intersects(mod->geometry());
|
||||
}
|
||||
update();
|
||||
}
|
||||
void BoxPanel::paintEvent(QPaintEvent *) {
|
||||
QPainter painter(this);
|
||||
ModuleUnit *mod;
|
||||
for(auto child : children()) {
|
||||
mod = (ModuleUnit*) child;
|
||||
QPointF pos(mod->x(), mod->y());
|
||||
painter.translate(pos);
|
||||
painter.fillRect(QRectF(1, 1, mod->width()-2, mod->height()-2), mod->isSel ? QColor(0, 0xaa, 0, 0xaa) : QColor(0, 0x44, 0xff, 0x77));
|
||||
painter.setPen(QColor(mod->isSel ? 0xffffff : 0xdddddd));
|
||||
if(boxWin->fdHasOutline->isChecked()) painter.drawRect(QRectF(0.5, 0.5, mod->width()-1, mod->height()-1));
|
||||
int off = 0;
|
||||
if(boxWin->fdHasPos->isChecked()) painter.drawText(2, off+=15, QString::number(mod->mX)+", "+QString::number(mod->mY));
|
||||
if(boxWin->fdHasSize->isChecked()) painter.drawText(2, off+=15, QString::number(mod->mW)+" x "+QString::number(mod->mH));
|
||||
if(! mod->name.isEmpty()) painter.drawText(2, off+15, mod->name);
|
||||
painter.translate(-pos);
|
||||
}
|
||||
QPen pen(0xff8800);
|
||||
pen.setCapStyle(Qt::FlatCap);
|
||||
pen.setDashPattern(QVector<qreal>{4, 4});
|
||||
painter.setPen(pen);
|
||||
painter.drawRect(QRectF(boxRect.x()-0.5, boxRect.y()-0.5, boxRect.width()+1, boxRect.height()+1));
|
||||
|
||||
if(boxWin->fdHasConn->isChecked()) {
|
||||
QBrush brush(0x0088ff);
|
||||
painter.setPen(QPen(brush, 3));
|
||||
QPainterPath path;
|
||||
for(auto btn : boxWin->grpGrp->buttons()) {
|
||||
auto mods = btn->property("mods").toList();
|
||||
if(mods.isEmpty()) continue;
|
||||
QPointF last = ((ModuleUnit*) mods[0].value<void*>())->geometry().center();
|
||||
for(int mm=1; mm<mods.size(); mm++) {
|
||||
QPointF pos = ((ModuleUnit*) mods[mm].value<void*>())->geometry().center();
|
||||
painter.drawLine(last, pos);
|
||||
auto deg = 180 / 3.1415926535 * atan((pos.y()-last.y()) / (pos.x()-last.x()));
|
||||
if(pos.x()<last.x()) deg += 180;
|
||||
last = pos;
|
||||
painter.translate(pos);
|
||||
painter.rotate(deg);
|
||||
path.clear();
|
||||
path.lineTo(-30,6);
|
||||
path.lineTo(-30,-6);
|
||||
path.closeSubpath();
|
||||
painter.fillPath(path, brush);
|
||||
painter.rotate(-deg);
|
||||
painter.translate(-pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(rect.isNull()) return;
|
||||
painter.setPen(0x00aa00);
|
||||
painter.drawRect(rect);
|
||||
}
|
||||
|
||||
|
||||
ModuleUnit::ModuleUnit(int x, int y, int w, int h, const JObj &module, const QString &name, QWidget *parent) : QWidget{parent}, mX{x}, mY{y}, mW{w}, mH{h}, mModule{module}, name{name} {
|
||||
box = (BoxPanel*)parent;
|
||||
setGeometry(x*box->rate, y*box->rate, w*box->rate, h*box->rate);
|
||||
}
|
||||
|
||||
void ModuleUnit::drawed() {
|
||||
auto btn = box->boxWin->grpGrp->checkedButton();
|
||||
if(btn==0) return;
|
||||
auto mods = btn->property("mods").toList();
|
||||
mods.append(QVariant::fromValue((void*)this));
|
||||
btn->setProperty("mods", mods);
|
||||
name = "G"+QString::number(box->boxWin->grpGrp->id(btn)+1)+"-"+QString::number(mods.size());
|
||||
box->update();
|
||||
}
|
||||
void ModuleUnit::mousePressEvent(QMouseEvent *event) {
|
||||
QWidget::mousePressEvent(event);
|
||||
if(event->button() != Qt::LeftButton) return;
|
||||
event->accept();
|
||||
if(box->isDrawing) return;
|
||||
setCursor(Qt::SizeAllCursor);
|
||||
auto glbPos = event->globalPos();
|
||||
box->grpRect = geometry();
|
||||
if(isSel) {
|
||||
mOtherSels.clear();
|
||||
ModuleUnit* mod;
|
||||
for(auto child : box->children()) if(child!=this && (mod = (ModuleUnit*)child)->isSel) {
|
||||
mod->mPressRel = mod->pos() - pos();
|
||||
box->grpRect |= mod->geometry();
|
||||
mOtherSels.emplace_back(mod);
|
||||
}
|
||||
}
|
||||
mPressRel = pos() - box->grpRect.topLeft();
|
||||
box->grpRect.translate(-glbPos);
|
||||
}
|
||||
|
||||
void ModuleUnit::mouseReleaseEvent(QMouseEvent *event) {
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
if(Qt::LeftButton != event->button()) return;
|
||||
event->accept();
|
||||
if(box->isDrawing) {
|
||||
if(name.isEmpty()) drawed();
|
||||
return;
|
||||
}
|
||||
unsetCursor();
|
||||
mPressRel.setX(INT_MIN);
|
||||
if(! isSel) {
|
||||
isSel = true;
|
||||
update();
|
||||
for(auto item : box->children()) if(item!=this && ((ModuleUnit*)item)->isSel) {
|
||||
((ModuleUnit*)item)->isSel = false;
|
||||
((ModuleUnit*)item)->update();
|
||||
}
|
||||
}
|
||||
for(auto sel : mOtherSels) sel->mPressRel.setX(INT_MIN);
|
||||
mOtherSels.clear();
|
||||
}
|
||||
#define SnapSpace 6
|
||||
void ModuleUnit::mouseMoveEvent(QMouseEvent *e) {
|
||||
if(! (e->buttons() & Qt::LeftButton)) return;
|
||||
if(box->isDrawing) {
|
||||
if(name.isEmpty()) drawed();
|
||||
else {
|
||||
auto mod = (ModuleUnit*) box->childAt(x()+e->x(), y()+e->y());
|
||||
if(mod && mod!=this && mod->name.isEmpty()) mod->drawed();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(mPressRel.x()==INT_MIN) return;
|
||||
if(! isSel) {
|
||||
isSel = true;
|
||||
for(auto child : box->children()) if(child!=this && ((ModuleUnit*)child)->isSel) ((ModuleUnit*)child)->isSel = false;
|
||||
}
|
||||
auto mousePos = e->globalPos();
|
||||
auto dstHor = box->grpRect.x() + mousePos.x();
|
||||
auto dstVer = box->grpRect.y() + mousePos.y();
|
||||
dstHor = qMax(0, dstHor);
|
||||
dstVer = qMax(0, dstVer);
|
||||
// if(dstHor) for(ModuleUnit *ele : mOtherEles) {//左右
|
||||
// if(abs(dstHor - ele->x()) < SnapSpace) {
|
||||
// dstHor = ele->x();
|
||||
// break;
|
||||
// }
|
||||
// auto eleRight = ele->x() + ele->width();
|
||||
// if(abs(dstHor - eleRight) < SnapSpace) {
|
||||
// dstHor = eleRight;
|
||||
// break;
|
||||
// }
|
||||
// auto right = dstHor + width();
|
||||
// if(abs(right - ele->x()) < SnapSpace && ele->x() - width() >= 0) {
|
||||
// dstHor = ele->x() - width();
|
||||
// break;
|
||||
// }
|
||||
// if(abs(right - eleRight) < SnapSpace && eleRight - width() >= 0) {
|
||||
// dstHor = eleRight - width();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if(dstVer) for(ModuleUnit *ele : mOtherEles) {//上下
|
||||
// if(abs(dstVer-ele->y()) < SnapSpace) {
|
||||
// dstVer = ele->y();
|
||||
// break;
|
||||
// }
|
||||
// auto eleBtm = ele->y() + ele->height();
|
||||
// if(abs(dstVer - eleBtm) < SnapSpace) {
|
||||
// dstVer = eleBtm;
|
||||
// break;
|
||||
// }
|
||||
// auto btm = dstVer + height();
|
||||
// if(abs(btm - ele->y()) < SnapSpace && ele->y() - height() >= 0) {
|
||||
// dstVer = ele->y() - height();
|
||||
// break;
|
||||
// }
|
||||
// if(abs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) {
|
||||
// dstVer = eleBtm - height();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
move(mPressRel.x() + dstHor, mPressRel.y() + dstVer);
|
||||
mX = qRound(x() / box->rate);
|
||||
mY = qRound(y() / box->rate);
|
||||
for(auto sel : mOtherSels) {
|
||||
if(sel->mPressRel.x()==INT_MIN) continue;
|
||||
sel->move(sel->mPressRel.x() + x(), sel->mPressRel.y() + y());
|
||||
sel->mX = qRound(sel->x() / box->rate);
|
||||
sel->mY = qRound(sel->y() / box->rate);
|
||||
}
|
||||
box->fitSize();
|
||||
}
|
||||
|
|
|
@ -2,16 +2,69 @@
|
|||
#define EXPERTBOXLAYOUTWIN_H
|
||||
|
||||
#include "basewin.h"
|
||||
#include "gutil/qjson.h"
|
||||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QButtonGroup>
|
||||
#include <QCheckBox>
|
||||
|
||||
class ExpertWin;
|
||||
class BoxPanel;
|
||||
class ExpertBoxLayoutWin : public BaseWin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExpertBoxLayoutWin(QWidget *parent = 0);
|
||||
explicit ExpertBoxLayoutWin(ExpertWin *parent = 0);
|
||||
|
||||
QCheckBox *fdHasPos, *fdHasSize, *fdHasConn, *fdHasName, *fdHasOutline;
|
||||
QButtonGroup *grpGrp;
|
||||
BoxPanel *box{0};
|
||||
QLabel *fdModNum, *fdBoxSize;
|
||||
};
|
||||
|
||||
class ModuleUnit;
|
||||
class BoxPanel : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BoxPanel(ExpertBoxLayoutWin *boxWin) : boxWin(boxWin) {}
|
||||
|
||||
void fitSize() {
|
||||
boxRect = childrenRect();
|
||||
auto www = qMax(1000, boxRect.x()+boxRect.width()+1);
|
||||
auto hhh = qMax(1000, boxRect.y()+boxRect.height()+1);
|
||||
if(www!=width() || hhh!=height()) resize(www, hhh);
|
||||
else update();
|
||||
boxWin->fdBoxSize->setText(QString("%1 x %2").arg(boxRect.width()).arg(boxRect.height()));
|
||||
}
|
||||
|
||||
QRect boxRect, grpRect;
|
||||
ExpertBoxLayoutWin *boxWin;
|
||||
double rate{1};
|
||||
QWidget *box;
|
||||
QRectF rect;
|
||||
bool isDrawing{false};
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
};
|
||||
|
||||
class ModuleUnit : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModuleUnit(int, int, int, int, const JObj &module, const QString &name, QWidget *parent = nullptr);
|
||||
|
||||
void drawed();
|
||||
int mX, mY, mW, mH;
|
||||
JObj mModule;
|
||||
QString name;
|
||||
BoxPanel *box;
|
||||
QPoint mPressRel{INT_MIN, INT_MIN};
|
||||
bool isSel{false};
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
void mouseMoveEvent(QMouseEvent *) override;
|
||||
|
||||
std::vector<ModuleUnit *> mOtherSels;
|
||||
};
|
||||
|
||||
#endif // EXPERTBOXLAYOUTWIN_H
|
||||
|
|
|
@ -709,7 +709,8 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e
|
|||
vBox->addLayout(hhh);
|
||||
|
||||
table = new Table;
|
||||
table->setNoEdit()->setSelectionMode(QTableWidget::SingleSelection);
|
||||
table->setEditTriggers(Table::NoEditTriggers);
|
||||
table->setSelectionMode(QTableWidget::SingleSelection);
|
||||
table->setColWidth(35)->setRowHeight(24, QHeaderView::Fixed);
|
||||
table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
|
||||
table->verticalHeader()->setMinimumWidth(35);
|
||||
|
@ -750,7 +751,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e
|
|||
vBox->addWidget(table);
|
||||
|
||||
tableRow = new Table(2, 0);
|
||||
tableRow->setNoEdit();
|
||||
tableRow->setEditTriggers(Table::NoEditTriggers);
|
||||
tableRow->setSelectionMode(QTableWidget::NoSelection);
|
||||
tableRow->setColWidth(35);
|
||||
tableRow->setRowHeight(24);
|
||||
|
|
|
@ -134,6 +134,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
|||
qFile.close();
|
||||
auto json = JFrom(data).toObj();
|
||||
if(! json.empty()) {
|
||||
cfg = json;
|
||||
mBox = json["ModuleConnectionInfo"].toObj();
|
||||
mModule = mBox["ModuleInfo"].toObj();
|
||||
}
|
||||
|
@ -247,7 +248,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
|||
fdNormal->setChecked(true);
|
||||
vvv->addWidget(fdNormal);
|
||||
|
||||
auto fdAdvacned = new QRadioButton("高级设计");
|
||||
fdAdvacned = new QRadioButton("高级设计");
|
||||
vvv->addWidget(fdAdvacned);
|
||||
|
||||
hh->addSpacing(20);
|
||||
|
@ -308,7 +309,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
|||
fdSectorCount->addItem(tr("六开"), 6);
|
||||
fdSectorCount->addItem(tr("七开"), 7);
|
||||
fdSectorCount->addItem(tr("八开"), 8);
|
||||
setCurrentData(fdSectorCount, mBox["SectorCount"].toInt());
|
||||
SetCurData(fdSectorCount, mBox["SectorCount"].toInt());
|
||||
vvv->addWidget(fdSectorCount);
|
||||
|
||||
fdDirection = new QComboBox();
|
||||
|
@ -344,12 +345,15 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
|||
connect(btn, &QPushButton::clicked, this, [=] {
|
||||
auto win = new ExpertBoxLayoutWin(this);
|
||||
win->show();
|
||||
win->raise();
|
||||
win->activateWindow();
|
||||
});
|
||||
vvv->addWidget(btn);
|
||||
}
|
||||
connect(fdNormal, &QRadioButton::toggled, this, [=](bool checked) {
|
||||
stack->setCurrentWidget(checked ? normalPanel : advacnedPanel);
|
||||
});
|
||||
if(cfg["is_irr"].toBool()) fdAdvacned->setChecked(true);
|
||||
}
|
||||
|
||||
gBox = new QGroupBox(tr("效果测试"));
|
||||
|
@ -589,7 +593,7 @@ QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; backgrou
|
|||
}
|
||||
void ExpertWin::closeEvent(QCloseEvent *event) {
|
||||
BaseWin::closeEvent(event);
|
||||
QFile qFile(QApplication::applicationDirPath()+"/temp.screen");
|
||||
QFile qFile("temp.screen");
|
||||
if(! qFile.open(QFile::WriteOnly)) return;
|
||||
qFile.write(savedData());
|
||||
qFile.close();
|
||||
|
@ -602,7 +606,10 @@ QByteArray ExpertWin::savedData() {
|
|||
mBox.insert("ModuleCol", (fdCardHeight->value() + ModuleHeight - 1) / ModuleHeight);
|
||||
mBox.insert("ModuleDirection", fdDirection->currentIndex());
|
||||
mBox.insert("SectorCount", fdSectorCount->currentData().toInt());
|
||||
JObj obj{{"ModuleConnectionInfo", mBox}};
|
||||
JObj obj{
|
||||
{"ModuleConnectionInfo", mBox},
|
||||
{"is_irr", fdAdvacned->isChecked()},
|
||||
};
|
||||
return JToBytes(obj, " ");
|
||||
}
|
||||
void ExpertWin::addMapData(QByteArray &data) {
|
||||
|
@ -716,80 +723,3 @@ void ExpertWin::addMapData(QByteArray &data) {
|
|||
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("\xB1\x04\0\0", 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);
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QJsonObject>
|
||||
#include <QRadioButton>
|
||||
|
||||
class ExpertWin : public BaseWin {
|
||||
Q_OBJECT
|
||||
|
@ -21,6 +21,13 @@ public:
|
|||
|
||||
QLabel *fdModuleWidth, *fdModuleHeight, *fdGroupNum, *fdScanNum;
|
||||
QLabel *fdChipType, *fdDecodeMode;
|
||||
JObj cfg;
|
||||
JObj mBox {
|
||||
{"ModuleRow", 1},
|
||||
{"ModuleCol", 1},
|
||||
{"Direction", 1},
|
||||
{"SectorCount", 1}
|
||||
};
|
||||
JObj mModule {
|
||||
{"ModuleWidth", 32},
|
||||
{"ModuleHeight", 16},
|
||||
|
@ -30,15 +37,10 @@ public:
|
|||
{"DecodeMode", "138译码"},
|
||||
{"GroupMode", "三线并行"}
|
||||
};
|
||||
JObj mBox {
|
||||
{"ModuleRow", 1},
|
||||
{"ModuleCol", 1},
|
||||
{"Direction", 1},
|
||||
{"SectorCount", 1}
|
||||
};
|
||||
|
||||
QSpinBox *fdCardWidth, *fdCardHeight;
|
||||
QComboBox *fdDirection, *fdSectorCount;
|
||||
QRadioButton *fdAdvacned;
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *) override;
|
||||
};
|
||||
|
|
|
@ -73,6 +73,10 @@ public:
|
|||
Vector(std::initializer_list<V> _Ilist) {
|
||||
this->ptr = new SharedData<std::vector<V>>{_Ilist, 1};
|
||||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return this->ptr ? this->ptr->data.empty() : true;
|
||||
}
|
||||
uint64_t size() const noexcept {
|
||||
return this->ptr ? this->ptr->data.size() : 0;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ Table::Table(std::initializer_list<ColAttr> colAttrs, int rows, QWidget *parent)
|
|||
noStretch = false;
|
||||
} else horizontalHeader()->setSectionResizeMode(i, (QHeaderView::ResizeMode)it->resizeMode);
|
||||
}
|
||||
mFieldMap.insert(it->field, i++);
|
||||
mFieldMap.emplace(it->field, i++);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,14 @@ void Table::resizeSec() {
|
|||
int colCnt = columnCount(), remainWidth = header->width(), stretchWidth = 0, secWidth;
|
||||
QTableWidgetItem *item;
|
||||
for(int cc=0; cc<colCnt; cc++) if((item = horizontalHeaderItem(cc))) {
|
||||
if((secWidth = item->data(0x99).toInt()) > 0) stretchWidth += secWidth;
|
||||
else remainWidth -= header->sectionSize(cc);
|
||||
}
|
||||
if((secWidth = item->data(0x99).toInt()) > 0) stretchWidth += secWidth;
|
||||
else remainWidth -= header->sectionSize(cc);
|
||||
}
|
||||
if(remainWidth<=0 || stretchWidth==0) return;
|
||||
for(int cc=0; cc<colCnt; cc++) if((item = horizontalHeaderItem(cc)) && (secWidth = item->data(0x99).toInt()) > 0) header->resizeSection(cc, secWidth * remainWidth / stretchWidth);
|
||||
}
|
||||
|
||||
void Table::updateGeometries() {
|
||||
QTableWidget::updateGeometries();
|
||||
emit updGeos();
|
||||
}
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#define QGUI_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QStackedLayout>
|
||||
#include <QSplitter>
|
||||
#include <QListWidget>
|
||||
#include <QTableWidget>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QSplitter>
|
||||
#include <QStackedLayout>
|
||||
#include <QTableWidget>
|
||||
#include <QTextEdit>
|
||||
|
||||
#define MainMust \
|
||||
|
@ -22,11 +24,28 @@
|
|||
|
||||
extern const int AlignRight;
|
||||
|
||||
inline int setCurrentData(QComboBox *combo, const QVariant &data) {
|
||||
inline QWidget *parentWgt(QObject *obj) {
|
||||
while(obj && ! obj->isWidgetType()) obj = obj->parent();
|
||||
return (QWidget*) obj;
|
||||
}
|
||||
inline QWidget *parentWin(QObject *obj) {
|
||||
while(obj) {
|
||||
if(obj->isWidgetType()) return ((QWidget*) obj)->window();
|
||||
obj = obj->parent();
|
||||
}
|
||||
return (QWidget*) obj;
|
||||
}
|
||||
|
||||
inline int SetCurData(QComboBox *combo, const QVariant &data) {
|
||||
auto idx = combo->findData(data);
|
||||
if(idx>-1) combo->setCurrentIndex(idx);
|
||||
return idx;
|
||||
}
|
||||
inline int SetCurText(QComboBox *combo, const QString &text) {
|
||||
auto idx = combo->findText(text);
|
||||
if(idx>-1) combo->setCurrentIndex(idx);
|
||||
return idx;
|
||||
}
|
||||
inline void gFont(QWidget *wgt, int size, bool bold = false, bool italic = false) {
|
||||
auto ft = wgt->font();
|
||||
ft.setPixelSize(size);
|
||||
|
@ -70,11 +89,22 @@ public:
|
|||
splitter->addWidget(parentWidget());
|
||||
setContentsMargins(0,0,0,0);
|
||||
};
|
||||
inline QLabel *addLabel() {
|
||||
auto lb = new QLabel;
|
||||
addWidget(lb);
|
||||
return lb;
|
||||
}
|
||||
inline QLabel *addLabel(const QString &text) {
|
||||
auto lb = new QLabel(text);
|
||||
addWidget(lb);
|
||||
return lb;
|
||||
}
|
||||
inline QDialogButtonBox *addBtnBox(QDialog *dlg = 0) {
|
||||
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
if(dlg) connect(btnBox, &QDialogButtonBox::rejected, dlg, &QDialog::reject);
|
||||
addWidget(btnBox);
|
||||
return btnBox;
|
||||
}
|
||||
};
|
||||
class HBox : public QBoxLayout {
|
||||
public:
|
||||
|
@ -90,6 +120,11 @@ public:
|
|||
splitter->addWidget(parentWidget());
|
||||
setContentsMargins(0,0,0,0);
|
||||
};
|
||||
inline QLabel *addLabel() {
|
||||
auto lb = new QLabel;
|
||||
addWidget(lb);
|
||||
return lb;
|
||||
}
|
||||
inline QLabel *addLabel(const QString &text) {
|
||||
auto lb = new QLabel(text);
|
||||
addWidget(lb);
|
||||
|
@ -143,10 +178,6 @@ public:
|
|||
Table() {}
|
||||
Table(std::initializer_list<ColAttr> colAttrs, int rows = 0, QWidget *parent = 0);
|
||||
|
||||
inline auto setNoEdit() {
|
||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
return this;
|
||||
}
|
||||
inline auto setDefs() {
|
||||
setSelectionBehavior(QTableWidget::SelectRows);
|
||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
|
@ -279,13 +310,15 @@ public:
|
|||
setCellWidget(row, col, widget);
|
||||
}
|
||||
|
||||
std::map<QString, int> mFieldMap;
|
||||
public Q_SLOTS:
|
||||
inline void clearRows() {setRowCount(0);}
|
||||
|
||||
signals:
|
||||
void updGeos();
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void updateGeometries() override;
|
||||
void resizeSec();
|
||||
QMap<QString,int> mFieldMap;
|
||||
bool noStretch{true};
|
||||
};
|
||||
|
||||
|
|
|
@ -94,13 +94,23 @@ public:
|
|||
if(type==Array) return *(JArray*) data;
|
||||
return JArray();
|
||||
}
|
||||
const JValue operator[](const QString &key) const {
|
||||
return type==Obj ? (*(JObj*) data)[key] : JValue();
|
||||
}
|
||||
const JValue operator[](int i) const {
|
||||
return type==Array ? (*(JArray*) data)[i] : JValue();
|
||||
}
|
||||
private:
|
||||
JValue(const void *) = delete; // avoid implicit conversions from char * to bool
|
||||
};
|
||||
|
||||
class JParser {
|
||||
public:
|
||||
JParser(QTextStream &in) : in(in) {}
|
||||
JParser(QTextStream &in) : in(in) {
|
||||
#if(QT_VERSION_MAJOR < 6)
|
||||
in.setCodec("UTF-8");
|
||||
#endif
|
||||
}
|
||||
|
||||
inline JValue read() {
|
||||
skipSpace();
|
||||
|
@ -144,7 +154,11 @@ inline JValue JFrom(QIODevice *device, QString *err = 0) {
|
|||
|
||||
class JOut {
|
||||
public:
|
||||
JOut(QTextStream &out, QString indent = "") : out(out), indent(indent) {}
|
||||
JOut(QTextStream &out, QString indent = "") : out(out), indent(indent) {
|
||||
#if(QT_VERSION_MAJOR < 6)
|
||||
out.setCodec("UTF-8");
|
||||
#endif
|
||||
}
|
||||
|
||||
void write(const JValue &obj);
|
||||
void writeStr(const QString &str);
|
||||
|
|
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 406 B |
After Width: | Height: | Size: 403 B |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 537 B |
|
@ -10,6 +10,7 @@ CONFIG += embed_translations
|
|||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
TARGET = $$quote(LedSet Express)
|
||||
DEFINES += __VER__=\\\"0.0.1\\\"
|
||||
|
||||
msvc {
|
||||
contains(QT_ARCH, i386) {
|
||||
|
@ -29,6 +30,22 @@ win32 {
|
|||
RC_ICONS = 128.ico
|
||||
}
|
||||
|
||||
|
||||
copydir.files += translations
|
||||
|
||||
win32 {
|
||||
EXE_SUFFIX = .exe
|
||||
copydir.path = $$OUT_PWD
|
||||
CONFIG += file_copies
|
||||
COPIES += copydir
|
||||
}
|
||||
osx {
|
||||
DIR_SUFFIX = -mac
|
||||
copydir.path = Contents/MacOS
|
||||
QMAKE_BUNDLE_DATA += copydir
|
||||
}
|
||||
|
||||
|
||||
INCLUDEPATH += $$PWD/npcap-sdk-1.13/Include
|
||||
LIBS += -L$$PWD/npcap-sdk-1.13/Lib/\
|
||||
-lwpcap\
|
||||
|
@ -51,7 +68,6 @@ SOURCES += \
|
|||
gutil/qjson.cpp \
|
||||
main.cpp \
|
||||
mainwin.cpp \
|
||||
moduleunit.cpp \
|
||||
pcaprethread.cpp \
|
||||
screenunit.cpp \
|
||||
testwin.cpp \
|
||||
|
@ -72,7 +88,6 @@ HEADERS += \
|
|||
gutil/qgui.h \
|
||||
gutil/qjson.h \
|
||||
mainwin.h \
|
||||
moduleunit.h \
|
||||
pcaprethread.h \
|
||||
screenunit.h \
|
||||
testwin.h \
|
||||
|
@ -80,14 +95,7 @@ HEADERS += \
|
|||
waitingdlg.h
|
||||
|
||||
TRANSLATIONS += \
|
||||
translations/app_en.ts
|
||||
|
||||
EXTRA_TRANSLATIONS += \
|
||||
translations/qt_zh_CN.ts \
|
||||
translations/qt_zh_TW.ts \
|
||||
translations/qt_ja.ts \
|
||||
translations/qt_en.ts
|
||||
|
||||
ts/app_en.ts
|
||||
|
||||
|
||||
# Default rules for deployment.
|
||||
|
|
|
@ -1,31 +1,29 @@
|
|||
#include "mainwin.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QLocale>
|
||||
#include <QTranslator>
|
||||
#include <QIcon>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QStyleFactory>
|
||||
#include <QDebug>
|
||||
#include <QTranslator>
|
||||
|
||||
#ifdef _MSC_VER //MSVC编译器
|
||||
#define _WINSOCKAPI_
|
||||
#include <windows.h>
|
||||
#include <DbgHelp.h>
|
||||
LONG WINAPI handleException(_EXCEPTION_POINTERS *excep) {
|
||||
QString errCode = QString::number(excep->ExceptionRecord->ExceptionCode, 16);
|
||||
QString errAddr = QString::number((uint)excep->ExceptionRecord->ExceptionAddress, 16);
|
||||
HANDLE hDumpFile = CreateFile(L"c:/ledset-crash.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(hDumpFile == INVALID_HANDLE_VALUE) return EXCEPTION_CONTINUE_SEARCH; //未处理异常, 让 windows 弹出错误框并结束 (Qt会卡死一段时间)
|
||||
auto errCode = QString::number(excep->ExceptionRecord->ExceptionCode, 16);
|
||||
auto errAddr = QString::number((uint)excep->ExceptionRecord->ExceptionAddress, 16);
|
||||
auto hDumpFile = CreateFile(L"ledset-crash.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(hDumpFile == INVALID_HANDLE_VALUE) {
|
||||
qCritical()<<"CreateFile ledset-crash.dmp Failed! ExceptionCode"<<errCode<<"ExceptionAddress"<<errAddr;
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
MINIDUMP_EXCEPTION_INFORMATION dumpInfo{GetCurrentThreadId(), excep, TRUE};
|
||||
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);//写入Dump文件内容
|
||||
CloseHandle(hDumpFile);
|
||||
QMessageBox::critical(nullptr, "程序出错", "<b>程序出错!</b> (code: "+errCode+". addr: "+errAddr+")<br/>请将C盘下的 ledok-crash.dmp 文件发送到 gangphon@qq.com 邮箱, 研发人员会尽快处理.");
|
||||
QMessageBox::critical(0, "程序出错 (V" __VER__" - " __DATE__", Code: "+errCode+")", "<b>程序出错!</b><br/>请将安装目录下的 ledok-crash.dmp 文件发送到 gangphon@qq.com 邮箱, 研发人员会尽快处理.");
|
||||
return EXCEPTION_EXECUTE_HANDLER; //已处理异常, 让 windows 正常结束
|
||||
// EXCEPTION_CONTINUE_EXECUTION 已修复错误, 让 windows 从异常发生处继续执行
|
||||
}
|
||||
#endif
|
||||
void test();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
|
@ -35,7 +33,7 @@ int main(int argc, char *argv[]) {
|
|||
QApplication::setOrganizationDomain("ledok.cn");
|
||||
QApplication::setApplicationName("LedSet Express");
|
||||
QApplication a(argc, argv);
|
||||
a.setStyle(QStyleFactory::create("Fusion"));
|
||||
QApplication::setStyle("Fusion");
|
||||
a.setWindowIcon(QIcon(":/128.ico"));
|
||||
a.setStyleSheet(R"rrr(
|
||||
QLineEdit {border: 1px solid #777; border-radius: 2px; padding: 2px;}
|
||||
|
@ -49,6 +47,7 @@ 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);}
|
||||
|
||||
QPushButton:checked {border: 2px solid #0a0; border-radius: 3px; padding-top: 2px; padding-bottom: 2px; }
|
||||
QPushButton:disabled {color: #777;}
|
||||
|
||||
QPushButton[ss="min"]{padding: 0; width: 30px; height: 25px; }
|
||||
|
@ -59,8 +58,6 @@ QPushButton[ss="blue"] {background: #059;}
|
|||
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;}
|
||||
)rrr");
|
||||
/*
|
||||
*/
|
||||
QFont font;
|
||||
font.setFamilies(QStringList{"Arial","Microsoft YaHei UI"});
|
||||
a.setFont(font);
|
||||
|
@ -84,18 +81,13 @@ QGroupBox::title {color: #fff; subcontrol-origin: margin; left: 0.5em;}
|
|||
a.setPalette(plt);
|
||||
|
||||
QTranslator translator;
|
||||
if(translator.load(QLocale::system(), "app", "_", ":/i18n")) a.installTranslator(&translator);
|
||||
if(translator.load(QLocale(), "app", "_", ":/i18n")) a.installTranslator(&translator);
|
||||
QTranslator qtTrans;
|
||||
if(qtTrans.load(QLocale::system(), "qt", "_", ":/i18n")) a.installTranslator(&qtTrans);
|
||||
if(qtTrans.load(QLocale(), "qt", "_", "translations")) a.installTranslator(&qtTrans);
|
||||
|
||||
MainWin w;
|
||||
#ifdef _MSC_VER
|
||||
SetUnhandledExceptionFilter(handleException);
|
||||
#endif
|
||||
//test();
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
void test() {
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "mainwin.h"
|
||||
#include "gutil/qjson.h"
|
||||
#include "pcaprethread.h"
|
||||
#include "fast.h"
|
||||
#include "expertwin.h"
|
||||
|
@ -21,6 +22,8 @@
|
|||
#include <QApplication>
|
||||
#include <QtEndian>
|
||||
#include <QStandardPaths>
|
||||
#include <QNetworkDatagram>
|
||||
#include <QNetworkInterface>
|
||||
|
||||
class ImgBtn : public QToolButton {
|
||||
public:
|
||||
|
@ -132,9 +135,9 @@ MainWin::MainWin() {
|
|||
table->setDefs();
|
||||
vBox->addWidget(table);
|
||||
|
||||
auto hstatus = new QHBoxLayout;
|
||||
hstatus->addWidget(new QLabel(tr("编译日期")+": "+__DATE__));
|
||||
hstatus->addStretch();
|
||||
auto hBox = new HBox(vBox);
|
||||
hBox->addLabel("V" __VER__" - " __DATE__);
|
||||
hBox->addStretch();
|
||||
|
||||
auto btnNetSelect = new QPushButton("通讯选择");
|
||||
connect(btnNetSelect, &QPushButton::clicked, this, [this] {
|
||||
|
@ -160,13 +163,11 @@ MainWin::MainWin() {
|
|||
reThd->start();
|
||||
QSettings().setValue("net_name", net_name = name);
|
||||
});
|
||||
hstatus->addWidget(btnNetSelect);
|
||||
hBox->addWidget(btnNetSelect);
|
||||
|
||||
auto btnRefresh = new QPushButton(tr("刷新"));
|
||||
connect(btnRefresh, &QPushButton::clicked, this, &MainWin::getCard);
|
||||
hstatus->addWidget(btnRefresh);
|
||||
|
||||
vBox->addLayout(hstatus);
|
||||
hBox->addWidget(btnRefresh);
|
||||
|
||||
show();
|
||||
|
||||
|
@ -189,10 +190,53 @@ MainWin::MainWin() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] {
|
||||
while(mUdpSocket.hasPendingDatagrams()) {
|
||||
auto gram = mUdpSocket.receiveDatagram();
|
||||
auto data = gram.data();
|
||||
if(data.isEmpty()) continue;
|
||||
auto senderAddress = gram.senderAddress();
|
||||
bool ok = true;
|
||||
if(senderAddress.protocol()==QUdpSocket::IPv6Protocol) senderAddress.setAddress(senderAddress.toIPv4Address(&ok));
|
||||
auto addr = ok ? senderAddress.toString() : "";
|
||||
int cnt = table->rowCount();
|
||||
if(data.startsWith("{\"")) {
|
||||
QString error;
|
||||
auto json = JFrom(gram.data(), &error);
|
||||
if(! error.isEmpty()) {
|
||||
qDebug()<<"Json Error: "+error;
|
||||
continue;
|
||||
}
|
||||
auto cardId = json["cardId"].toStr();
|
||||
for(int rr=0; rr<cnt; rr++) if(table->text(rr, "name")==cardId) {
|
||||
table->setText(rr, "link", addr);
|
||||
goto end;
|
||||
}
|
||||
table->setRowCount(cnt+1);
|
||||
//table->setText(cnt, "type", tr("虚拟设备"));
|
||||
table->setText(cnt, "name", cardId);
|
||||
table->setText(cnt, "link", addr);
|
||||
//table->setText(cnt, "vcsNum", QString::number(*(quint32_be*)(data.data()+headMap.body)));
|
||||
//table->setText(cnt, "netPorts", "P:"+QString::number(virtualVCM));
|
||||
//table->setText(cnt, "info", "备注:可直接配屏,无需发送卡");
|
||||
} else {
|
||||
auto bytes = gram.data();
|
||||
auto packet = (UDPPacket *)bytes.data();
|
||||
for(int rr=0; rr<cnt; rr++) if(table->text(rr, "name")==packet->serialCode) {
|
||||
table->setText(rr, "link", addr);
|
||||
goto end;
|
||||
}
|
||||
table->setRowCount(cnt+1);
|
||||
table->setText(cnt, "name", packet->serialCode);
|
||||
table->setText(cnt, "link", addr);
|
||||
}
|
||||
end:;
|
||||
}
|
||||
});
|
||||
getCard();
|
||||
}
|
||||
MainWin::~MainWin() {
|
||||
mUdpSocket.close();
|
||||
QSettings config;
|
||||
config.setValue("FileHome", gFileHome);
|
||||
}
|
||||
|
@ -212,7 +256,28 @@ void MainWin::getCard() {
|
|||
table->setText(rr, "netPorts", "P:"+QString::number(virtualVCM));
|
||||
table->setText(rr, "info", "备注:可直接配屏,无需发送卡");
|
||||
});
|
||||
if(res) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend)));
|
||||
if(res) {
|
||||
QString err = pcap_geterr(pcapSend);
|
||||
if(! err.endsWith("(2150891551)")) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend)));
|
||||
}
|
||||
auto data = JToBytes(JObj{{"action", "getInfo"}});
|
||||
uchar ccc[]{0x7E, 0x7E, 0x7E, 0x90, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x21,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x9F};
|
||||
if(mUdpSocket.writeDatagram(data, QHostAddress("255.255.255.255"), 22222) != data.length()) qDebug() << "getInfo write to 255.255.255.255 failed";
|
||||
if(mUdpSocket.writeDatagram((char *)ccc, sizeof(ccc), QHostAddress("255.255.255.255"), 31296) != sizeof(ccc)) qDebug() << "getInfo write to 255.255.255.255 failed";
|
||||
auto networkinterfaces = QNetworkInterface::allInterfaces();
|
||||
foreach(auto face, networkinterfaces) {
|
||||
auto flags = face.flags();
|
||||
bool can = (flags & QNetworkInterface::IsRunning) && (flags & QNetworkInterface::CanBroadcast) && ! (flags & QNetworkInterface::IsLoopBack);
|
||||
if(! can) continue;
|
||||
auto addrEntries = face.addressEntries();
|
||||
foreach(QNetworkAddressEntry addrEntry, addrEntries) {
|
||||
auto ip = addrEntry.ip();
|
||||
if(ip.protocol()!=QAbstractSocket::IPv4Protocol) continue;
|
||||
auto broadcast = addrEntry.broadcast();
|
||||
if(mUdpSocket.writeDatagram(data, broadcast, 22222) != data.length()) qDebug() << "getInfo write failed." << ip.toString() << "->" << broadcast.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "basewin.h"
|
||||
#include "gutil/qgui.h"
|
||||
#include <QUdpSocket>
|
||||
|
||||
class MainWin : public BaseWin {
|
||||
Q_OBJECT
|
||||
|
@ -12,9 +13,17 @@ public:
|
|||
QWidget *win{0};
|
||||
QByteArray net_name;
|
||||
Table *table{0};
|
||||
QUdpSocket mUdpSocket;
|
||||
|
||||
public slots:
|
||||
void getCard();
|
||||
};
|
||||
|
||||
struct UDPPacket {
|
||||
unsigned char SyncHead[3];
|
||||
unsigned char ucCommType;
|
||||
char serialCode[20];
|
||||
unsigned int iLength;
|
||||
};
|
||||
|
||||
#endif // MAINWIN_H
|
||||
|
|
|
@ -1,198 +0,0 @@
|
|||
#include "moduleunit.h"
|
||||
#include "expertboxlayoutwin.h"
|
||||
#include <QDirIterator>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QSpinBox>
|
||||
#include <QMouseEvent>
|
||||
|
||||
ModuleUnit::ModuleUnit(ExpertBoxLayoutWin *expertWin, const QString &name, int x, int y, int w, int h, QWidget *parent) : QWidget{parent}, expertWin{expertWin}, name{name}, mX{x}, mY{y}, mW{w}, mH{h} {
|
||||
setGeometry(x, y, w, h);
|
||||
setMouseTracking(true);
|
||||
auto font = this->font();
|
||||
font.setPixelSize(12);
|
||||
setFont(font);
|
||||
|
||||
mSidePen.setCapStyle(Qt::FlatCap);
|
||||
mSidePen.setDashPattern(QVector<qreal>{2,2});
|
||||
}
|
||||
|
||||
void ModuleUnit::paintEvent(QPaintEvent *) {
|
||||
QPainter painter(this);
|
||||
painter.setPen(mSidePen);
|
||||
painter.drawRect(QRectF(0.5, 0.5, width()-1, height()-1));
|
||||
painter.drawText(2, 16, name);
|
||||
painter.drawText(2, 32, "位置: "+QString::number(mX)+", "+QString::number(mY));
|
||||
painter.drawText(2, 48, "大小: "+QString::number(mW)+" x "+QString::number(mH));
|
||||
//磁条吸附时两化吸附的边
|
||||
static QPen snapPen(QColor(0x00ff00), 2);
|
||||
painter.setPen(snapPen);
|
||||
if(mLRSnap==1) painter.drawLine(QPointF(1, 0), QPointF(1, height()));
|
||||
else if(mLRSnap==2) painter.drawLine(QPointF(width()-1, 0), QPointF(width()-1, height()));
|
||||
if(mTBSnap==1) painter.drawLine(QPointF(0, 1), QPointF(width(), 1));
|
||||
else if(mTBSnap==2) painter.drawLine(QPointF(0, height()-1), QPointF(width(), height()-1));
|
||||
}
|
||||
|
||||
void ModuleUnit::setFrmSec(const QPoint &pos) {
|
||||
if(isMaximized()) return;
|
||||
if(pos.y()<8) {
|
||||
if(pos.x()<16) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor);
|
||||
else if(pos.x()<width()-16) setFrmSecIfNeed(Qt::TopSection, Qt::SizeVerCursor);
|
||||
else setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor);
|
||||
} else if(pos.y()>=height()-8) {
|
||||
if(pos.x()<16) setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor);
|
||||
else if(pos.x()<width()-16) setFrmSecIfNeed(Qt::BottomSection, Qt::SizeVerCursor);
|
||||
else setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor);
|
||||
} else if(pos.x()<8) {
|
||||
if(pos.y()<16) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor);
|
||||
else if(pos.y()<height()-16) setFrmSecIfNeed(Qt::LeftSection, Qt::SizeHorCursor);
|
||||
else setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor);
|
||||
} else if(pos.x()>=width()-8) {
|
||||
if(pos.y()<16) setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor);
|
||||
else if(pos.y()<height()-16) setFrmSecIfNeed(Qt::RightSection, Qt::SizeHorCursor);
|
||||
else setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor);
|
||||
} else setFrmSecIfNeed(Qt::TitleBarArea, Qt::SizeAllCursor);
|
||||
}
|
||||
void ModuleUnit::mousePressEvent(QMouseEvent *e) {
|
||||
QWidget::mousePressEvent(e);
|
||||
if(e->button() != Qt::LeftButton) return;
|
||||
setFrmSec(e->pos());
|
||||
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = mPressRel = pos() - e->globalPos();
|
||||
else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(width() - e->globalX(), height() - e->globalY());
|
||||
else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(width() - e->globalX(), height() );
|
||||
else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(width() , height() - e->globalY());
|
||||
else if(mFrmSec==Qt::TopRightSection ) mPressRel = geometry().topRight() - e->globalPos();
|
||||
else if(mFrmSec==Qt::BottomLeftSection ) mPressRel = geometry().bottomLeft() - e->globalPos();
|
||||
else if(mFrmSec==Qt::NoSection) mPressRel.setX(INT_MIN);
|
||||
if(mPressRel.x()!=INT_MIN) {
|
||||
mOtherEles.clear();
|
||||
auto parent = this->parentWidget();
|
||||
if(0 == parent) return;
|
||||
auto items = parent->children();
|
||||
foreach(auto item, items) {
|
||||
if(item==this) continue;
|
||||
auto ele = static_cast<ModuleUnit*>(item);
|
||||
mOtherEles.append(ele);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleUnit::mouseReleaseEvent(QMouseEvent *event) {
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
if(Qt::LeftButton == event->button()) {
|
||||
mPressRel.setX(INT_MIN);
|
||||
clearSnap();
|
||||
foreach(auto ele, mOtherEles) ele->clearSnap();
|
||||
}
|
||||
}
|
||||
#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 = 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);
|
||||
mPressRel.setX(INT_MIN);
|
||||
}
|
||||
|
||||
void ModuleUnit::setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor) {
|
||||
if(mFrmSec==frmSec) return;
|
||||
mFrmSec = frmSec;
|
||||
if(cursor==Qt::ArrowCursor) unsetCursor();
|
||||
else setCursor(cursor);
|
||||
}
|
||||
|
||||
void ModuleUnit::clearSnap() {
|
||||
if(mLRSnap==0 && mTBSnap==0) return;
|
||||
mLRSnap = mTBSnap = 0;
|
||||
update();
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef MODULEUNIT_H
|
||||
#define MODULEUNIT_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPen>
|
||||
|
||||
#define m_handleLen 10
|
||||
class ExpertBoxLayoutWin;
|
||||
class ModuleUnit : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModuleUnit(ExpertBoxLayoutWin *, const QString &name, int x, int y, int w, int h, QWidget *parent = nullptr);
|
||||
|
||||
ExpertBoxLayoutWin *expertWin{0};
|
||||
QString name;
|
||||
int mX, mY, mW, mH;
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void mousePressEvent(QMouseEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
void mouseMoveEvent(QMouseEvent *) override;
|
||||
void leaveEvent(QEvent *) override;
|
||||
|
||||
void setFrmSec(const QPoint &);
|
||||
void setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor);
|
||||
void clearSnap();
|
||||
QPen mSidePen{Qt::white};
|
||||
|
||||
QPoint mPressRel{INT_MIN, INT_MIN};
|
||||
Qt::WindowFrameSection mFrmSec{Qt::NoSection};
|
||||
char mLRSnap{0}, mTBSnap{0};
|
||||
QList<ModuleUnit *> mOtherEles;
|
||||
|
||||
};
|
||||
|
||||
#endif // MODULEUNIT_H
|
|
@ -1,6 +1,14 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>128.ico</file>
|
||||
<file>imgs/align-left.png</file>
|
||||
<file>imgs/align-right.png</file>
|
||||
<file>imgs/align-top.png</file>
|
||||
<file>imgs/align-bottom.png</file>
|
||||
<file>imgs/arrange-left.png</file>
|
||||
<file>imgs/arrange-right.png</file>
|
||||
<file>imgs/arrange-top.png</file>
|
||||
<file>imgs/arrange-bottom.png</file>
|
||||
<file>imgs/checkbox-check.png</file>
|
||||
<file>imgs/checkbox-un.png</file>
|
||||
<file>imgs/radio-check.png</file>
|
||||
|
|
|
@ -62,7 +62,7 @@ void ScreenUnit::mousePressEvent(QMouseEvent *e) {
|
|||
QWidget::mousePressEvent(e);
|
||||
if(e->button() != Qt::LeftButton) return;
|
||||
setFrmSec(e->pos());
|
||||
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = mPressRel = pos() - e->globalPos();
|
||||
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = pos() - e->globalPos();
|
||||
else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(width() - e->globalX(), height() - e->globalY());
|
||||
else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(width() - e->globalX(), height() );
|
||||
else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(width() , height() - e->globalY());
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_TW">
|
||||
</TS>
|
|
@ -33,7 +33,6 @@ public:
|
|||
reply->deleteLater();
|
||||
});
|
||||
}
|
||||
QPushButton *btnAbort;
|
||||
QLabel *fdText;
|
||||
QString sucText;
|
||||
WaitingIndicator *mIndicator;
|
||||
|
|