[Interest] QThread and QPixmap::grabWindow()

Alex Malyushytskyy alexmalvtk at gmail.com
Sat Aug 10 01:18:46 CEST 2013


I guess my suggestion was not clear.


Create a slot where:
- QPixmap::grabWindow( QApplication::desktop()->winId() );

will be called.

- QPixmap is converted to QImage
-  Signal and slot may contain reference to the QImage as a parameter,
so you can access filled QImage after signal is emitted..

Connect custom signal from your threat to this slot using
BlockingQueuedConnection.

This will insure that your thread will wait until QImage is filled.

Since QImage is device independent you may use it in other than GUI threads.



Finally emit such signal instead instead of the code you posted.



Keep in mind that it probably there is no any reason to take screenshots
too often,
especially when your target is desktop - you can't really make sure it is
taken the moment you want it.
GUI threat may be already doing something so you would have to wait.
And since only GUI thread has to do it, it might make sense to have only 1
copy of screenshot which could be accessed by multiple threads.

So I suggest to store it as QImage and the mentioned above slot should
check the time pixmap was taken and current time , update it if it is
needed ( if that was done at least 1sec ago?).


Hope this helps,

    Alex





On Thu, Aug 8, 2013 at 2:36 PM, Alexander Syvak <alexander.svk at gmail.com>wrote:

> It's done as following, the thread wrapper (the class holding the QThread
> object and the pointer to be moved into the thread-worker) connects the
> class to be moved into the worker-thread with the main thread slot
> 'make_screenshot(pointer to the class which emits the signal)'. The main
> thread slot puts into the pointer the made screenshot.
> However, pictures are received are half damaged.
> When there's only one thread worker, the screenshots are OK.
> Any variants?
>
>
> 2013/8/8 Rainer Wiesenfarth <Rainer_Wiesenfarth at trimble.com>
>
>> Am 08.08.2013 00:11, schrieb Alexander Syvak:
>>
>>> [...]
>>>
>>>     auto const this_thread = this->thread ();
>>>     moveToThread (QApplication::instance()->**thread());
>>>
>>>     screenshot = QPixmap::grabWindow( QApplication::desktop()->**winId()
>>> );
>>>     moveToThread(this_thread);
>>> [...]
>>>
>>
>> I think you might have a problem in understanding threads and the thread
>> context as used in Qt. moveToThread() does NOT change the thread the
>> current code runs in! It only changes the target for events sent to this
>> object.
>>
>> In your example, the thread that executes this->thread() is identical to
>> the one that executes QPixmap::grabWindow().
>>
>> You will have to implement synchronization between the main (GUI) thread
>> and your workers. The workers send an event to the main thread each time
>> they need a screenshot, the main thread picks up the event, takes the
>> screenshot and sends an event back to the "caller". The addressed worker
>> thread then picks up this event and processes the screenshot.
>>
>> If you have only one worker, you might wrap up your processing in a
>> single method and use QtConcurrent::run().
>>
>> Best Regards / Mit freundlichen Grüßen
>> Rainer Wiesenfarth
>>
>> --
>> Software Engineer | Trimble Imaging Division
>> Rotebühlstraße 81 | 70178 Stuttgart | Germany
>> Office +49 711 22881 0 | Fax +49 711 22881 11
>> http://www.trimble.com/**imaging/ <http://www.trimble.com/imaging/> |
>> http://www.inpho.de/
>>
>> Trimble Germany GmbH, Am Prime Parc 11, 65479 Raunheim
>> Eingetragen beim Amtsgericht Darmstadt unter HRB 83893,
>> Geschäftsführer: Dr. Frank Heimberg, Hans-Jürgen Gebauer
>>
>>
>> _______________________________________________
>> Interest mailing list
>> Interest at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/interest
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130809/bc7d9ea0/attachment.html>


More information about the Interest mailing list