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. Setting focus to a running QProcess
Forum Updated to NodeBB v4.3 + New Features

Setting focus to a running QProcess

Scheduled Pinned Locked Moved General and Desktop
8 Posts 3 Posters 9.9k 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.
  • V Offline
    V Offline
    vezprog
    wrote on 17 May 2012, 14:27 last edited by
    #1

    So I am having trouble figuring out a way to bring an application to the forefront for a QProcess. My application is a System Dock that allows users to drag executables from their local PC, and add it to the dock. When adding to the dock, it creates a button with the object name as the directory location of the application added.

    The thread is created in the Widget window like so:
    @
    /*
    // app button clicked (slot)
    */
    void Widget::appButtonClicked()
    {
    // get sender of the signal
    QToolButton *button = qobject_cast<QToolButton *>(sender());

    // format the exe location
    QString temp = button->objectName();
    temp = temp.replace("/", "\\\\");
    temp = "\"" + temp + "\"";
    
    // start the new process
    newProcess = new Process();
    newProcess->exeLocation = temp;
    newProcess->start();
    

    }
    @

    On the button push, I run a QProcess in a thread so that I don't freeze the GUI and allows other processes to be opened as well:
    @
    #include "process.h"

    /*
    // cc
    */
    Process::Process(QObject *parent) :
    QThread(parent)
    {
    exeLocation = "";
    }

    /*
    // class execution loop
    */
    void Process::run()
    {
    // start the proccess
    QProcess process;
    process.start(exeLocation);
    process.waitForFinished(-1);
    }
    @

    What I also am going to do is append the thread to a QList<QThread *> on creation so that I know which process's are active at all times.

    But, I am looking to change the code for button press signal to check if the application has already been opened. As in, I only want one instance of the application running at a time. If it is already running, then I want bring that process to focus / bring the screen to the front.

    Is there any that there is a way to do this in Qt, or is this going to be platform specific? I am currently developing on Windows 7.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mlong
      wrote on 17 May 2012, 14:36 last edited by
      #2

      Bringing the process to the front will be a system-specific thing, I believe.

      Also, there's no need to run your QProcesses in separate threads. You can use "QProcess:startDetached()":/doc/qt-4.8/qprocess.html#startDetached to run the process without blocking, and you can connect to the QProcess's "finished()":/doc/qt-4.8/qprocess.html#finished signal to catch when the process ends.

      Software Engineer
      My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

      1 Reply Last reply
      0
      • V Offline
        V Offline
        vezprog
        wrote on 17 May 2012, 14:59 last edited by
        #3

        Ah, very nice. Thanks! I have just read this snipet actually that I am going to try to do using the process id:
        http://www.qtcentre.org/threads/42554-QProcess-and-focus-problem

        So I will save my QProcess to a list when created, then to bring it to focus ill have to search the list on click and compare the process id's, then bring it to focus.

        I think it may work :)

        1 Reply Last reply
        0
        • A Offline
          A Offline
          aabc
          wrote on 17 May 2012, 15:15 last edited by
          #4

          Gread idea

          1 Reply Last reply
          0
          • V Offline
            V Offline
            vezprog
            wrote on 17 May 2012, 15:17 last edited by
            #5

            Actually, for some reason, the finished signal is not working with the startDetached() call after I create it on the heap...very odd.

            @
            /*
            // app button clicked (slot)
            */
            void Widget::appButtonClicked()
            {
            // get sender of the signal
            QToolButton *button = qobject_cast<QToolButton *>(sender());

            // format the exe location
            QString temp = button->objectName();
            temp = temp.replace("/", "\\\\");
            temp = "\"" + temp + "\"";
            
            QProcess *exeprocess = new QProcess(this);
            connect(exeprocess, SIGNAL(finished(int)), this, SLOT(processFinished(int)));
            exeprocess->setObjectName(button->objectName());
            exeprocess->startDetached(temp);
            
            // append the process to the list
            processList.append(exeprocess);
            

            }

            /*
            // process finished
            */
            void Widget::processFinished(int state)
            {
            // get sender of the signal
            QProcess *exitprocess = qobject_cast<QProcess *>(sender());

            // loop through the list and match the process id
            for (i=0;i<processList.size();i++){
                if (processList[i]->pid() == exitprocess->pid()){
                    // delete the icon
                    delete (processList.takeAt(i));
                    return;
                }
            }
            

            }
            @

            1 Reply Last reply
            0
            • A Offline
              A Offline
              aabc
              wrote on 17 May 2012, 15:17 last edited by
              #6

              That is odd...

              1 Reply Last reply
              0
              • V Offline
                V Offline
                vezprog
                wrote on 17 May 2012, 16:20 last edited by
                #7

                Found this on another thread:

                QProcess::startDetached() [doc.qt.nokia.com] are static methods and therefore never send signals.

                1 Reply Last reply
                0
                • V Offline
                  V Offline
                  vezprog
                  wrote on 17 May 2012, 18:02 last edited by
                  #8

                  So I have somewhat figured it out...and I am kind of stuck but I think I know why. Here's what I did.

                  @
                  /*
                  // app button clicked (slot)
                  */
                  void Widget::appButtonClicked()
                  {
                  // get sender of the signal
                  QToolButton *button = qobject_cast<QToolButton *>(sender());

                  for (i=0;i<processList.size();i++){
                      // check if the process is already open
                      QStringList objectNameSplit;
                      objectNameSplit = QString(processList[i]->objectName()).split("*");
                      if (objectNameSplit.size() > 1){
                          if (objectNameSplit[0] == button->objectName()){
                              Q_PID pidQt = (Q_PID)QString(objectNameSplit[1]).toInt();
                              EnumWindows(EnumWindowsProc, (LPARAM)pidQt);  // get the window handles
                              return;
                          }
                      }
                  }
                  
                  // format the exe location
                  QString temp = button->objectName();
                  temp = temp.replace("/", "\\\\");
                  temp = "\"" + temp + "\"";
                  
                  QString tempWd;
                  QStringList tempArgs;
                  qint64 tempPid;
                  
                  // start the process
                  QProcess *exeprocess = new QProcess();
                  exeprocess->startDetached(temp, tempArgs, tempWd, &tempPid);
                  
                  // set the object name for future reference
                  QString objectName = button->objectName() + "*" + QVariant(tempPid).toString();
                  exeprocess->setObjectName(objectName);
                  
                  // append the process to the list
                  processList.append(exeprocess);
                  

                  }
                  @

                  When I started the process, I got the process ID. Next if the application is already open, I used the windows API EnumWindows which loops through each window until call false within the callback functions.

                  Here is the standard windows api call back function:
                  @
                  /*
                  // window enumeration callback (GLOBAL FUNCTION NOT IN CLASS)
                  */
                  BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
                  {
                  // get the window process ID
                  DWORD searchedProcessId = (DWORD)lParam;
                  DWORD windowProcessId = 0;
                  GetWindowThreadProcessId(hWnd,&windowProcessId);

                  // check the process id match
                  if (windowProcessId == searchedProcessId){
                      ShowWindow(hWnd, SW_SHOW);
                      return FALSE;
                  }
                  return TRUE;  //continue enumeration
                  

                  }
                  @

                  where I pass in the process ID...If it matches, then I return false and stop the enumeration loop. Unfortunately the ShowWindow function fails to bring the window to the foreground...

                  Question, when QProcess starts, does it handle a point to the parent process? or the child process created by the QProcess? Because I might be trying to bring the dock app to the foreground instead of the opened exectuable.

                  1 Reply Last reply
                  0

                  1/8

                  17 May 2012, 14:27

                  • Login

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