PDA

View Full Version : Qt Multi Threading RePainting Problem



Mohammad
8th January 2012, 21:52
Hi i am working on college task that involve a recursion drawing question and i am working with Qt.
my problem when the drawing function begin, the gui freezing until drawing finish,even though i used multi threading .
is there any way to avoid freezing while repainting main window ???
here is the code:

class draw:public QThread
{
public :
QPainter *d;
QWidget *t;
draw(){}
void run()
{
Drawing(10,40,0,3.1415926535897932384626433832795/4,200,200,d);
}

void Drawing(int n,double d,double q1,double q2,int x,int y,QPainter *dr)
{
if (n > 0)
{
int x1 = x - (sin(q1) * d);
int y1 = y - (cos(q1) * d);
dr->drawLine(x, y, x1, y1);
t->repaint();
int x2 = x1- (cos(q1) * d);
int y2 = y1 + (sin(q1) * d);
dr->drawLine(x1, y1, x2, y2);
t->repaint();
int x3 = x2 + (sin(q1) * d);
int y3 = y2 + (cos(q1) * d);
dr->drawLine(x2 , y2 , x3 , y3);
t->repaint();
dr->drawLine(x3 , y3 , x , y );
t->repaint();
double d1 = d / sqrt( 2.0 ); //d1 = d/?2
int x4 = x1 - ( cos(q2) * d1);
int y4 = y1 - ( sin(q2) * d1);
Drawing(n - 1, d1, q1 - 3.1415926535897932384626433832795/4, q2 + 3.1415926535897932384626433832795/4 , x1 , y1,dr);

Drawing(n - 1, d1, q1 + 3.1415926535897932384626433832795/4, q2 - 3.1415926535897932384626433832795/4 , x4 , y4,dr);
}
}
};


void MainWindow::on_pushButton_clicked()
{
image=new QPixmap(this->geometry().width(),this->geometry().height());
image->fill(this,0,0);
dr=new QPainter(this->image);
r=this->geometry();
draw d;
d.d=dr;
d.t=this;
d.run();
delete dr;
}





void MainWindow::paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.drawPixmap(r,*this->image);
}

wysota
9th January 2012, 05:58
You cannot draw on widgets from within threads. However since you are calling run() and not start(), your thread is not created at all and run() is called on behalf of the main thread. Have a look at the mandlebrot example to see how to use threads for drawing.

Mohammad
12th January 2012, 15:36
thanks wysota (http://www.qtcentre.org/members/11-wysota)for your helpful reply .
my problem is not big computation of the recursive shape but freezing while Repainting (i want user see how it's created -draw step by step about (2^n) repaint - not show it totally drawn in one step) .
can any one present a tick to do this ???

wysota
12th January 2012, 15:44
To do what you want you need to divide your drawing process into steps and then redraw the canvas for each step separately introducing some kind of delay. More or less like so:



public slots:
void setCurrentStep(int s) {
m_step = s;
update();
}

void XX::paintEvent(QPaintEvent *) {
QPainter p(this);
p.draw...
p.draw...
if(m_step == 0) return; // stops rendering at this point if step == 0
p.draw...
p.draw...
if(m_step == 1) return; // stops rendering at this point if step == 1
//...
//...
}

And then you can do something like that:


QTimeLine *tl = new QTimeLine(5000, this);
tl->setFrameRange(0, 4);
connect(tl, SIGNAL(frameChanged(int)), this, SLOT(setCurrentStep(int)));
connect(tl, SIGNAL(fnished()), tl, SLOT(deleteLater()));
tl->start();

This will render 5 steps of your animation in the total duration of 5 seconds (1s/frame). No threads required.

Mohammad
12th January 2012, 15:52
thank you wysota that is what i need.