Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, December 2006
Problem with QThread and QProcess


Message 1 in thread

Hi everyone,

i have a GUI app from which i want to exexcute binaries. So i create a QThread in order to start a QProcess executing the binary so that the GUI does not freeze. Unfortunately nothing seems to happen i.e. the process is supposed to create a log file which usually takes around 1 sec, but no file is created. Here's my code so far:

QStringList args;
args.append("--script ");
args.append(_script);
QProcess *_proc = new QProcess();
_proc->start(_plinkBin, args);

while(!_proc->waitForFinished())
{
	if(_area)
		_area->append(_proc->readLine());	
}

Where _area is a QTextEdit and _script is a QString. This method is called from my QThread class from within the run() method.

Thanks in advance!
Chris



Christian Rengstl M.A.
Klinik und Poliklinik fÃr Innere Medizin II
Kardiologie - Forschung
UniversitÃtsklinikum Regensburg
B3 1.388
Franz-Josef-Strauss-Allee 11
93053 Regensburg
Tel.: +49-941-944-7230


--
 [ signature omitted ] 

Message 2 in thread

On Tuesday 12 December 2006 10:10, Christian Rengstl wrote:
> Hi everyone,
>
> i have a GUI app from which i want to exexcute binaries. So i create a
> QThread in order to start a QProcess executing the binary so that the GUI
> does not freeze. Unfortunately nothing seems to happen i.e. the process is
> supposed to create a log file which usually takes around 1 sec, but no file
> is created. Here's my code so far:
>
> Where _area is a QTextEdit and _script is a QString. This method is called
> from my QThread class from within the run() method.

See http://doc.trolltech.com/4.2/threads.html#qobject-reentrancy:

"Although QObject is reentrant, the GUI classes, notably QWidget and all its 
subclasses, are not reentrant. They can only be used from the main thread. As 
noted earlier, QCoreApplication::exec() must also be called from that thread.

In practice, the impossibility of using GUI classes in other threads than the 
main thread can easily be worked around by putting time-consuming operations 
in a separate worker thread and displaying the results on screen in the main 
thread when the worker thread is finished. This is the approach used for 
implementing the Mandelbrot and the Blocking Fortune Client example."


-- 
 [ signature omitted ] 

Message 3 in thread

(Moving this back to qt-interest)

On Tuesday 12 December 2006 11:09, you wrote:
> The thing is that my GUI runs in the main thread  and from the GUI i start
> a thread that itself starts a QProcess in order to execute the binary.

Yes, and that's the problem:

> >> Where _area is a QTextEdit and _script is a QString. This method is
> >> called from my QThread class from within the run() method.

You are calling a function on a GUI class from a thread that is not the GUI 
thread. You cannot call QTextEdit::append() the way you are now.

-- 
 [ signature omitted ] 

Message 4 in thread

(Moved to qt-interest again, please make sure your replies go to the mailing 
list)

On Tuesday 12 December 2006 11:51, Christian Rengstl wrote:
> Ohhhh, okay now i see. Thanks for this hint!
>
>
> Christian Rengstl M.A.
> Klinik und Poliklinik fÃr Innere Medizin II
> Kardiologie - Forschung
> UniversitÃtsklinikum Regensburg
> B3 1.388
> Franz-Josef-Strauss-Allee 11
> 93053 Regensburg
> Tel.: +49-941-944-7230
>
> >>> Bradley T Hughes <bhughes@xxxxxxxxxxxxx> schrieb am Di, Dez 12, 2006 um
> >>> 11:18
>
> AM in Nachricht <200612121118.59859.bhughes@xxxxxxxxxxxxx>:
> > (Moving this back to qt-interest)
> >
> > On Tuesday 12 December 2006 11:09, you wrote:
> >> The thing is that my GUI runs in the main thread  and from the GUI i
> >> start a thread that itself starts a QProcess in order to execute the
> >> binary.
> >
> > Yes, and that's the problem:
> >> >> Where _area is a QTextEdit and _script is a QString. This method is
> >> >> called from my QThread class from within the run() method.
> >
> > You are calling a function on a GUI class from a thread that is not the
> > GUI thread. You cannot call QTextEdit::append() the way you are now.
> >
> > --
> > Bradley T. Hughes - bhughes at trolltech.com
> > Trolltech ASA - Sandakervn. 116, P.O. Box 4332 Nydalen, 0402 Oslo, Norway
> >
> > --
> > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> > "unsubscribe" in the subject or the body.
> > List archive and information: http://lists.trolltech.com/qt-interest/

-- 
 [ signature omitted ] 

Message 5 in thread

On 12.12.06 10:10:27, Christian Rengstl wrote:
> i have a GUI app from which i want to exexcute binaries. So i create a QThread in order to start a QProcess executing the binary so that the GUI does not freeze. Unfortunately nothing seems to happen i.e. the process is supposed to create a log file which usually takes around 1 sec, but no file is created. Here's my code so far:

Why do you think you need a thread? QProcess already allows to run
"asynchronously", all you have to do is use signals/slots to get
notified when the process is finished, instead of waiting for it.

Andreas

-- 
 [ signature omitted ] 

Message 6 in thread

> i have a GUI app from which i want to exexcute binaries. So i create
> a QThread in order to start a QProcess executing the binary so that 
> the GUI does not freeze. Unfortunately nothing seems to happen i.e. 

I don't understand why you are using a QThread ... you could just forget 
about the QThread, use QProcess directly and instead of using 
"waitForFinished()" you could connect to  "finished(int, 
QProcess::ExitStatus)". This way your GUI won't freeze as well.

