261 lines
9.0 KiB
C++
261 lines
9.0 KiB
C++
|
|
#include "mainwindow.h"
|
|||
|
|
#include "ui_mainwindow.h"
|
|||
|
|
#include <QMessageBox>
|
|||
|
|
#include <QDateTime>
|
|||
|
|
#include <QBuffer>
|
|||
|
|
|
|||
|
|
MainWindow::MainWindow(QWidget *parent)
|
|||
|
|
: QMainWindow(parent)
|
|||
|
|
, ui(new Ui::MainWindow)
|
|||
|
|
{
|
|||
|
|
ui->setupUi(this);
|
|||
|
|
|
|||
|
|
// 创建接收器实例
|
|||
|
|
IBinocularMarkReceiver* pReceiver = nullptr;
|
|||
|
|
if (IBinocularMarkReceiver::CreateInstance(&pReceiver) == 0 && pReceiver) {
|
|||
|
|
m_receiver.reset(pReceiver);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 连接信号槽
|
|||
|
|
connect(ui->btn_connect, &QPushButton::clicked, this, &MainWindow::onConnectClicked);
|
|||
|
|
connect(ui->btn_startWork, &QPushButton::clicked, this, &MainWindow::onStartWorkClicked);
|
|||
|
|
connect(ui->btn_stopWork, &QPushButton::clicked, this, &MainWindow::onStopWorkClicked);
|
|||
|
|
connect(ui->btn_singleImage, &QPushButton::clicked, this, &MainWindow::onSingleImageClicked);
|
|||
|
|
connect(ui->btn_singleDetection, &QPushButton::clicked, this, &MainWindow::onSingleDetectionClicked);
|
|||
|
|
connect(ui->btn_setExposureTime, &QPushButton::clicked, this, &MainWindow::onSetExposureTimeClicked);
|
|||
|
|
connect(ui->btn_setGain, &QPushButton::clicked, this, &MainWindow::onSetGainClicked);
|
|||
|
|
|
|||
|
|
// 设置事件回调
|
|||
|
|
if (m_receiver) {
|
|||
|
|
m_receiver->SetEventCallback([this](ReceiverEventType eventType, const std::string& errorMsg) {
|
|||
|
|
QMetaObject::invokeMethod(this, [this, eventType, errorMsg]() {
|
|||
|
|
QString msg;
|
|||
|
|
switch (eventType) {
|
|||
|
|
case ReceiverEventType::CONNECTED:
|
|||
|
|
msg = "已连接";
|
|||
|
|
updateConnectionState(true);
|
|||
|
|
break;
|
|||
|
|
case ReceiverEventType::DISCONNECTED:
|
|||
|
|
msg = "已断开";
|
|||
|
|
updateConnectionState(false);
|
|||
|
|
break;
|
|||
|
|
case ReceiverEventType::CONNECTION_ERROR:
|
|||
|
|
msg = QString("连接错误: %1").arg(QString::fromStdString(errorMsg));
|
|||
|
|
updateConnectionState(false);
|
|||
|
|
break;
|
|||
|
|
case ReceiverEventType::HEARTBEAT_TIMEOUT:
|
|||
|
|
msg = "心跳超时";
|
|||
|
|
updateConnectionState(false);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
msg = "未知事件";
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
appendResult(msg);
|
|||
|
|
ui->statusbar->showMessage(msg);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 设置持续检测结果回调
|
|||
|
|
m_receiver->SetMarkResultCallback([this](const std::vector<VrMark3D>& marks, int64_t timestamp, int errorCode) {
|
|||
|
|
QMetaObject::invokeMethod(this, [this, marks, timestamp, errorCode]() {
|
|||
|
|
QString result = QString("[%1] 持续检测结果 (错误码: %2):\n")
|
|||
|
|
.arg(QDateTime::fromMSecsSinceEpoch(timestamp).toString("hh:mm:ss.zzz"))
|
|||
|
|
.arg(errorCode);
|
|||
|
|
|
|||
|
|
if (errorCode == 0 && !marks.empty()) {
|
|||
|
|
for (const auto& mark : marks) {
|
|||
|
|
result += QString(" Mark ID=%1: (%.2f, %.2f, %.2f)\n")
|
|||
|
|
.arg(mark.markID)
|
|||
|
|
.arg(mark.x, 0, 'f', 2)
|
|||
|
|
.arg(mark.y, 0, 'f', 2)
|
|||
|
|
.arg(mark.z, 0, 'f', 2);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
result += " 无检测结果\n";
|
|||
|
|
}
|
|||
|
|
appendResult(result);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
MainWindow::~MainWindow()
|
|||
|
|
{
|
|||
|
|
if (m_receiver && m_receiver->IsConnected()) {
|
|||
|
|
m_receiver->StopWork();
|
|||
|
|
m_receiver->Disconnect();
|
|||
|
|
}
|
|||
|
|
delete ui;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::onConnectClicked()
|
|||
|
|
{
|
|||
|
|
if (!m_receiver) {
|
|||
|
|
QMessageBox::warning(this, "错误", "接收器未初始化");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (m_receiver->IsConnected()) {
|
|||
|
|
m_receiver->Disconnect();
|
|||
|
|
ui->btn_connect->setText("连接");
|
|||
|
|
updateConnectionState(false);
|
|||
|
|
} else {
|
|||
|
|
QString ip = ui->lineEdit_ip->text();
|
|||
|
|
uint16_t port = ui->lineEdit_port->text().toUShort();
|
|||
|
|
|
|||
|
|
int ret = m_receiver->Connect(ip.toStdString(), port);
|
|||
|
|
if (ret == 0) {
|
|||
|
|
ui->btn_connect->setText("断开");
|
|||
|
|
updateConnectionState(true);
|
|||
|
|
appendResult(QString("正在连接 %1:%2...").arg(ip).arg(port));
|
|||
|
|
} else {
|
|||
|
|
QMessageBox::warning(this, "错误", QString("连接失败,错误码: %1").arg(ret));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::onStartWorkClicked()
|
|||
|
|
{
|
|||
|
|
if (!m_receiver || !m_receiver->IsConnected()) return;
|
|||
|
|
|
|||
|
|
int ret = m_receiver->StartWork();
|
|||
|
|
if (ret == 0) {
|
|||
|
|
appendResult("开始持续检测");
|
|||
|
|
ui->btn_startWork->setEnabled(false);
|
|||
|
|
ui->btn_stopWork->setEnabled(true);
|
|||
|
|
} else {
|
|||
|
|
QMessageBox::warning(this, "错误", QString("启动失败,错误码: %1").arg(ret));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::onStopWorkClicked()
|
|||
|
|
{
|
|||
|
|
if (!m_receiver || !m_receiver->IsConnected()) return;
|
|||
|
|
|
|||
|
|
int ret = m_receiver->StopWork();
|
|||
|
|
if (ret == 0) {
|
|||
|
|
appendResult("停止持续检测");
|
|||
|
|
ui->btn_startWork->setEnabled(true);
|
|||
|
|
ui->btn_stopWork->setEnabled(false);
|
|||
|
|
} else {
|
|||
|
|
QMessageBox::warning(this, "错误", QString("停止失败,错误码: %1").arg(ret));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::onSingleImageClicked()
|
|||
|
|
{
|
|||
|
|
if (!m_receiver || !m_receiver->IsConnected()) return;
|
|||
|
|
|
|||
|
|
appendResult("请求单次取图...");
|
|||
|
|
auto imageData = m_receiver->RequestSingleImage(5000);
|
|||
|
|
|
|||
|
|
if (imageData.timestamp > 0) {
|
|||
|
|
displayImage(ui->label_left, imageData.leftImageBase64);
|
|||
|
|
displayImage(ui->label_right, imageData.rightImageBase64);
|
|||
|
|
appendResult(QString("取图成功 [%1]")
|
|||
|
|
.arg(QDateTime::fromMSecsSinceEpoch(imageData.timestamp).toString("hh:mm:ss.zzz")));
|
|||
|
|
} else {
|
|||
|
|
appendResult("取图失败或超时");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::onSingleDetectionClicked()
|
|||
|
|
{
|
|||
|
|
if (!m_receiver || !m_receiver->IsConnected()) return;
|
|||
|
|
|
|||
|
|
appendResult("请求单次检测...");
|
|||
|
|
auto result = m_receiver->RequestSingleDetection(5000);
|
|||
|
|
|
|||
|
|
if (result.timestamp > 0) {
|
|||
|
|
displayImage(ui->label_left, result.leftImageBase64);
|
|||
|
|
displayImage(ui->label_right, result.rightImageBase64);
|
|||
|
|
|
|||
|
|
QString msg = QString("检测完成 [%1] (错误码: %2):\n")
|
|||
|
|
.arg(QDateTime::fromMSecsSinceEpoch(result.timestamp).toString("hh:mm:ss.zzz"))
|
|||
|
|
.arg(result.errorCode);
|
|||
|
|
|
|||
|
|
if (result.errorCode == 0 && !result.marks.empty()) {
|
|||
|
|
for (const auto& mark : result.marks) {
|
|||
|
|
msg += QString(" Mark ID=%1: (%.2f, %.2f, %.2f)\n")
|
|||
|
|
.arg(mark.markID)
|
|||
|
|
.arg(mark.x, 0, 'f', 2)
|
|||
|
|
.arg(mark.y, 0, 'f', 2)
|
|||
|
|
.arg(mark.z, 0, 'f', 2);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
msg += " 无检测结果\n";
|
|||
|
|
}
|
|||
|
|
appendResult(msg);
|
|||
|
|
} else {
|
|||
|
|
appendResult("检测失败或超时");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::onSetExposureTimeClicked()
|
|||
|
|
{
|
|||
|
|
if (!m_receiver || !m_receiver->IsConnected()) return;
|
|||
|
|
|
|||
|
|
double exposureTime = ui->lineEdit_exposure->text().toDouble();
|
|||
|
|
|
|||
|
|
if (exposureTime <= 0) {
|
|||
|
|
appendResult("错误:曝光时间必须大于0");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int ret = m_receiver->SetExposureTime(exposureTime);
|
|||
|
|
if (ret == 0) {
|
|||
|
|
appendResult(QString("设置曝光时间成功:%.2f").arg(exposureTime));
|
|||
|
|
} else {
|
|||
|
|
appendResult(QString("设置曝光时间失败,错误码: %1").arg(ret));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::onSetGainClicked()
|
|||
|
|
{
|
|||
|
|
if (!m_receiver || !m_receiver->IsConnected()) return;
|
|||
|
|
|
|||
|
|
double gain = ui->lineEdit_gain->text().toDouble();
|
|||
|
|
|
|||
|
|
if (gain <= 0) {
|
|||
|
|
appendResult("错误:增益必须大于0");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int ret = m_receiver->SetGain(gain);
|
|||
|
|
if (ret == 0) {
|
|||
|
|
appendResult(QString("设置增益成功:%.2f").arg(gain));
|
|||
|
|
} else {
|
|||
|
|
appendResult(QString("设置增益失败,错误码: %1").arg(ret));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::displayImage(QLabel* label, const std::string& base64Data)
|
|||
|
|
{
|
|||
|
|
if (base64Data.empty()) return;
|
|||
|
|
|
|||
|
|
QByteArray imageData = QByteArray::fromBase64(QByteArray::fromStdString(base64Data));
|
|||
|
|
QImage image;
|
|||
|
|
if (image.loadFromData(imageData)) {
|
|||
|
|
label->setPixmap(QPixmap::fromImage(image).scaled(
|
|||
|
|
label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::appendResult(const QString& text)
|
|||
|
|
{
|
|||
|
|
ui->textEdit_result->append(text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void MainWindow::updateConnectionState(bool connected)
|
|||
|
|
{
|
|||
|
|
ui->btn_startWork->setEnabled(connected);
|
|||
|
|
ui->btn_stopWork->setEnabled(false);
|
|||
|
|
ui->btn_singleImage->setEnabled(connected);
|
|||
|
|
ui->btn_singleDetection->setEnabled(connected);
|
|||
|
|
ui->btn_setExposureTime->setEnabled(connected);
|
|||
|
|
ui->btn_setGain->setEnabled(connected);
|
|||
|
|
ui->lineEdit_ip->setEnabled(!connected);
|
|||
|
|
ui->lineEdit_port->setEnabled(!connected);
|
|||
|
|
}
|