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. Embed an application inside a Qt Window [SOLVED]
Forum Updated to NodeBB v4.3 + New Features

Embed an application inside a Qt Window [SOLVED]

Scheduled Pinned Locked Moved General and Desktop
17 Posts 4 Posters 31.4k Views 1 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.
  • JKSHJ Offline
    JKSHJ Offline
    JKSH
    Moderators
    wrote on last edited by
    #3

    Hi,

    I was just investigating this myself recently. I found a number of issues with embedding external windows on Windows, however.

    You can find short example code and a description of issues at https://bugreports.qt-project.org/browse/QTBUG-40320 (in the code, ignore the calls to QObject::connect())

    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

    1 Reply Last reply
    0
    • I Offline
      I Offline
      ion_knight
      wrote on last edited by
      #4

      Currently this is my implementation but it doesn't work correctly cause I am unsure if my order is correct/parenting etc. What is does is show the video but it's not embedded into the the main widget. To be honest now at this point I'm completely lost. All I what to do is embed the video inside a Qt application, if anyone has any ideas where i'm going wrong that would be great.

      @#include "widget.h"
      #include "ui_widget.h"

      Widget::Widget(QWidget *parent) :
      QWidget(parent),
      ui(new Ui::Widget)
      {
      ui->setupUi(this);
      QString program;
      program = "E:\Downloads\mplayer\mplayer.exe";

      QStringList arguments;
      arguments << "E:\\Downloads\\BigBuckBunny_320x180.mp4";
      WId winid = this->winId();
      QWindow *container = QWindow::fromWinId(winid);
      QWidget *program_start  = createWindowContainer(container);
      QPushButton *button = new QPushButton("&Download", this);
      //QWidget *container = new QWidget(parent);
      //QProcess *myProcess = new QProcess(parent);
      QVBoxLayout *layout = new QVBoxLayout;
      QProcess *myProcess = new QProcess(parent);
      myProcess->start(program, arguments);
      
      layout->addWidget(program_start);
      layout->addWidget(button);
      setLayout(layout);
      
      myProcess->waitForFinished();
      

      }

      Widget::~Widget()
      {
      delete ui;
      }

      @

      But thanks for the help so far every bit helps.

      1 Reply Last reply
      0
      • JKSHJ Offline
        JKSHJ Offline
        JKSH
        Moderators
        wrote on last edited by
        #5

        [quote]
        @
        WId winid = this->winId();
        QWindow *container = QWindow::fromWinId(winid);
        QWidget *program_start = createWindowContainer(container);
        @
        [/quote]You embedded your Widget object.

        You need to get the WId (HWND) of your MPlayer window after you launch the process.

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        1 Reply Last reply
        0
        • I Offline
          I Offline
          ion_knight
          wrote on last edited by
          #6

          Ok well only way I have found, that i could set or get the mplayer HWND, is via setting it's parameters ("-wid 1234"). Which should set the ID for the process.

          However there must be a way to get the ID via winID or am I looking in the wrong direction. I expected that I had the container in the wrong place in the code however haven't been able to get it to work yet.

          This is the line, that is my main problem, can't see which object should be used.
          @WId winid = this->winId();@

          Tried doing what you said but know that I am still lost with winID (HWND).
          @ QString program;
          program = "E:\Downloads\mplayer\mplayer.exe";

          QStringList arguments;
          arguments << "-wid" << QString::number((int)winId()) << "E:\\Downloads\\BigBuckBunny_320x180.mp4";
          
          QVBoxLayout *layout = new QVBoxLayout;
          
          QPushButton *button = new QPushButton("Test2");
          QPushButton *button2 = new QPushButton("Test");
          
          
          QProcess *m_process = new QProcess(this);
          
          m_process->setProgram(program);
          m_process->setArguments(arguments);
          
          m_process->start();
          
          WId winid = winId();
          QWindow *container = QWindow::fromWinId(winid);
          QWidget *program_start  = createWindowContainer(container);@
          
          1 Reply Last reply
          0
          • JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by
            #7

            Every window has its own HWND. When you create a new widget and show it, your OS will give it a HWND. When you launch MPlayer, your OS will give it a different HWND.

            (Note: HWND is specific to the Windows OS. Linux and Mac OS X use other types of ID)

            [quote]This is the line, that is my main problem, can’t see which object should be used.
            @WId winid = this->winId();@
            [/quote]The object you want does not exist. Qt cannot find the HWND of a non-Qt window.

            You need to use native OS functions to find the HWND of the external MPlayer window. Something like FindWindow(): http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx Also scroll down to the comments of that page -- other uses have posted alternative ways to find HWND.

            See the link in my first post for an example.

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            1 Reply Last reply
            0
            • I Offline
              I Offline
              ion_knight
              wrote on last edited by
              #8

              Well think I am now getting the correct ID (using find window). However code builds but just plays the video outside of the window. I must be getting very close however as not getting the same functional errors (no windows are crashing etc).

              @ WId id = (WId)FindWindow(NULL, L"Mplayer");
              //if (!id)
              // return -1;

              QString program;
              program = "C:\\Users\\Downloads\\MPlayer\\mplayer.exe";
              
              QStringList arguments;
              arguments << "-vo directx:noaccel" << "-wid " << QString::number((int)winId()) << "C:\\Users\\Downloads\\big_buck_bunny_480p_surround-fix.avi";
              
              QProcess *m_process = new QProcess(this);
              m_process->setProgram(program);
              m_process->setArguments(arguments);
              
              m_process->start();
              
              QWindow *container = QWindow::fromWinId(id);
              QWidget *program_start  = QWidget::createWindowContainer(container);
              
              QMessageBox test;
              test.setText(QString::number(id));
              test.exec&#40;&#41;;
              
              setCentralWidget(program_start&#41;;
              program_start->setMinimumSize(400,400&#41;;
              program_start->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding&#41;;
              QVBoxLayout *layout = new QVBoxLayout;
              layout->addWidget(program_start);
              program_start->setLayout(layout);
              

              @

              Currently what happens if I only pass the video file name to arguments the video will play. If I include the -wid and or -vo the program no longer runs, if anyone has an idea where I am going wrong please let me know. As currently thinking I have two problems one being my mplayer parameters and the other being related to the container (again not sure though what exactly is the problem line). Thanks for everyones help so far.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andreyc
                wrote on last edited by
                #9

                From the mplayer man page
                @
                -wid <window ID> (also see -gui-wid) (X11, OpenGL and DirectX only)
                This tells MPlayer to attach to an existing window. Useful to embed MPlayer in a browser (e.g. the plugger extension). This option fills the given window completely, thus aspect scaling, panscan, etc are no longer handled by MPlayer but must be managed by the application that created the window.
                @

                -wid takes a window id of your app or widget and mplayer will use it to output a video. But you will have to control "aspect scaling, panscan, etc".

                Take a look on the sources of "smplayer":http://smplayer.sourceforge.net/ I think they use this embeded mplayer approach.

                1 Reply Last reply
                0
                • I Offline
                  I Offline
                  ion_knight
                  wrote on last edited by
                  #10

                  Yea sadly my problem isn't really related to what "-wid" does but why when adding it to the parameters does it not show any video. Either way to give you an idea smplayer is actually where i started this adventure and even they use the same method i do.

                  Below is the code of smplayer that inserts the "-wid" into the arguement/parameter list.

                  @ proc->addArgument("-wid");
                  #if defined(Q_OS_OS2)
                  #define WINIDFROMHWND(hwnd) ( ( hwnd ) - 0x80000000UL )
                  proc->addArgument( QString::number( WINIDFROMHWND( (int) mplayerwindow->videoLayer()->winId() ) ));
                  #else
                  proc->addArgument( QString::number( (qint64) mplayerwindow->videoLayer()->winId() ) );@

                  and sadly what it looks like to me is that they are using the same method to insert the winID as I have(apart from adding that define before winid). So not really sure what else it might be. Could be a mplayer problem i guess so going to test it tonight to see if i get the same problems on a different machine.

                  Thanks for the quote on "-wid" even though I knew that already it will be really helpful for anyone trying to follow this forum post. Hopefully at some point I'll be able to solve it so it's a little more useful than completely useless :P

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andreyc
                    wrote on last edited by
                    #11

                    Ah, I did not read the line with -wid correctly in your code. Somehow I thought that you put the result of FindWindow as a parameter of -wid.

                    1 Reply Last reply
                    0
                    • I Offline
                      I Offline
                      ion_knight
                      wrote on last edited by
                      #12

                      lol you did actually it was me who made the mistake and still had my program independant method (that's the fromwinid method). Helps if i actually use the winid of the container not mplayer itself :P.

                      1 Reply Last reply
                      0
                      • I Offline
                        I Offline
                        ion_knight
                        wrote on last edited by
                        #13

                        Well sadly it looks like I can't get either way to work, but yea think the other method is meant to work in general and the implementation below is supposed to work with mplayer, but failing with application errors atm oh fun.

                        @ QWindow *container;

                        WId winid = container->winId();
                        //QWindow *container = QWindow::fromWinId(winid);
                        QWidget *program_start  = createWindowContainer(container);
                        
                        QString program;
                        program = "E:\\Downloads\\mplayer\\mplayer.exe";
                        
                        QStringList arguments;
                        arguments << "-wid" << QString::number(winid) << "E:\\Downloads\\BigBuckBunny_320x180.mp4";
                        
                        //QStringList arguments;
                        //arguments << "E:\\Downloads\\BigBuckBunny_320x180.mp4";
                        
                        QVBoxLayout *layout = new QVBoxLayout;
                        
                        QPushButton *button = new QPushButton("Test2");
                        QPushButton *button2 = new QPushButton("Test");
                        
                        
                        QProcess *m_process = new QProcess();
                        
                        m_process->setProgram(program);
                        m_process->setArguments(arguments);
                        
                        m_process->start();
                        

                        @

                        Any advice on either method would be good really.

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          andreyc
                          wrote on last edited by
                          #14

                          I think you don't need to create a QWindow (BTW, in your code above you don't allocate it)
                          Try to use QWidget and get winId() from it.

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andreyc
                            wrote on last edited by
                            #15

                            This code works on Linux.
                            I created a simple QMainWindow app added QWidget on it in designer and couple QPushButton to start and stop the player.
                            This is a
                            @
                            void MainWindow::on_playButton_clicked()
                            {
                            if (m_process == nullptr) {
                            ui->playButton->setEnabled(false);
                            ui->stopButton->setEnabled(true);
                            QStringList arguments;
                            arguments << "-wid" << QString::number(ui->widget->winId())
                            << m_fileName;
                            m_process = new QProcess();
                            m_process->setProgram(m_player);
                            m_process->setArguments(arguments);
                            m_process->start();
                            }
                            }

                            void MainWindow::on_stopButton_clicked()
                            {
                            if (m_process != nullptr) {
                            ui->playButton->setEnabled(true);
                            ui->stopButton->setEnabled(false);
                            delete m_process;
                            m_process = nullptr;
                            }
                            }
                            @

                            1 Reply Last reply
                            0
                            • I Offline
                              I Offline
                              ion_knight
                              wrote on last edited by
                              #16

                              Well that's kind of weird (but hopeful) I can hear the audio and the widget appears but it's completely green(which is a good sign as it's the same green you get when moving an mplayer screen) , did also try a widget within a widget but got the same result just without the green widget only problem was I couldn't call "program_start->show();" otherwise just crashed on runtime with memory errors. Wish I was doing it on Linux would make my life so much easier :P, pretty sure this is a windows specific problem though but gonna play with a linux implementation anyway as it's a handy thing to know. Hopefully I can resolve these issues and get back to actually coding something, instead of banging my head against a wall :P.

                              @ //QWindow *container = null_ptr;

                              // WId winid = container->winId();
                              //QWindow *container = QWindow::fromWinId(winid);
                              //QWidget *program_start = new QWidget();
                              WId winid = this->winId();
                              QString program;

                              program = "E:\\Downloads\\mplayer\\mplayer.exe";
                              
                              QStringList arguments;
                              arguments << "-wid" << QString::number(winid) << "E:\\Downloads\\BigBuckBunny_320x180.mp4";
                              
                              //QStringList arguments;
                              //arguments << "E:\\Downloads\\BigBuckBunny_320x180.mp4";
                              
                              QVBoxLayout *layout = new QVBoxLayout;
                              
                              QPushButton *button = new QPushButton("Test2");
                              QPushButton *button2 = new QPushButton("Test");
                              
                              
                              QProcess *m_process = new QProcess(this);
                              
                              m_process->setProgram(program);
                              m_process->setArguments(arguments);
                              // program_start->show();
                              this->show();
                              m_process->start();
                              

                              @

                              1 Reply Last reply
                              0
                              • I Offline
                                I Offline
                                ion_knight
                                wrote on last edited by
                                #17

                                After a bit of playing with mplayer I have found it's because you also need to change in the config and change the default render method. config listed below

                                @# Write your default config options here!
                                #-wid 1234
                                #vo=directx
                                #vo=direct3d
                                vo=gl
                                #vo=gl_tiled
                                #vo=sdl@

                                you can't use directx otherwise you'll just see a green screen. Currently using opengl and it seems the fastest for this usage.

                                1 Reply Last reply
                                0
                                • jsulmJ jsulm referenced this topic on

                                • Login

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