#include "main_window.h" #include #include #include #include #include #include #include #include #include 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"); } }