Help on PyQt4 QProcess

E

Edgar Fuentes

Dear friends,

I need execute an external program from a gui using PyQt4, to avoid
that hang the main thread, i must connect the signal "finished(int)"
of a QProcess to work properly.

for example, why this program don't work?

from PyQt4.QtCore import QProcess
pro = QProcess() # create QProcess object
pro.connect(pro, SIGNAL('started()'), lambda
x="started":print(x)) # connect
pro.connect(pro, SIGNAL("finished(int)"), lambda
x="finished":print(x))
pro.start('python',['hello.py']) # star hello.py program
(contain print("hello world!"))
timeout = -1
pro.waitForFinished(timeout)
print(pro.readAllStandardOutput().data())

output:

started
0
b'hello world!\n'

see that not emit the signal finished(int)

I'm using Python 3.2 and PyQt 4.8.4 under winxp 32bit.


best regards,
 
P

Phil Thompson

Dear friends,

I need execute an external program from a gui using PyQt4, to avoid
that hang the main thread, i must connect the signal "finished(int)"
of a QProcess to work properly.

for example, why this program don't work?

from PyQt4.QtCore import QProcess
pro = QProcess() # create QProcess object
pro.connect(pro, SIGNAL('started()'), lambda
x="started":print(x)) # connect
pro.connect(pro, SIGNAL("finished(int)"), lambda
x="finished":print(x))
pro.start('python',['hello.py']) # star hello.py program
(contain print("hello world!"))
timeout = -1
pro.waitForFinished(timeout)
print(pro.readAllStandardOutput().data())

output:

started
0
b'hello world!\n'

see that not emit the signal finished(int)

Yes it is, and your lambda slot is printing "0" which is the return code
of the process.

Phil
 
E

Edgar Fuentes

Dear friends,
I need execute an external program from a gui using PyQt4, to avoid
that hang the main thread, i must connect the signal "finished(int)"
of a QProcess to work properly.
for example, why this program don't work?
   from PyQt4.QtCore import QProcess
   pro = QProcess() # create QProcess object
   pro.connect(pro, SIGNAL('started()'), lambda
x="started":print(x))        # connect
   pro.connect(pro, SIGNAL("finished(int)"), lambda
x="finished":print(x))
   pro.start('python',['hello.py'])        # star hello.py program
(contain print("hello world!"))
   timeout = -1
   pro.waitForFinished(timeout)
   print(pro.readAllStandardOutput().data())

   started
   0
   b'hello world!\n'
see that not emit the signal finished(int)

Yes it is, and your lambda slot is printing "0" which is the return code
of the process.

Phil

Ok, but the output should be:

started
b'hello world!\n'
finished

no?.

thanks Phil
 
C

Carl Banks

Dear friends,
I need execute an external program from a gui using PyQt4, to avoid
that hang the main thread, i must connect the signal "finished(int)"
of a QProcess to work properly.
for example, why this program don't work?
   from PyQt4.QtCore import QProcess
   pro = QProcess() # create QProcess object
   pro.connect(pro, SIGNAL('started()'), lambda
x="started":print(x))        # connect
   pro.connect(pro, SIGNAL("finished(int)"), lambda
x="finished":print(x))
   pro.start('python',['hello.py'])        # star hello.py program
(contain print("hello world!"))
   timeout = -1
   pro.waitForFinished(timeout)
   print(pro.readAllStandardOutput().data())

   started
   0
   b'hello world!\n'
see that not emit the signal finished(int)

Yes it is, and your lambda slot is printing "0" which is the return code
of the process.

Phil

Ok, but the output should be:

started
b'hello world!\n'
finished

no?.

thanks Phil

Two issues. First of all, your slot for the finished function does not have the correct prototype, and it's accidentally not throwing an exception because of your unnecessary use of default arguments. Anyway, to fix that, try this:

pro.connect(pro, SIGNAL("finished(int)"), lambda v, x="finished":print(x))

Notice that it adds an argument to the lambda (v) that accepts the int argument of the signal. If you don't have that argument there, the int argument goes into x, which is why Python prints 0 instead of "finished".

Second, processess run asynchrously, and because of line-buffering, IO can output asynchronously, and so there's no guarantee what order output occurs.. You might try calling the python subprocess with the '-u' switch to force unbuffered IO, which might be enough to force synchronous output (depending on how signal/slot and subprocess semantics are implemented).


Carl Banks
 
E

Edgar Fuentes

On Fri, 19 Aug 2011 10:15:20 -0700 (PDT), Edgar Fuentes
Dear friends,
I need execute an external program from a gui using PyQt4, to avoid
that hang the main thread, i must connect the signal "finished(int)"
of a QProcess to work properly.
for example, why this program don't work?
   from PyQt4.QtCore import QProcess
   pro = QProcess() # create QProcess object
   pro.connect(pro, SIGNAL('started()'), lambda
x="started":print(x))        # connect
   pro.connect(pro, SIGNAL("finished(int)"), lambda
x="finished":print(x))
   pro.start('python',['hello.py'])        # star hello..py program
(contain print("hello world!"))
   timeout = -1
   pro.waitForFinished(timeout)
   print(pro.readAllStandardOutput().data())
output:
   started
   0
   b'hello world!\n'
see that not emit the signal finished(int)
Yes it is, and your lambda slot is printing "0" which is the return code
of the process.
Phil
Ok, but the output should be:
    started
    b'hello world!\n'
    finished

