weld_measure/main_window.cpp
2026-08-12 08:44:39 -03:00

167 lines
5.7 KiB
C++

#include "main_window.h"
#include <QFileDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGroupBox>
#include <QFormLayout>
#include <QStyle>
#include <QMessageBox>
#include <QPainter>
#include <QtMath>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle("Sistema de Inspección y Medición de Soldaduras (Línea Única)");
resize(1200, 800);
createUI();
createDefaultSampleImage();
}
void MainWindow::createUI()
{
QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);
mainLayout->setContentsMargins(8, 8, 8, 8);
mainLayout->setSpacing(8);
// Left sidebar panel
QWidget *panel = new QWidget(centralWidget);
panel->setFixedWidth(320);
QVBoxLayout *panelLayout = new QVBoxLayout(panel);
panelLayout->setContentsMargins(4, 4, 4, 4);
// Image loading section
QGroupBox *grpFile = new QGroupBox("1. Imagen de Inspección", panel);
QVBoxLayout *fileLayout = new QVBoxLayout(grpFile);
QPushButton *btnOpen = new QPushButton("Cargar Imagen...", grpFile);
btnOpen->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton));
btnOpen->setFixedHeight(36);
fileLayout->addWidget(btnOpen);
panelLayout->addWidget(grpFile);
// Calibration setup section
QGroupBox *grpCalib = new QGroupBox("2. Calibración por Escala", panel);
QVBoxLayout *calibLayout = new QVBoxLayout(grpCalib);
QFormLayout *formCalib = new QFormLayout();
m_spinCalibMm = new QDoubleSpinBox(grpCalib);
m_spinCalibMm->setRange(0.001, 10000.0);
m_spinCalibMm->setValue(10.0);
m_spinCalibMm->setSuffix(" mm");
m_spinCalibMm->setDecimals(3);
formCalib->addRow("Largo Real Patrón:", m_spinCalibMm);
calibLayout->addLayout(formCalib);
m_btnCalibrate = new QPushButton("Calibrar Escala", grpCalib);
m_btnCalibrate->setFixedHeight(34);
m_btnCalibrate->setStyleSheet("font-weight: bold; background-color: #2b5b84; color: white; border-radius: 4px;");
calibLayout->addWidget(m_btnCalibrate);
panelLayout->addWidget(grpCalib);
// Measurement readout section
QGroupBox *grpMeas = new QGroupBox("3. Medición en Vivo", panel);
QVBoxLayout *measLayout = new QVBoxLayout(grpMeas);
m_lblMeasurement = new QLabel("Medida: -\nDistancia: - px", grpMeas);
m_lblMeasurement->setStyleSheet("font-size: 14px; font-weight: bold; color: #ff5555; background: #1e1e24; padding: 10px; border-radius: 4px;");
measLayout->addWidget(m_lblMeasurement);
panelLayout->addWidget(grpMeas);
panelLayout->addStretch();
// OpenGL Central Viewport Widget
m_glWidget = new WeldOpenGLWidget(centralWidget);
mainLayout->addWidget(panel);
mainLayout->addWidget(m_glWidget, 1);
// Connect signals & slots
connect(btnOpen, &QPushButton::clicked, this, &MainWindow::openImage);
connect(m_btnCalibrate, &QPushButton::clicked, this, &MainWindow::onCalibrateClicked);
connect(m_glWidget, &WeldOpenGLWidget::measurementUpdated, this, &MainWindow::updateMeasurementInfo);
}
void MainWindow::createDefaultSampleImage()
{
QImage img(1000, 700, QImage::Format_RGB32);
img.fill(QColor(40, 42, 48));
QPainter painter(&img);
painter.setRenderHint(QPainter::Antialiasing);
// Draw simulated weld seam
for (int x = 100; x < 900; x += 6) {
double y = 350 + qSin(x / 30.0) * 15 + qCos(x / 7.0) * 8;
double r = 25 + qSin(x / 10.0) * 5;
painter.setBrush(QColor(130, 135, 145));
painter.setPen(QPen(QColor(170, 175, 185), 1.5));
painter.drawEllipse(QPointF(x, y), r, r * 0.5);
}
// Draw reference pattern bar (200px = 10mm)
int scaleX = 150;
int scaleY = 560;
int scaleLenPx = 200;
painter.setBrush(QColor(230, 230, 230));
painter.setPen(Qt::NoPen);
painter.drawRoundedRect(scaleX - 20, scaleY - 30, scaleLenPx + 40, 70, 8, 8);
QPen rulerPen(Qt::black, 4, Qt::SolidLine, Qt::SquareCap);
painter.setPen(rulerPen);
painter.drawLine(scaleX, scaleY, scaleX + scaleLenPx, scaleY);
painter.drawLine(scaleX, scaleY - 15, scaleX, scaleY + 15);
painter.drawLine(scaleX + scaleLenPx, scaleY - 15, scaleX + scaleLenPx, scaleY + 15);
painter.setFont(QFont("Arial", 11, QFont::Bold));
painter.drawText(QRect(scaleX - 20, scaleY + 10, scaleLenPx + 40, 25), Qt::AlignCenter, "PATRÓN DE PRUEBA: 10.0 mm");
img.save("/home/sebastian/repos/weld_measure/sample_weld.png");
m_glWidget->setImage(img);
// Position single line right over the sample pattern bar (200px = 10mm)
m_glWidget->setLinePoints(QPointF(scaleX, scaleY), QPointF(scaleX + scaleLenPx, scaleY));
m_glWidget->calibrateWithCurrentLine(10.0);
}
void MainWindow::openImage()
{
QString fileName = QFileDialog::getOpenFileName(this, "Abrir Imagen de Inspección", "", "Imágenes (*.png *.jpg *.jpeg *.bmp *.tif *.tiff)");
if (!fileName.isEmpty()) {
if (!m_glWidget->loadImage(fileName)) {
QMessageBox::warning(this, "Error", "No se pudo cargar la imagen seleccionada.");
}
}
}
void MainWindow::onCalibrateClicked()
{
double knownMm = m_spinCalibMm->value();
m_glWidget->calibrateWithCurrentLine(knownMm);
QMessageBox::information(this, "Calibración Exitosa",
QString("Escala fijada correctamente:\n%1 mm/px\n\nAhora puede mover la misma línea para medir cualquier parte de la imagen.")
.arg(m_glWidget->mmPerPixel(), 0, 'g', 5));
}
void MainWindow::updateMeasurementInfo(double px, double mm)
{
Q_UNUSED(px);
if (m_glWidget->isCalibrated()) {
m_lblMeasurement->setText(QString("Medida: %1 mm").arg(mm, 0, 'f', 2));
} else {
m_lblMeasurement->setText("Medida: Sin Calibrar");
}
}