[MAC OS] Embded Qt application into another Qt application with QWindow::createWindowContainer



  • Hi all.
    I want to embeb one my Qt application (child) into another my application(parent) (like GoogleChrome)

    The code below work good for Windows:

    Child:

    ChildWidget::ChildWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::ChildWidget)
      , sharedMemory("mysharedTEST")
    {
        ui->setupUi(this);
        qDebug() << "ChildWidget winId:" << winId();
        QString winIdStr(QString::number(winId()));
    
        QBuffer buffer;
        buffer.open(QBuffer::ReadWrite);
        QDataStream out(&buffer);
        out << winIdStr;
        int size = buffer.size();
    
        if (!sharedMemory.create(size))
        {
            qDebug() << "Unable to create shared memory segment.";
            QMessageBox::information(this,"", sharedMemory.errorString());
            return;
        }
        sharedMemory.lock();
        char *to = (char*)sharedMemory.data();
        const char *from = buffer.data().data();
        memcpy(to, from, qMin(sharedMemory.size(), size));
    
        sharedMemory.unlock();
        setWindowFlags(Qt::FramelessWindowHint);
    }
    

    Parent:

    ParentWidget::ParentWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::ParentWidget),
        childWidget(NULL)
    {
        ui->setupUi(this);
    
    
        connect(ui->integrateWidgetBtn, SIGNAL(clicked(bool)), this, SLOT(integrate()));
    }
    
    void ParentWidget::integrate()
    {
        QString error;
        QLibrary library("child.exe");
        if (!library.load())
        {
            error = library.errorString();
            QMessageBox::information(this,"", error);
            return;
        }
        if (library.load())
        {
            error = "library loaded";
        }
    
        QSharedMemory sharedMemory("mysharedTEST");
        if (!sharedMemory.attach())
        {
            QMessageBox::information(this, "", sharedMemory.errorString());
            return;
        }
    
        QBuffer buffer;
        QDataStream in(&buffer);
    
        sharedMemory.lock();
        int ss = sharedMemory.size();
        buffer.setData((char*)sharedMemory.constData(), ss);
        buffer.open(QBuffer::ReadOnly);
        QString winIdStr;
        in >> winIdStr;
        sharedMemory.unlock();
    
        sharedMemory.detach();
        int childWidgetWinId = winIdStr.toInt(); //get from debug output
    
        if (childWidgetWinId == 0)
        {
            QMessageBox::information(this, "", "childWidgetWinId was not loaded");
            return;
        }
        QWindow* childWindow = QWindow::fromWinId(childWidgetWinId);
        childWidget = QWidget::createWindowContainer(childWindow, this, Qt::Widget);
        ui->childWidgetLayout->addWidget(childWidget);
    }
    

    But on MAC OS I got a problem.

    1. In QLibrary I don't know how to load child.exe (I knew, that there is no exe files on MAC, I tried just name and *.app, *.o)
    2. If skip QLibrary, QSharedMemory didn't return child application recorded data (it is 0)
    3. If skip recieving child winId through QSharedMemory and put it to parent through parent QLineEdit to QWidget::createWindowContainer - I got a crash (tried insert child app winId and child processId).

    The main question is how embded child Qt app in Parent Qt application on MAC OS? (question 3)
    And If you know answer on 1 and 2 question, I will also be grateful.



  • @Holiday

    I don't know anything about QLibrary; but on Mac there are executables, you simply have to find them in the application bundle.

    e.g. What you would know as Firefox.exe on windows would be something like Firefox.app/Contents/MacOS/Firefox.

    In the finder, an "executable" is represented as a folder holding local DLLs, subprocesses, resources etc and the icon you click on to launch the program is shown for the bundle folder.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.