PDA

View Full Version : QT3 to Qt4 port - problem seeing Ellipse etc



tanimbar
5th March 2008, 12:19
Hello,
I'm new to the forum and have a problem porting a science program from QT3.*.* on linux to qt4 on windows XP sp2. By the way, I'm an old fortran programmer and know little about Qt.

I have the program running correctly on Opensuse 10.2/Qt3.3.8.

For the code that doesn't work correctly on XP the user is supposed to:
1) Left-mouse select a point,
2) then hold down the left-mouse and drag an ellipse across an area of interest,
3) release the mouse and the underlying screen image is altered according to the ellipse area covered.

However, on the XP version the ellipse does not appear.

The relevent code is summarised below.



void strPlot::mousePressEvent( QMouseEvent *e)
pixmapa = QPixmap::grabWidget(this);

if ( e->button() == Qt::LeftButton )
//here I've left out that defines screen coords etc.



void strPlot::mouseMoveEvent( QMouseEvent *e)
{

int idx, nr_pryzmy;
QRect rr;
QPoint punkt;
int temp_x1,temp_z1,z_szer=0,z_wys=0;
double xm,zm;

QPainter p( this );

if(e->state() & Qt::LeftButton)
{
if(click_x1>click_x2)
{
temp_x1 = click_x2;
click_x2 = click_x1;
}

if(click_z1>click_z2)
{
temp_z1 = click_z2;
click_z2 = click_z1;
}

if(click_x1<xel) click_x1 = xel;
if(click_x2>xer) click_x2 = xer;
if(click_z1<yel) click_z1 = yel;
if(click_z2>yer) click_z2 = yer;

z_szer = click_x2 - click_x1;
z_wys = click_z2 - click_z1;

rr = QRect(temp_x1,temp_z1,z_szer,z_wys);

bitBlt(this,0,0,&pixmapa);

//rysuj_prostokaty(&p);
//repaint(rr);
p.setBrush(NoBrush);
p.setPen(QPen(black,2));
p.setPen(DashLine);
if(z_ksztalt==1 || z_ksztalt==-1) p.drawRect(rr);

if(z_ksztalt==2)p.drawEllipse(rr); // THIS IS THE BIT THAT FAILS

}
}

void strPlot::mouseReleaseEvent( QMouseEvent *e)

//here I've left out a lot of subsiduary code etc.

if(z_ksztalt==2)
{
rr = QRect(click_x1,click_z1,z_szer,z_wys) ;
zmien_stan(QRegion(rr,QRegion::Ellipse));

}
}
}
//Tanimbar: the update below causes the selected blocks to change density colour
update();
QPainter p( this );
rysuj_prostokaty(&p);
}

As I understand the code the following is supposed to happen:
1) on MousePressevent a pixmap is grabbed,
2) on MouseMovement the pixmap is passed to bitBlt and overdrawn on top of the, now, underlying widget,
3) while the Mouse is moving an ellipse should be drawn on the pixmap,
4) on Mousereleaseevent the pixmap disappears and the underlying widget is updated with new information, a colour change to blocks, formerly delineated by the ellipse.

However, after extensive trials, much reading of manuals and forums, I still cannot get the ellipse to become visible. Everything else works, including the events/actions required on MousereleaseEvent.

Can anyone help - hints, tips suggestions?

Thanks in advance.

wysota
5th March 2008, 12:46
In Qt4 you can only paint within paintEvent. But I suggest you do it differently - use QRubberBand class. By default it's rectangular, so you'll have to subclass it.

tanimbar
5th March 2008, 18:29
Wysota,
Thank you for the information - I now know what to look at.

Thanks for editing my original message.

regards, Tanimbar

tanimbar
10th March 2008, 13:44
Thanks for Wysota for the QrubberBand tip/hint. That works very well for the situation described in my first note, i.e., dragging a rectangle over a widget by the user to define an area of interest.

It occured to me that QrubberBand, using Line and not Rectangle, might also work for the case where the user mousepresses, drags a line to new point, mousereleases and then, mousepresses again to continue defining a polyline around an area of interest.

But I can't get QRubberBand::Line to work: the program always draws a Rectangle.

I've tried various style options, for example, QWindowsXPstyle, and all sorts of code variations but can't get Qrubberband to use a line.

There was a bug related to QRubberband not using Line but that is reported as fixed http://trolltech.org/developer/task-tracker/index_html?method=entry&id=78876.

The code below is the present example that doesn't draw a line.


void strPlot::mousePressEvent( QMouseEvent *e)
{

double xm,zm;
int x,y;
QPoint punkt;
// pixmapa = QPixmap::grabWidget(this);
if ( e->button() == Qt::LeftButton )
.
.
.
origin = e->pos();
if (!rubberBand)
rubberBand->setStyle( (QStyle*)new QWindowsXPStyle() );
rubberBand = new QRubberBand(QRubberBand::Line, this);
// works rubberBand->setGeometry(click_x1,click_z1,5,5);
rubberBand->setGeometry(QRect(origin, QSize(1,1)));
rubberBand->show();
.
.

So, a couple of questions:
1) Does anyone have a working example of QRubberBand using Line?
2) Does anyone know if a bug still exists for QRubberBand line?
3) Does anyone have a suggestion/fix/hint?

By the way, I'm an old fortran programmer, don't know C++ or Qt (sorry) and using Qt4.3.4 OpenSource on a Windows XP SP2 system.

Thanks very much.