Hi guys,
What is the equivalent of setRasterOp( NotXorROP ) in Qt4?? I cant see any alternative defined in qtAssistance.
Thanks
Hi guys,
What is the equivalent of setRasterOp( NotXorROP ) in Qt4?? I cant see any alternative defined in qtAssistance.
Thanks
I think currently there is no equivalent. Use of such thing would be highly limited as Qt4 forbids painting outside a paint event.
Then I'll have tough time porting to qt4. In my application there are many places where I have used setRasterOp, so how should I solve the problem????
If qt4 doesnt support setRasterOp, what about projects whose functionality is completely based on QPainter and setRasterOp. It will be a tough time for guy like me who is given tasks to port to qt4.Qt4 forbids painting outside a paint event
Is there a way I can solve above problem of setRasterOp with minimun code changes???. Without this my application looks very odd....
Please help!!!!!
You only have to modify your paintEvent code to apply the changes you'd do using the raster operation.
Raster operations are history with Qt4. They don't fit into the graphic pipeline of Qt4, so say good bye to them.
But what did you do with the raster operations ?
The most common use case was the XOR mode to implement rubberbands, crosshairs ... without having to repaint the content below. With Qt4 you always have to repaint the content below - and yes this is sometimes too slow for interactive operations, f.e for a remote X session over a line with a limited bandwidth.
You might have a look at http://qwt.sourceforge.net/class_qwt_picker.html. QwtPicker is implemented as a masked widget, that displays a rubberband on top of your widget. Using it you can implement rubberband supported selections in a couple of lines.
Uwe
Here is my sample code. How do I solve the setRasterOp problem
//.h
Qt Code:To copy to clipboard, switch view to plain text mode
//.cpp
Qt Code:
#include "setrasteroptest.h" #include <QMouseEvent> #include <QPainter> //Program to draw a straight line using Qt4 //constructor { ui.setupUi(this); QPalette palette; palette.setColor(backgroundRole(), color); setPalette(palette); setMouseTracking(true); } setRasterOpTest::~setRasterOpTest() {} //Press mouse and remember firstPoint and oldPoint { if (e->button() == Qt::LeftButton) { firstPoint = e->pos(); oldPoint = e->pos(); } } //release mouse function //If mouse is released on left button pressed //draw a line in red color to whever the mouse is released { if (e->button() == Qt::LeftButton ) { QPainter paint; paint.begin( this ); oldPoint = e->pos(); paint.drawLine(firstPoint, oldPoint); paint.end(); update(); } } //mouse move event //Perform rubber banding { //draw the line in xor mode (rubberbanding) QPainter painter; painter.begin( this ); //setRasterOp not defined in Qt4. //painter.setRasterOp (NotXorROP); // first draw over the previously drawn line and // erase it (in NotXorROP mode) if(prevRubberband){ painter.drawLine(firstPoint, oldPoint ); } oldPoint = e->pos(); painter.drawLine( firstPoint, oldPoint ); painter.end(); prevRubberband = true; update(); } { }To copy to clipboard, switch view to plain text mode
Thanks for your understanding
I think the code is broken as calling update() from mouseMove when using a raster op would not make any sense.... Anyway:
Qt Code:
void setRasterOpTest::mousePressEvent *e){ m_firstpt = e->pos(); m_lastpt = e->pos(); } { m_lastpt = e->pos(); update(); } update(); } //... (do regular stuff here) if(!m_firstpt.isNull()){ painter.save(); painter.setPen(Qt::black); painter.drawLine(m_firstpt, m_lastpt); painter.restore(); } }To copy to clipboard, switch view to plain text mode
Wow!!!
The code written has reduced a lot and very efficient too. Now I'm getting why trolltech decided to make such a change. Awesome!!!!
I have one doubt from above code. When I draw a line it disappears once the mouse it released. What I want is, the line has to appear after the mouse is released such that I can draw two or more lines.
I tried setting some boolean values, but didnt help.
Thanks!
Change the two QPoint members into a list or vector of points and don't null out the vector on mouse release. Then in the paint event iterate over the list and draw all the points.
SOmething like this. But unlucky
Qt Code:
m_vector<<e->pos(); } m_vector<<e->pos(); update(); } m_vector<<e->pos(); update(); } //... (do regular stuff here) if( m_vector.count() <= 0 ) return; QPainter painter; painter.begin(this); painter.setPen( Qt::black ); painter.drawLines ( m_vector ); painter.end(); }To copy to clipboard, switch view to plain text mode
Also let me explain, I dont want a continuous flow of line as in scribble example but only straight line. I start from a point and when I release the mouse a straight line should be drawn. Then again I click on some other point and when I release the mouse another straight line should be drawn.
Thanks for your understanding
Last edited by vermarajeev; 29th March 2007 at 13:36.
Hi wysota!,
Can you please help me with this???
Waiting for a reply!!!!!!
The below solution draws only a single line. How to draw two or more lines???
Qt Code:
if (e->button() == Qt::LeftButton) { m_firstpt = e->pos(); m_lastpt = e->pos(); } } if ((e->buttons() & Qt::LeftButton) ){ m_lastpt = e->pos(); update(); } } if (e->button() == Qt::LeftButton ) { m_lastpt = e->pos(); update(); } } painter.setPen( Qt::black ); painter.drawLine(m_firstpt, m_lastpt); }To copy to clipboard, switch view to plain text mode
One more solution, Now this draws so many lines.. I'm trying and let you know if I get it...
Here is the program...
Qt Code:
if (e->button() == Qt::LeftButton) { m_firstpt = e->pos(); m_lastpt = e->pos(); } } if ((e->buttons() & Qt::LeftButton) ){ m_lastpt = e->pos(); update(); } } if (e->button() == Qt::LeftButton ) { m_lastpt = e->pos(); update(); } } painter.setPen( Qt::black ); painter.drawLines( m_vectorLine ); }To copy to clipboard, switch view to plain text mode
If you get it before please let me know...
Thanks
Sorry, I've been unavailable.
Maybe you should change your concept a little and make it so that you click and drag with left mouse button and when you want to finish a line segment, you click with right mouse button.
It would look more or less like so:
Qt Code:
void setRasterOpTest::mousePressEvent *e){ if(e->button()==Qt::LeftButton){ m_list.clear(); m_list << e->pos(); m_lastpt = e->pos(); } else if(e->button()==Qt::RightButton){ m_list << e->pos(); m_lastpt = e->pos(); } } { m_lastpt = e->pos(); update(); } if(e->button()==Qt::LeftButton()){ if(m_list.size()==1 && (e->pos()-m_list[0]).manhattanLength()<5){ m_list.clear(); update(); return; } m_list << e->pos(); update(); } } //... (do regular stuff here) if(!m_list.isEmpty()){ painter.save(); painter.setPen(Qt::black); painter.drawLines(m_list); painter.setPen(Qt::red); painter.drawLine(m_list[m_list.size()-1], m_lastpt); painter.restore(); } }To copy to clipboard, switch view to plain text mode
EDIT: A complete working example is attached.
Last edited by wysota; 30th March 2007 at 11:16.
Hi wysota,
My application is something like QPainter in MS where you can draw different kind of molecules (in chemistry term). The product is now to be ported to qt4. If I change the functionality (which is not a good idea) of drawing operations, I'll have tough time with my client.
The above sample program is the first step (where I should be able to draw two or more straight lines) to move forward.
I think you can understand my problem so please help me to achieve the same functionality as setRasterOp in qt3 performs.
Waiting eagerly for a reply....
How about Uwe's idea...Will that help????
One more thing...
I checked the output for example you have given. It is not that I want.
Your case:
You draw a line with left mouse button pressed, it draws a red line, then you press the right mouse button, It draws a continous line.
My case:
You click at a point start dragging and release the mouse button. A straight line should be drawn. Then again if I mousePress at some other point another line has to be drawn with the previous one shown.
Hope I'm clear!!
Thanks for your understanding
Last edited by vermarajeev; 30th March 2007 at 11:55.
Oh... I see... well, this is even easier. Just make a vector of QLine and add a line composed of m_firstPt and m_lastPt on mouse release and don't clear the vector on mouse press. The rest should remain the same as my first example.
Uwe was speaking about more or less the same thing [qtclass]QRubberBand[qtclass] does. It won't be useful in your case.
And here is the code that I want....
Qt Code:
#include "setrasteroptest.h" #include <QMouseEvent> #include <QPainter> //Program to draw a straight line using Qt4 //constructor { ui.setupUi(this); QPalette palette; palette.setColor(backgroundRole(), color); setPalette(palette); setMouseTracking(true); m_bflag = false; } setRasterOpTest::~setRasterOpTest() {} if (e->button() == Qt::LeftButton){ m_firstpt = e->pos(); m_lastpt = e->pos(); } } if ((e->buttons() & Qt::LeftButton) ){ m_lastpt = e->pos(); m_bflag = true; update(); } } if (e->button() == Qt::LeftButton ) { m_lastpt = e->pos(); update(); } } painter.setPen( Qt::black ); painter.drawLines( m_vectorLine ); if( m_bflag ){ painter.drawLine( m_firstpt, m_lastpt ); m_bflag = false; } }To copy to clipboard, switch view to plain text mode
Thanks wysota!!!!
I don't know the details of your applications, but in general there are two types of lines. One that is supporting an interaction ( what is often called a rubberband ), the other one is a permanent line - the result of the interaction. Raster operations (XOR mode) are only useful for the first type of line (dragging), so I´m pretty sure, that your code is about rubberbanding - even if you are not aware about this yet.
The trick about painting in XOR mode is, that painting the same thing twice, erases the first painting. This makes it possible to drag an object, without having to repaint the content of the widget. With Qt4 you always (!) have to repaint the content to erase the previous position of the line - and in many environments, you will see that the dragged object can't follow mouse movements in time.
Implementing rubberbands (dragging) without raster operations leads to very different code with worse results. This is something you and your client have to accept. The only choice you have is if you want to merge the painting code of rubberband and content (that´s what the Qt widgets do), or if you isolate the painting code of the rubberband to an masked 2. widget, where changes of the mask lead to paint events for the content widget. The main advantage of the second implementation is that you can implement it once and can use it with any type of content widget - that´s what f.e. QwtPicker is about.
Uwe
By the way: QRubberBand is a styled line/rect, but absolutely no replacement for the XOR mode.
Bookmarks