Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to combine 2 applications in one application with one window

How to combine 2 applications in one application with one window

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 685 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • hamzaelaziziH Offline
    hamzaelaziziH Offline
    hamzaelazizi
    wrote on last edited by
    #1

    Hello everyone, so my problem is that i have a Qt application that allows me to take images using a thermal camera on a raspberry Pi, and then i have another application that allows me to take and save images using a nightvision camera, now the purpose of my project is to combine both projects and have one window showing both the thermal camera flow as well as the night camera flow with a capture button that'll take and save images for both cameras, meaning if i click on the capture button, both cameras need to take an image and save it. I don't know how to combine 2 .cpp into one especially that my thermal camera application runs on main.cpp and the other one runs on widget.cpp. Thank you !

    • widget.h
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QCamera>
    #include <QScopedPointer>
    #include <QCameraInfo>
    #include <QAction>
    #include <QCameraImageCapture>
    #include <QCameraViewfinder>
    #include <QPushButton>
    #include <QTimer>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
        void set_camera_action(QAction *camera_action);
        void set_camera(const QCameraInfo &camera_info);
    
    private:
        Ui::Widget *ui;
    
        void _setup_ui();
        void _setup_camera_devices();
    
        int idx{0};
    
        QScopedPointer<QCamera> _camera;
        QScopedPointer<QCameraImageCapture> _image_capture;
        QCameraViewfinder *_camera_view;
        QWidget *_central_widget;
        QPushButton *_take_image_button;
        QPushButton *_take_image_button_timer;
        QPushButton *_turn_camera_on;
        QPushButton *_turn_camera_off;
        QTimer *timer;
    };
    #endif // WIDGET_H
    
    • widget.cpp
    #include "widget.h"
    #include "ui_widget.h"
    #include "LeptonThread.h"
    #include "MyLabel.h"
    
    #include <QDir>
    #include <QFile>
    #include <QMenuBar>
    #include <QMenu>
    #include <QActionGroup>
    #include <QVBoxLayout>
    #include <QImage>
    #include <QStandardPaths>
    #include <QDebug>
    #include <QVideoFrame>
    #include <QRandomGenerator>
    #include <QThread>
    
    Q_DECLARE_METATYPE(QCameraInfo)
    
    Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        _camera_view = new QCameraViewfinder();
        _take_image_button_timer = new QPushButton("Take Timed Images");
        _take_image_button = new QPushButton("Take Image");
        _turn_camera_off = new QPushButton("Turn Off");
        _turn_camera_on= new QPushButton("Turn On");
        timer = new QTimer(this);
    
        _central_widget = new QWidget();
        _central_widget->show();
        _setup_ui();
        set_camera(QCameraInfo::defaultCamera());
    
        _image_capture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
    
        connect(_take_image_button, &QPushButton::clicked, [this]
        {
                _image_capture.data()->capture();
        });
    
        connect(_turn_camera_off, &QPushButton::clicked, [this]{_camera.data()->stop(); timer->stop();});
        connect(_turn_camera_on, &QPushButton::clicked, [this]{_camera.data()->start();});
    
    
        connect(_take_image_button_timer, &QPushButton::clicked, [this]
        {
            for(int hh=0;hh<5;hh++)
            {
                QThread::sleep(2);
                _image_capture.data()->capture();
            }
            //timer->start(1000);
         });
    
        QObject::connect(_image_capture.data(), &QCameraImageCapture::imageCaptured, [=] (int id=0, QImage img)
        {
                    idx=0;
                    QString fileName = QString::number(idx) + ".png";
                    QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/" + fileName;
                    while(QFile::exists(path))
                    {
                        idx++;
                        fileName = QString::number(idx) + ".png";
                        path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/" + fileName;
                    }
                    qDebug() << "khrjt mn lboucle";
                    img.save(path, "PNG");
         });
    
    }
    
    void Widget::_setup_ui()
    {
        QVBoxLayout *layout = new QVBoxLayout();
        layout->addWidget(_camera_view);
        layout->addWidget(_turn_camera_on);
        layout->addWidget(_turn_camera_off);
        layout->addWidget(_take_image_button);
        layout->addWidget(_take_image_button_timer);
        _central_widget->setLayout(layout);
    }
    void Widget::set_camera_action(QAction *camera_action)
    {
        set_camera(qvariant_cast<QCameraInfo>(camera_action->data()));
    }
    
    void Widget::set_camera(const QCameraInfo &camera_info)
    {
        _camera.reset(new QCamera(camera_info));
        _image_capture.reset(new QCameraImageCapture(_camera.data()));
    
        _camera.data()->setCaptureMode(QCamera::CaptureStillImage);
        _camera.data()->setViewfinder(_camera_view);
        _camera.data()->start();
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    
    • main.cpp
    #include <QApplication>
    #include <QThread>
    #include <QMutex>
    #include <QMessageBox>
    
    #include <QColor>
    #include <QLabel>
    #include <QtDebug>
    #include <QString>
    #include <QPushButton>
    #include <QVBoxLayout>
    
    #include "widget.h"
    #include "ui_widget.h"
    #include "LeptonThread.h"
    #include "MyLabel.h"
    
    void printUsage(char *cmd) {
            char *cmdname = basename(cmd);
        printf("Usage: %s [OPTION]...\n"
                   " -h      display this help and exit\n"
                   " -cm x   select colormap\n"
                   "           1 : rainbow\n"
                   "           2 : grayscale\n"
                   "           3 : ironblack [default]\n"
                   " -tl x   select type of Lepton\n"
                   "           2 : Lepton 2.x [default]\n"
                   "           3 : Lepton 3.x\n"
                   "               [for your reference] Please use nice command\n"
                   "                 e.g. sudo nice -n 0 ./%s -tl 3\n"
                   " -ss x   SPI bus speed [MHz] (10 - 30)\n"
                   "           20 : 20MHz [default]\n"
                   " -min x  override minimum value for scaling (0 - 65535)\n"
                   "           [default] automatic scaling range adjustment\n"
                   "           e.g. -min 30000\n"
                   " -max x  override maximum value for scaling (0 - 65535)\n"
                   "           [default] automatic scaling range adjustment\n"
                   "           e.g. -max 32000\n"
                   " -d x    log level (0-255)\n"
                   "", cmdname, cmdname);
        return;
    }
    
    int LeptonThread::snapshotCount =0;
    
    int main( int argc, char **argv )
    {
        int typeColormap = 3; // colormap_ironblack
        int typeLepton = 2; // Lepton 2.x
        int spiSpeed = 20; // SPI bus speed 20MHz
        int rangeMin = -1; //
        int rangeMax = -1; //
        int loglevel = 0;
        for(int i=1; i < argc; i++) {
            if (strcmp(argv[i], "-h") == 0) {
                printUsage(argv[0]);
                exit(0);
            }
            else if (strcmp(argv[i], "-d") == 0) {
                int val = 3;
                if ((i + 1 != argc) && (strncmp(argv[i + 1], "-", 1) != 0)) {
                    val = std::atoi(argv[i + 1]);
                    i++;
                }
                if (0 <= val) {
                    loglevel = val & 0xFF;
                }
            }
            else if ((strcmp(argv[i], "-cm") == 0) && (i + 1 != argc)) {
                int val = std::atoi(argv[i + 1]);
                if ((val == 1) || (val == 2)) {
                    typeColormap = val;
                    i++;
                }
            }
            else if ((strcmp(argv[i], "-tl") == 0) && (i + 1 != argc)) {
                int val = std::atoi(argv[i + 1]);
                if (val == 3) {
                    typeLepton = val;
                    i++;
                }
            }
            else if ((strcmp(argv[i], "-ss") == 0) && (i + 1 != argc)) {
                int val = std::atoi(argv[i + 1]);
                if ((10 <= val) && (val <= 30)) {
                    spiSpeed = val;
                    i++;
                }
            }
            else if ((strcmp(argv[i], "-min") == 0) && (i + 1 != argc)) {
                int val = std::atoi(argv[i + 1]);
                if ((0 <= val) && (val <= 65535)) {
                    rangeMin = val;
                    i++;
                }
            }
            else if ((strcmp(argv[i], "-max") == 0) && (i + 1 != argc)) {
                int val = std::atoi(argv[i + 1]);
                if ((0 <= val) && (val <= 65535)) {
                    rangeMax = val;
                    i++;
                }
            }
        }
    
        //create the app
        QApplication a( argc, argv );
    
        QWidget *myWidget = new QWidget;
        myWidget->setGeometry(400, 300, 340, 290);
    
        //create an image placeholder for myLabel
        //fill the top left corner with red, just bcuz
        QImage myImage;
        myImage = QImage(320, 240, QImage::Format_RGB888);
        QRgb red = qRgb(255,0,0);
        for(int i=0;i<80;i++) {
            for(int j=0;j<60;j++) {
                myImage.setPixel(i, j, red);
            }
        }
    
        //create a label, and set it's image to the placeholder
        MyLabel myLabel(myWidget);
        myLabel.setGeometry(10, 10, 320, 240);
        myLabel.setPixmap(QPixmap::fromImage(myImage));
    
        //create a FFC button
        QPushButton *button1 = new QPushButton("Perform FFC", myWidget);
        button1->setGeometry(580/2-50, 290-35, 100, 30);
    
        //create a capture button
        QPushButton *button2 = new QPushButton("Capture", myWidget);
        button2->setGeometry(100/2-50, 290-35, 100, 30);
    
        //create a thread to gather SPI data
        //when the thread emits updateImage, the label should update its image accordingly
        LeptonThread *thread = new LeptonThread();
        thread->setLogLevel(loglevel);
        thread->useColormap(typeColormap);
        thread->useLepton(typeLepton);
        thread->useSpiSpeedMhz(spiSpeed);
        thread->setAutomaticScalingRange();
        if (0 <= rangeMin) thread->useRangeMinValue(rangeMin);
        if (0 <= rangeMax) thread->useRangeMaxValue(rangeMax);
        QObject::connect(thread, SIGNAL(updateImage(QImage)), &myLabel, SLOT(setImage(QImage)));
    
        //connect ffc button to the thread's ffc action
        QObject::connect(button1, SIGNAL(clicked()), thread, SLOT(performFFC()));
        thread->start();
    
        //connect capture button to the thread's capture action
        QObject::connect(button2, SIGNAL(clicked()), thread, SLOT(Capture()));
    
        myWidget->show();
        Widget w;
        w.show();
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • posktomtenP Offline
      posktomtenP Offline
      posktomten
      wrote on last edited by
      #2

      Hi!
      Maybe you can turn one program into a class that you use in the other
      And let the program handle the output from the class using SIGNALS and SLOTS.

      posktomten

      hamzaelaziziH 1 Reply Last reply
      1
      • posktomtenP posktomten

        Hi!
        Maybe you can turn one program into a class that you use in the other
        And let the program handle the output from the class using SIGNALS and SLOTS.

        hamzaelaziziH Offline
        hamzaelaziziH Offline
        hamzaelazizi
        wrote on last edited by
        #3

        @posktomten Thank you for your answer, actually i'm pretty new to Qt programming so can you please tell me how to do that exactly ? or can you give me an example so i can see how it works exactly.

        1 Reply Last reply
        0
        • posktomtenP Offline
          posktomtenP Offline
          posktomten
          wrote on last edited by posktomten
          #4

          In Qt Creator: "File", "New File ...", select "C / C ++" and "C ++ class"
          You get an h-file and a cpp file.

          The program and the class can communicate through SIGNALS and SLOTS

          Example:
          In the Program

          // in h file
          public slots: 
               void getValue (const QString & string);
          
          // in cpp file
          // Declares an object of class MyClass
          MyClass *mMyClass; 
          // Create contact
          connect (mMyClass, & MyClass::a_signal, this, & mMyProgram::setValue);
          
          // Receives what the class sends
          void MyProgram::getValue(QString *content)
          {
                  // Do something
          }
          

          In the class

          //In h file
                   signals:
                       // Declares a signal
                       void a_signal (QString);
          
          // In cpp file
          // Sends a signal
          emit a_signal (QString ("Hello!"));
          

          Hope you get some inspiration!

          posktomten

          hamzaelaziziH 1 Reply Last reply
          0
          • posktomtenP posktomten

            In Qt Creator: "File", "New File ...", select "C / C ++" and "C ++ class"
            You get an h-file and a cpp file.

            The program and the class can communicate through SIGNALS and SLOTS

            Example:
            In the Program

            // in h file
            public slots: 
                 void getValue (const QString & string);
            
            // in cpp file
            // Declares an object of class MyClass
            MyClass *mMyClass; 
            // Create contact
            connect (mMyClass, & MyClass::a_signal, this, & mMyProgram::setValue);
            
            // Receives what the class sends
            void MyProgram::getValue(QString *content)
            {
                    // Do something
            }
            

            In the class

            //In h file
                     signals:
                         // Declares a signal
                         void a_signal (QString);
            
            // In cpp file
            // Sends a signal
            emit a_signal (QString ("Hello!"));
            

            Hope you get some inspiration!

            hamzaelaziziH Offline
            hamzaelaziziH Offline
            hamzaelazizi
            wrote on last edited by
            #5

            @posktomten Thank you sir for your help i'll try to get this working !

            1 Reply Last reply
            0
            • posktomtenP Offline
              posktomtenP Offline
              posktomten
              wrote on last edited by
              #6

              I have clarified my example a bit.

              posktomten

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Hi,

                You don't need combine two classes in a single one.

                In fact it depends on how you implemented both widgets originally. If they work the same way, you can simply create two objects, one for each camera and configure them properly rather than duplicate code.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • posktomtenP Offline
                  posktomtenP Offline
                  posktomten
                  wrote on last edited by
                  #8

                  Just! or perhaps have two classes that inherit common characteristics from a parent class.

                  posktomten

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved