QWebFrame print in a separate thread - multithreading

In my qt application I'm printing some large html code from a QWebFrame (mainFrame from a QWebPage). The html code contains some inline images and takes a while to be printed. Therefore I tried to put the print call into a separate thread to keep the gui responsive. As mentioned in the docs I thought this should be possible (Painting in threads).
But I still get the famous "QPixmap: It is not safe to use pixmaps outside the GUI thread"
My code to print is as follows:
void PrintDialog::paintRequested(QPrinter *printer) {
futureWatcher = new QFutureWatcher<void>();
QEventLoop q;
connect(futureWatcher, SIGNAL(finished()), &q, SLOT(quit()), Qt::UniqueConnection);
futureWatcher->setFuture(QtConcurrent::run(m_webPage->mainFrame(), &QWebFrame::print, printer));
q.exec();
}
To clarify all objects reside in the gui thread and the html gets generated before. The images get inlined like follows:
QImage image
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG");
QString html = "<img src=\"data:image/png;base64," + QString(ba.toBase64() + "\"/>";
So what am I doing wrong here? Is it that the QWebFrame internally uses some QPixmaps? Is there any solution for using the QWebFrame::print call in another thread?

Related

QT slot ignores while loop

Hello i'm try to create an application in QT with two thread but i have an issue :
I have a slot which run when i click on a pushbutton, and on the click it is supposed to change the name of a label called lValeur. But it change the text only once . Play help me i want to die ...
Here is the interesting part of my code :
void IHM::ClicButtonPer()
{
ButtonDem->setEnabled(true) ;
ButtonPer->setEnabled(false) ;
QString val ;
QTimer attendre ;
do
{
val = "Valeur : " ;
val += valeur ;
lValeur->setText(val) ;
attendre.start(1000) ;
while(attendre.isActive())
QApplication::processEvents() ;
if(ButtonPer->isEnabled())
break ;
}while(1) ;
}
and the connect function which execute the slot :
connect(ButtonPer, SIGNAL(clicked()), this, SLOT(ClicButtonPer())) ;
EDIT : that's multithreading because i have another thread which communicate with a TCP server
EDIT 2 :
connect(&m_timer, &QTimer::timeout, this, &IHM::on_timer);
this code just return me an error on &IHM::on_timer: cannot take the address of an rvalue of type 'void'
EDIT 3 (and the last one) :
I change connect(&m_timer, &QTimer::timeout, this, &IHM::on_timer);
with connect(&m_timer, SIGNAL(timeout()), this, SLOT(on_timer)) ;
Hope it will help someone
Very strange code. You need to learn the basics of programming. A timer is an entity that is not used in loops. Timers are usually used to repeatedly perform any action at predetermined equal intervals of time, but avoiding loops.
As for Qt and the QTimer class,
you need to create a QTimer object in a nonlocal scope. You can add the variable declaration to the IHM class header. In the simplest case, you also need to create a slot method.
class IHM : public...
{
...
private:
QTimer m_timer;
private slots:
void on_timer();
}
Then in the IHM cpp file you need to connect the timeout signal of the timer the slot. It can be done in the IHM constructor.
connect(&m_timer, &QTimer::timeout, this, &IHM::on_timer);
Put the code you need to be called repeatedly, to the slot body. Start and stop the timer wherever you need. For example:
void IHM::ClicButtonPer()
{
...
m_timer.start(1000);
}
void IHM::on_timer()
{
...
val += valeur;
lValeur->setText(val);
if(ButtonPer->isEnabled())
{
m_timer.stop();
}
}
As for the issue "it change the text only once" you need to read about Qt event loop. I can suggest
Signals & Slots
Threads_Events_QObjects.
You can also set a breakpoint to the line attendre.start(1000); then go down the steps and see what conditions are actually met.
Read also:
Threading Basics
Multithreading Technologies in Qt
Threads and QObjects

Running methods on different threads

simply put for a hw problem I need to run a bubble sort with 3 million elements. Do this normally. and then sort 4 individual lists (not nearly accurate but is all thats required) of 750000 elements each on a different thread.
I have a class that extends thread that simply prints a line if im running the thread. But I'm not sure how to get it to run a method
class thread extends Thread{
override def run()
{
// Displaying the thread that is running
println("Thread " + Thread.currentThread().getName() +" is running.")
}
}
//this for loop is in an object
for (c <- 1 to 5)
{
var th = new thread()
th.setName(c.toString())
th.start()
}
I am going to stick to answering the question you asked instead of trying to do your homework for you. I hope that is enough to get your started trying things out for yourself.
Recall that class names should be capitalized. That is probably a good thing to remember as your instructor will probably mark you down if you forget that during an exam.
class MyThread extends Thread{
override def run() = {
// Displaying the thread that is running
println("Thread " + Thread.currentThread().getName() +" is running.")
sort()
}
def sort() = {
// my sorting code here
}
}
If your instructor has not restricted you to using Thread only, I would also, similar to Luis Miguel Mejía Suárez, recommend Future instead of Thread. The syntax it uses is cleaner and preferable for how I would do multithreading in a professional setting. However, the choice may not be yours, so if your teacher says use Thread, use Thread.
For a primer on using Futures, see here.
Good luck!

For Geb Page Object, when is the static content block initialized?

When following the geb page object pattern, it is encouraged to create a static block of values that represent the elements on the page you are attempting to interface with. It is also good to create an at checker. Here is an example:
class SomePage extends Page{
static at = {$(By.xpath("some header or something")).displayed}
static content = {
element1 {$(By.xpath("some xpath1"))}
element2 {$(By.xpath("some xpath2"))}
//so on and so forth
}
}
Now I think I know the answer this question already but could not find the docs to back it up. I am pretty sure that the static content block is initialized once the "at checker" is called from a test script, but I am not sure. If what I am suggesting is true then that would mean something like this:
class SomePage extends Page{
static at = {$(By.xpath("some header or something")).displayed}
def someString
static content = {
element1 {$(By.xpath("//*[contains(text(), ${someString}"))}
element2 {$(By.xpath("some xpath2"))}
//so on and so forth
}
def setSomeString(String x){
this.someString = x
}
}
would be impractical right, or maybe even impossible? This is because in order to call "setSomeString" you need to call the at checker to tell the script which class to reference for method and variable calls, but if you call the at checker that means the static content becomes initialized.
Furthermore, if a webpage has content that doesn't show up upon initial arrival to the webpage, then you would not be able to put that content into the static content block either, since the at checker should be called as soon as you arrive on said webPage.
I am simply looking to confirm or deny that this is the behavior of geb page object. and I would be happy to hear answers describing best practice given the above situation.
also if there is a way to re-initialize the content, I would like to know that too, but I figure there is not.
A content definition is evaluated every time the result of the definition is requested:
def somePage = to SomePage //at checker is executed but the defintion for element1 isn't
somePage.element1 // closure defined for element1 is executed
somePage.element1 // and here again
// many lines of code which trigger additional content to show up on the page
somePage.element1 // closure defined for element1 is executed again

Cairo.Surface is leaking... How to debug it with Monodevelop?

I have many doubts related with Cairo and GTK# (that runs on .NET and Mono). I'm developing a GTK# application for MS Windows and Linux. I'm using GTK# 2.12 over .NET right now while I'm working on the application.
I've created a custom widget that uses Cairo.ImageSurface and Cairo.Context objects. As far as I know, I'm calling the Dispose method of every ImageSurface object and every Context object I create inside the widget code.
The widget responds to the "MouseOver" event, redrawing some parts of its DrawingArea.
The (first) problem:
almost every redrawing operation increases a little bit the amount of used memory. When the amount of used memory has increased 3 or 4 Kbytes the Monodevelop tracelog panel shows me the following message:
Cairo.Surface is leaking, programmer is missing a call to Dispose
Set MONO_CAIRO_DEBUG_DISPOSE to track allocation traces
The code that redraws a part of the widget is something like:
// SRGB is a custom struct, not from Gdk nor Cairo
void paintSingleBlock(SRGB color, int i)
{
using (Cairo.Context g = CairoHelper.Create (GdkWindow)) {
paintSingleBlock (g, color, i);
// We do this to avoid memory leaks. Cairo does not work well with the GC.
g.GetTarget().Dispose ();
g.Dispose ();
}
}
void paintSingleBlock(Cairo.Context g, SRGB color, int i)
{
var scale = Math.Pow (10.0, TimeScale);
g.Save();
g.Rectangle (x(i), y(i), w(i), h(i));
g.ClosePath ();
g.Restore ();
// We don't directly use stb.Color because in some cases we need more flexibility
g.SetSourceRGB (color.R, color.G, color.B);
g.LineWidth = 0;
g.Fill ();
}
The (second) problem: Ok, Monodevelop tells me that I should set MONO_CAIRO_DEBUG_DISPOSE to "track allocation traces" (In order to find the leak, I suppose)... but I don't know how to set this environment variable (I'm in Windows). I've tried using bash and executing something like:
MONO_CAIRO_DEBUG_DISPOSE=1 ./LightCreator.exe
But nothing appears in stderr nor stdout... (neither the messages that appear in the Monodevelop's applicationt trace panel). I also don't know how to get the debugging messages that see inside Monodevelop but without Monodevelop.
There's anyone with experience debugging GTK# or Cairo# memory leaks?
Thanks in advance.
Just wanted to throw my 2c here as I was fighting a similar leak problem in Cairo with surfaces. What I noticed is that if I create a Surface object the ReferenceCount property becomes 1 and if I attach this surface to a Context if becomes not 2 but 3. After disposing the Context the ReferenceCount comes back but to 2.
So I used some reflection to call the native methods in Cairo to decrease the ReferenceCount when I really want to Dispose a surface. I use this code:
public static void HardDisposeSurface (this Surface surface)
{
var handle = surface.Handle;
long refCount = surface.ReferenceCount;
surface.Dispose ();
refCount--;
if (refCount <= 0)
return;
var asm = typeof (Surface).Assembly;
var nativeMethods = asm.GetType ("Cairo.NativeMethods");
var surfaceDestroy = nativeMethods.GetMethod ("cairo_surface_destroy", BindingFlags.Static | BindingFlags.NonPublic);
for (long i = refCount; i > 0; i--)
surfaceDestroy.Invoke (null, new object [] { handle });
}
After using it I still have some leaks, but they seem to be related to other parts of Cairo and not with the surfaces.
I have found that a context created with CairoHelper.Create() will have a reference count of two.
A call to dispose reduces the reference count by one. Thus the context is never freed and keeps its target alive, too.
The native objects have manual reference counting, but the Gtk# wrappers want to keep a native object alive as long as there is a C# instance referencing it.
If a native object is created for a C# wrapper instance it does not need to increment the reference count because the wrapper instance 'owns' the native object and the reference count has the correct value of one. But if a wrapper instance is created for an already existing native object the reference count of the native object needs to be manually incremented to keep the object alive.
This is decided by a bool parameter when a wrapper instance is created.
Looking at the code for CairoHelper.Create() will show something like this
public static Cairo.Context Create(Gdk.Window window) {
IntPtr raw_ret = gdk_cairo_create(window == null ? IntPtr.Zero : window.Handle);
Cairo.Context ret = new Cairo.Context (raw_ret, false);
return ret;
}
Even though the native context was just created 'owned' will be false and the C# context will increment the reference count.
There is no fixed version right now, it can only be corrected by fixing the source and building Gtk# yourself.
CairoHelper is an auto-generated file, to change the parameter to true this attribute must be included in gdk/Gdk.metadata.
<attr path="/api/namespace/class[#cname='GdkCairo_']/method[#name='Create']/return-type" name="owned">true</attr>
Everything to build Gtk# can be found here.
https://github.com/mono/gtk-sharp

Java Graphics synchronisation issues drawing dynamic data

I have a program where I want to draw data that is constantly being updated (it is microhpone-line-data incidentally). The data is an 8000-length array of doubles, I don't really care about 'losing' data which is overriden between takes of the paint method.
In my naive implementation it became obvous that there's synchronisation issues, where the audio-data is updated while the painting routine is under-way.
I'm also aware I'm slightly out-of-date on Java and the Concurrency package it has, but my first response was to just put synchronised blocks around the shared data code. Unsurprisingly this blocks the graphics thread sometimes, so I'm thinking there's probaly a much better way of doing this.
Essentially I just dont have much experience with synchronisation and am screwing things up a bit somewhere. I wonder if someone with a better understanding of these matters might be able to suggest a more elegant solution that doesn't block the graphics thread?
My naive code:
Object lock = new Object();
double[] audio = new double[8000]
// array size is always exactly 8000
public update( double[] audio ) {
synchronized( lock ) {
this.audio=audio; // and some brief processing
}
repaint();
}
public void paint( Graphics g ) {
synchronized( lock ) {
// draw the contents of this.audio
}
}
Self-answer, unless some more intelligent person can offer something better, I just save a reference to the audio array at the beginning of the routine and draw from that, then any updates to the audio buffer do their calculations in a separate array and then assign this.audio to the new array in a single step.
It appears to work, although the paint routine does get an occasional flicker it is nothing like it was, where it was flashing very noticeably about 10% of the time due to synchronised blocking. The audio-data does not update half-way through the drawing routine either. so... problem solved. probably.
double[] audio = new double[8000]
// array size is always exactly 8000
public update( double[] audio ) {
// do any brief processing
this.audio=audio; // the reference is re-assigned in one step
repaint();
}
public void paint( Graphics g ) {
audioNow = this.audio; // save the reference
// draw the contents of audioNow (not this.audio)
}

Resources