<snip> 

> while(!_proc->waitForFinished())
> {
>    if(_area)
>       _area->append(_proc->readLine()); 
> }
> Where _area is a QTextEdit and _script is a QString. This method is 
> called from my QThread class from within the run() method.

And there is your problem. If I understood correctly, you are calling the 
above code from within a QThread. You CANNOT use QTextEdit from diffrent 
thread but your GUI thread! If you try it the way I mentioned above, you 
won't have this problem anyways ;-)

Regards,
Malte

--
 [ signature omitted ] 

Message 7 in thread

Thanks for all your answers. I fixed it by using signals in the thread returning the output of the qprocess.


Christian Rengstl M.A.
Klinik und Poliklinik fÃr Innere Medizin II
Kardiologie - Forschung
UniversitÃtsklinikum Regensburg
B3 1.388
Franz-Josef-Strauss-Allee 11
93053 Regensburg
Tel.: +49-941-944-7230


>>> Malte Witt <malte.witt@xxxxxxxxxxxxx> schrieb am Mi, Dez 13, 2006 um  9:27 AM
in Nachricht
<OF8D5FB991.D6534F56-ONC1257243.002DD207-C1257243.002E76B6@xxxxxxxxxxxxx>:
>>  i have a GUI app from which i want to exexcute binaries. So i create
>> a QThread in order to start a QProcess executing the binary so that 
>> the GUI does not freeze. Unfortunately nothing seems to happen i.e. 
> 
> I don't understand why you are using a QThread ... you could just forget 
> about the QThread, use QProcess directly and instead of using 
> "waitForFinished()" you could connect to  "finished(int, 
> QProcess::ExitStatus)". This way your GUI won't freeze as well.
> 
> <snip> 
> 
>> while(!_proc- >waitForFinished())
>> {
>>    if(_area)
>>       _area- >append(_proc- >readLine()); 
>> }
>> Where _area is a QTextEdit and _script is a QString. This method is 
>> called from my QThread class from within the run() method.
> 
> And there is your problem. If I understood correctly, you are calling the 
> above code from within a QThread. You CANNOT use QTextEdit from diffrent 
> thread but your GUI thread! If you try it the way I mentioned above, you 
> won't have this problem anyways ;- )
> 
> Regards,
> Malte
> 
> --
> To unsubscribe -  send a mail to qt- interest- request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt- interest/

--
 [ signature omitted ] 

Message 8 in thread

On 13.12.06 09:36:13, Christian Rengstl wrote:
> Thanks for all your answers. I fixed it by using signals in the thread returning the output of the qprocess.

Hmm, I'm interested in why you didn't throw away the QThread and use the
QProcess' signals directly?

Andreas

-- 
 [ signature omitted ] 

Message 9 in thread

The reason is this sentence about waitForStarted(), waitForFinished(), ... from the docs:
Calling these functions from the main thread (the thread that calls QApplication::exec()) may cause your user interface to freeze

Maybe i just understood it wrong, but the way i understand is that calling these methods from the GUI could cause it to freeze.


Christian Rengstl M.A.
Klinik und Poliklinik fÃr Innere Medizin II
Kardiologie - Forschung
UniversitÃtsklinikum Regensburg
B3 1.388
Franz-Josef-Strauss-Allee 11
93053 Regensburg
Tel.: +49-941-944-7230


>>> Andreas Pakulat <apaku@xxxxxx> schrieb am Mi, Dez 13, 2006 um 11:51 AM in
Nachricht <20061213105144.GD7858@xxxxxxxxxxxxxxxxxxxxxxxxxxx>:
> On 13.12.06 09:36:13, Christian Rengstl wrote:
>> Thanks for all your answers. I fixed it by using signals in the thread 
> returning the output of the qprocess.
> 
> Hmm, I'm interested in why you didn't throw away the QThread and use the
> QProcess' signals directly?
> 
> Andreas


--
 [ signature omitted ] 

Message 10 in thread

On 13.12.06 13:51:04, Christian Rengstl wrote:
> The reason is this sentence about waitForStarted(), waitForFinished(), ... >from the docs:
> Calling these functions from the main thread (the thread that calls QApplication::exec()) may cause your user interface to freeze
> 
> Maybe i just understood it wrong, but the way i understand is that calling these methods from the GUI could cause it to freeze.

Right, and as I told you before you don't need either of these to have
QProcess run asynchronously (i.e. without freezing the gui). Just
connect the processFinished signal to a slot in your class and in that
slot read the output from the QProcess.

There's no need for giving yourself the QThread headache just to not
have a freezing GUI.

Andreas

-- 
 [ signature omitted ] 

Message 11 in thread

> The reason is this sentence about waitForStarted(), 
> waitForFinished(), ... from the docs:
> Calling these functions from the main thread (the thread that calls 
> QApplication::exec()) may cause your user interface to freeze
> 
> Maybe i just understood it wrong, but the way i understand is that 
> calling these methods from the GUI could cause it to freeze.

That'd defenitely true - it will block/freeze your GUI, BUT you don't have 
to call waitForFinished() if you connect your own slot to finished() 
signal of QProcess.

Try it like this:

- Create your QProcess
- connect finished() signal with your own slot
- start qprocess
- be happy ;-)

It's a different approach, but you save a QThread and all the trouble that 
comes with multithreading!

Regards,
Malte

--
 [ signature omitted ]