Page 1 of 2 12 LastLast
Results 1 to 20 of 21

Thread: QProcess disconnect trouble

  1. #1
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default QProcess disconnect trouble

    Hello,

    I'm creating a simple watchdog program that watches a process. If the process exits or crashes I want to restart the process. My dialog has a program exe and working directory line edits, for program selection, along with Start/Stop/Restart buttons. It has a QTimer for automatically restarting a crashed/exited program after N seconds.

    My program functions as a systray icon that provides message bubbles based on the status or any crash/exit events. So I have the QProcess signals connected like this in my dialog's constructor:
    Qt Code:
    1. process = new QProcess();
    2. connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleProcessError(QProcess::ProcessError)));
    3. connect(process, SIGNAL(finished(int, QProcess::ExitStatus )), this, SLOT(handleProcessFinish(int, QProcess::ExitStatus)));
    To copy to clipboard, switch view to plain text mode 

    When pushing the stop button, I want to kill the process with QProcess::kill(). When the process is killed, naturally, the handleProcessError slot gets called and I do not want this. I wanted to disable this by using:
    Qt Code:
    1. disconnect(process, SIGNAL(error(QProcess::ProcessError)), 0, 0);
    2. disconnect(process, SIGNAL(finished(int exitCode, QProcess::ExitStatus exitStatus)), 0,0);
    3. process->kill();
    To copy to clipboard, switch view to plain text mode 

    I've also tried calling:
    Qt Code:
    1. process->disconnect();
    2. process->kill();
    To copy to clipboard, switch view to plain text mode 
    in an attempt to blindly disconnect everything.

    It appears after calling these disconnect calls the error signal is not actually disconnected as I still get my message bubble popping up telling me that the program has crashed. Furthermore, my handleProcessError slot is designed to call my restart QTimer::start() so that the program will automatically restart.

    My hopes to disconnect it have failed and when the user clicks "Stop" I do not want the program to automatically restart. This has led me to deleting the QProcess object, and creating a new instance.

    Any ideas as to why the signals are not getting disconnected?

    Using Qt 4.5.1 with VS2008

    Thanks,
    Darryl

  2. #2
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QProcess disconnect trouble

    process->kill is provided as a absolutely last resort to try and kill a process that isn't responding. You shouldn't use it for normal operations. When the user presses 'Stop', send a signal to the process to quit normally, and then you will not get an error signal.

  3. The following user says thank you to squidge for this useful post:

    wally (6th April 2010)

  4. #3
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Thanks for the tip, I will try that out instead of using process->kill().

    That still does not, however, address the issue with the signals not being disconnected.

    Any ideas?

  5. #4
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QProcess disconnect trouble

    You can't write formal parameters in SIGNAL macro neither in connect nor in dosconnect. See program output in 'Output' window in Studio. Wrong calling of connect/disconnect writes there a message

  6. #5
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by fatjuicymole View Post
    process->kill is provided as a absolutely last resort to try and kill a process that isn't responding. You shouldn't use it for normal operations. When the user presses 'Stop', send a signal to the process to quit normally, and then you will not get an error signal.
    Actually, the documentation for QProcess::terminate() says that the "Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by calling kill()."

    So I would need to call kill to ensure that any application that is run by the WatchDog is terminated, on Windows at least.
    Last edited by wally; 5th April 2010 at 15:59. Reason: Added quote

  7. #6
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by borisbn View Post
    You can't write formal parameters in SIGNAL macro neither in connect nor in dosconnect. See program output in 'Output' window in Studio. Wrong calling of connect/disconnect writes there a message
    I haven't seen any problems in the output. I'm also not sure what you mean by formal parameters. Do you mean defining the variable name in the function like:
    Qt Code:
    1. SIGNAL(error(QProcess::ProcessError error))
    To copy to clipboard, switch view to plain text mode 
    I know that this will not work and the signals I have defined do not define the value "error" I know that the SIGNALS are connected as they will enter the slot. I corrected this error from my first post.

    Either way, calling process->disconnect() should disconnect all the sender object and all signals from all receiver objects and slots.

    I've even tried calling
    Qt Code:
    1. process->blockSignals(true);
    2. process->kill();
    3. process->blockSignals(false);
    To copy to clipboard, switch view to plain text mode 
    and my slots still get entered.

    Any one have any other ideas as to why my signals are not getting disconnected?
    Last edited by wally; 5th April 2010 at 16:48.

  8. #7
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    I think QtCentre's moving to a new host may have ruined the code tags in my initial post. So that everyone is clear:
    I've connected my signals to my process in the Dialog's constructor like this (and I have verified that they are connected):
    Qt Code:
    1. process = new QProcess();
    2. connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleProcessError(QProcess::ProcessError)));
    3. connect(process, SIGNAL(finished(int, QProcess::ExitStatus )), this, SLOT(handleProcessFinish(int, QProcess::ExitStatus)));
    To copy to clipboard, switch view to plain text mode 

    When pushing the stop button, I want to kill the process with QProcess::kill(). When the process is killed, naturally, the handleProcessError slot gets called and I do not want this. I wanted to disable this by using:
    Qt Code:
    1. disconnect(process, SIGNAL(error(QProcess::ProcessError)), 0, 0);
    2. disconnect(process, SIGNAL(finished(int exitCode, QProcess::ExitStatus)), 0,0);
    3. process->kill();
    To copy to clipboard, switch view to plain text mode 

    I've also tried calling:
    Qt Code:
    1. process->disconnect();
    2. process->kill();
    To copy to clipboard, switch view to plain text mode 
    in an attempt to blindly disconnect everything.

    the slots, handleProcessError and handleProcessFinish are still being called.
    Last edited by wally; 5th April 2010 at 16:47.

  9. #8
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by wally View Post
    Actually, the documentation for QProcess::terminate() says that the "Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by calling kill()."
    It depends on what your process does. If it has a systray icon, then it must have an event loop.

  10. The following user says thank you to squidge for this useful post:

    wally (6th April 2010)

  11. #9
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by fatjuicymole View Post
    It depends on what your process does. If it has a systray icon, then it must have an event loop.
    Understandable. But the QProcess that is running is not necessarily in the Systray. The program that calls the QProcess runs in the systray.

    Eitherway, the signals on the QProcess do not get disconnected. I tested connecting/disconnecting signals from other random objects (like a spinbox) and that works fine.

    I'm starting to think that the signals of a QProcess that has an active process cannot be disconnected while the process is still running.

  12. #10
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QProcess disconnect trouble

    Have you tried blockSignals ?

  13. #11
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Yup. See post #6

    Didn't work either.

  14. #12
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: QProcess disconnect trouble

    Maybe it's a windows/vs problem. You might try your app on Linux or do somethiing simple like the following to see if it works:

    I created a new GUI project with Qt Creator. Used your code in the MainWindow constructor to start a process (a php script that waits for input on stdin) and make connections, put a push button in the form, and created two slots:
    Qt Code:
    1. void MainWindow::on_pushButton_clicked(){
    2. disconnect(process,SIGNAL(error(QProcess::ProcessError)),0,0);
    3. process->kill();
    4. }
    5.  
    6. void MainWindow::handleProcessError(QProcess::ProcessError){
    7. qDebug() << process->errorString();
    8. }
    To copy to clipboard, switch view to plain text mode 
    It silently kills the process as shown. If I comment out the disconnect statement I get "Process crashed".

  15. The following user says thank you to norobro for this useful post:

    wally (6th April 2010)

  16. #13
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by norobro View Post
    Maybe it's a windows/vs problem. You might try your app on Linux or do somethiing simple like the following to see if it works:

    I created a new GUI project with Qt Creator. Used your code in the MainWindow constructor to start a process (a php script that waits for input on stdin) and make connections, put a push button in the form, and created two slots:
    Qt Code:
    1. void MainWindow::on_pushButton_clicked(){
    2. disconnect(process,SIGNAL(error(QProcess::ProcessError)),0,0);
    3. process->kill();
    4. }
    5.  
    6. void MainWindow::handleProcessError(QProcess::ProcessError){
    7. qDebug() << process->errorString();
    8. }
    To copy to clipboard, switch view to plain text mode 
    It silently kills the process as shown. If I comment out the disconnect statement I get "Process crashed".
    Hmmm.. Maybe it is a Windows problem since that's essentially what I tried.

    What version of Qt are you using?

    I will try this in Linux and/or QtCreator tomorrow.

  17. #14
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,641
    Thanks
    13
    Thanked 1,592 Times in 1,520 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QProcess disconnect trouble

    From post 7:
    Qt Code:
    1. disconnect(process, SIGNAL(error(QProcess::ProcessError)), 0, 0);
    2. disconnect(process, SIGNAL(finished(int exitCode, QProcess::ExitStatus)), 0,0);
    3. process->kill();
    To copy to clipboard, switch view to plain text mode 
    should not list the name of the int parameter at line 2. Perhaps this leaves the finished() signal still connected?

    Have you tried calling QProcess::terminate() (close gracefully) rather than QProcess::kill() (close with mallet)? I cannot imagine many Windows applications that ignore the WM_CLOSE message sent by terminate()

  18. The following user says thank you to ChrisW67 for this useful post:

    wally (6th April 2010)

  19. #15
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: QProcess disconnect trouble

    @wally - I'm using Qt 4.6.0 on Linux.

    I recently installed Qt 4.6.2 on my WinXP partiton and thought I'd give my simple app a try. I started "calc.exe" as a process and it ended silently. So disconnect worked here. Also it ended whether I used the "mallet" (TM ChrisW67) or terminate() .

  20. The following user says thank you to norobro for this useful post:

    wally (6th April 2010)

  21. #16
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by ChrisW67 View Post
    should not list the name of the int parameter at line 2. Perhaps this leaves the finished() signal still connected?
    I missed that. I guess that is what borisbn is alluding to in post #4.
    I put that slot in my app with the disconnect error and received a "no such slot" warning on the command line but the process still terminated without complaining.

  22. #17
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by wally View Post
    Yup. See post #6

    Didn't work either.
    In post #6, you re-enable directly after the kill. I was thinking of leaving the blocking active until the process is restarted, just in case some signals are in the event queue.

  23. The following user says thank you to squidge for this useful post:

    wally (6th April 2010)

  24. #18
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by fatjuicymole View Post
    In post #6, you re-enable directly after the kill. I was thinking of leaving the blocking active until the process is restarted, just in case some signals are in the event queue.
    Good point. I'll give that a shot.

  25. #19
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Quote Originally Posted by ChrisW67 View Post
    From post 7:
    Qt Code:
    1. disconnect(process, SIGNAL(error(QProcess::ProcessError)), 0, 0);
    2. disconnect(process, SIGNAL(finished(int exitCode, QProcess::ExitStatus)), 0,0);
    3. process->kill();
    To copy to clipboard, switch view to plain text mode 
    should not list the name of the int parameter at line 2. Perhaps this leaves the finished() signal still connected?

    Have you tried calling QProcess::terminate() (close gracefully) rather than QProcess::kill() (close with mallet)? I cannot imagine many Windows applications that ignore the WM_CLOSE message sent by terminate()
    Sorry that's a typo.. I don't have the name of the int parameter in my actual code.

    Regarding QProcess::terminate() vs. QProcess::kill(), the documentation says that "Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by calling kill()." Since, I'm using this program to run any possible program (including console applications) I will have to stick with the "mallet."

  26. #20
    Join Date
    Oct 2008
    Posts
    19
    Thanks
    6
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QProcess disconnect trouble

    Hello Everyone,

    Thank you for your help. The solution was my lack of awareness on what's happening when you call QProcess::kill(). I was trying to disconnect and then reconnect my signals by calling the connect immediately after calling kill() (like in post #6 where I call blockSignals before and after the kill call.

    I got the idea from fatjuicymole when he made a comment about my post #6. The process object was getting its signals reconnected before the external program had been terminated, since QProcess::kill() is not a synchronous function as it does not wait for the external function to be terminated.

    Now when I press the stop button, the slot stopProcess contains the following:
    Qt Code:
    1. disconnect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleProcessError(QProcess::ProcessError error)));
    2. disconnect(process, SIGNAL(finished(int, QProcess::ExitStatus )), this, SLOT(handleProcessFinish(int, QProcess::ExitStatus)));
    3. process->kill()
    To copy to clipboard, switch view to plain text mode 

    and then when I press the start button I reconnect the signals, e.g.:
    Qt Code:
    1. connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleProcessError(QProcess::ProcessError error)));
    2. connect(process, SIGNAL(finished(int, QProcess::ExitStatus )), this, SLOT(handleProcessFinish(int, QProcess::ExitStatus)));
    3. process->start(processName);
    To copy to clipboard, switch view to plain text mode 

    Thanks for your help everyone. The problem, like usual, ended up being the user. You learn something new everyday, even though you realize that you should've known it anyways

Similar Threads

  1. Disconnect slot when another is being connected
    By holst in forum Qt Programming
    Replies: 4
    Last Post: 8th September 2009, 09:49
  2. auto-disconnect in ~QGraphicsItem?
    By Lykurg in forum Qt Programming
    Replies: 2
    Last Post: 22nd July 2008, 08:14
  3. QTcpSocket not recognizing disconnect
    By jimroos in forum Qt Programming
    Replies: 3
    Last Post: 6th September 2007, 15:31
  4. How to make QHttp detect a disconnect?
    By gfunk in forum Qt Programming
    Replies: 1
    Last Post: 7th February 2007, 10:07
  5. qsqldatabase does not sense db disconnect
    By rburge in forum Qt Programming
    Replies: 0
    Last Post: 9th March 2006, 18:59

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.