thanks Phil

Two issues.  First of all, your slot for the finished function does nothave the correct prototype, and it's accidentally not throwing an exception because of your unnecessary use of default arguments.  Anyway, to fix that, try this:

pro.connect(pro, SIGNAL("finished(int)"), lambda v, x="finished":print(x))

Notice that it adds an argument to the lambda (v) that accepts the int argument of the signal.  If you don't have that argument there, the int argument goes into x, which is why Python prints 0 instead of "finished".

Second, processess run asynchrously, and because of line-buffering, IO can output asynchronously, and so there's no guarantee what order output occurs.  You might try calling the python subprocess with the '-u' switch to force unbuffered IO, which might be enough to force synchronous output (depending on how signal/slot and subprocess semantics are implemented).

Carl Banks

Thanks Carl, your intervention was very helpful for me, this solve my
semantic error. I need to study more about signal/slots and process.
 
P

Phil Thompson

On Aug 19, 1:56 pm, Phil Thompson
 wrote:
On Fri, 19 Aug 2011 10:15:20 -0700 (PDT), Edgar Fuentes
Dear friends,
I need execute an external program from a gui using PyQt4, to avoid
that hang the main thread, i must connect the signal
"finished(int)"
of a QProcess to work properly.
for example, why this program don't work?
   from PyQt4.QtCore import QProcess
   pro = QProcess() # create QProcess object
   pro.connect(pro, SIGNAL('started()'), lambda
x="started":print(x))        # connect
   pro.connect(pro, SIGNAL("finished(int)"), lambda
x="finished":print(x))
   pro.start('python',['hello.py'])        # star hello.py program
(contain print("hello world!"))
   timeout = -1
   pro.waitForFinished(timeout)
   print(pro.readAllStandardOutput().data())

   started
   0
   b'hello world!\n'
see that not emit the signal finished(int)
Yes it is, and your lambda slot is printing "0" which is the return
code
of the process.

Ok, but the output should be:
    started
    b'hello world!\n'
    finished

thanks Phil

Two issues.  First of all, your slot for the finished function does not
have the correct prototype, and it's accidentally not throwing an
exception because of your unnecessary use of default arguments.  Anyway,
to fix that, try this:

pro.connect(pro, SIGNAL("finished(int)"), lambda v,
x="finished":print(x))

Notice that it adds an argument to the lambda (v) that accepts the int
argument of the signal.  If you don't have that argument there, the int
argument goes into x, which is why Python prints 0 instead of "finished".

Second, processess run asynchrously, and because of line-buffering, IO
can output asynchronously, and so there's no guarantee what order output
occurs.  You might try calling the python subprocess with the '-u' switch
to force unbuffered IO, which might be enough to force synchronous output
(depending on how signal/slot and subprocess semantics are implemented).

Carl Banks

Thanks Carl, your intervention was very helpful for me, this solve my
semantic error. I need to study more about signal/slots and process.

In which case you should look at the modern, Pythonic connection syntax
rather than the old one...

pro.started.connect(lambda: print("started"))
pro.finished.connect(lambda: print("finished"))

Phil
 
E

Edgar Fuentes

56 pm, Phil Thompson
 wrote:
On Fri, 19 Aug 2011 10:15:20 -0700 (PDT), Edgar Fuentes
Dear friends,
I need execute an external program from a gui using PyQt4, to avoid
that hang the main thread, i must connect the signal
"finished(int)"
of a QProcess to work properly.
for example, why this program don't work?
   from PyQt4.QtCore import QProcess
   pro = QProcess() # create QProcess object
   pro.connect(pro, SIGNAL('started()'), lambda
x="started":print(x))        # connect
   pro.connect(pro, SIGNAL("finished(int)"), lambda
x="finished":print(x))
   pro.start('python',['hello.py'])        # star hello.py program
(contain print("hello world!"))
   timeout = -1
   pro.waitForFinished(timeout)
   print(pro.readAllStandardOutput().data())
output:
   started
   0
   b'hello world!\n'
see that not emit the signal finished(int)
Yes it is, and your lambda slot is printing "0" which is the return
code
of the process.
Phil
Ok, but the output should be:
    started
    b'hello world!\n'
    finished
no?.
thanks Phil
Two issues.  First of all, your slot for the finished function does not
have the correct prototype, and it's accidentally not throwing an
exception because of your unnecessary use of default arguments.  Anyway,
to fix that, try this:
pro.connect(pro, SIGNAL("finished(int)"), lambda v,
x="finished":print(x))
Notice that it adds an argument to the lambda (v) that accepts the int
argument of the signal.  If you don't have that argument there, the int
argument goes into x, which is why Python prints 0 instead of
"finished".
Second, processess run asynchrously, and because of line-buffering, IO
can output asynchronously, and so there's no guarantee what order output
occurs.  You might try calling the python subprocess with the '-u' switch
to force unbuffered IO, which might be enough to force synchronous output
(depending on how signal/slot and subprocess semantics are
implemented).
Carl Banks
Thanks Carl, your intervention was very helpful for me, this solve my
semantic error. I need to study more about signal/slots and process.

In which case you should look at the modern, Pythonic connection syntax
rather than the old one...

    pro.started.connect(lambda: print("started"))
    pro.finished.connect(lambda: print("finished"))

Phil

Pythonic, great!, more straightforward.

Thanks again Phil and Carl.

best regards,

Edgar Fuentes
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top