Results 1 to 7 of 7

Thread: Must QPainter be in paintEvent ??

  1. #1
    Join Date
    Sep 2009
    Location
    Surrey, BC, Canada
    Posts
    110
    Thanks
    1
    Thanked 2 Times in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Unhappy Must QPainter be in paintEvent ??

    I'm using Qt 4.5.2 in WindowsXP and Qt 4.4.3 in Ubuntu 8.10 (default Intrepid repository)

    My question comes from how to draw a QImage by using QGraphicsView?
    (Well, yes, I did draw it by using the classical QLablel, but that seems not to be what I expected.)

    Now, I manage to realize this by overloading function "drawBackground",
    Qt Code:
    1. void CImageView::drawBackground(QPainter *painter, const QRectF &rect)
    2. {
    3. painter->drawImage(rect,*m_QTImage);
    4. }
    To copy to clipboard, switch view to plain text mode 

    and call this drawBackGround() function in another function of the same class by
    Qt Code:
    1. this->m_QTScene->invalidate();
    2. QPainter painter(this);
    3. drawBackground(&painter, this->m_QTScene->sceneRect());
    To copy to clipboard, switch view to plain text mode 

    where the class CImageView inherits from QGraphicsView .

    However, in Ubuntu 8.10, Qt 4.4.3, I was always suggested by

    "QPainter::begin: Widget painting can only begin as a result of a paintEvent."


    I'm posting to ask whether it is a must to put QPainter inside the function paintEvent?
    If it is a must, why this is only a warning message, but not reported as an error? Is this a difference between Qt 4.5.2 and Qt 4.4.3?

    What's more, I tried to put QPainter into paintEvent by the following code

    Qt Code:
    1. void CImageView::paintEvent(QPaintEvent *event)
    2. {
    3. if(this->m_isDrawing)
    4. {
    5. QGraphicsView::paintEvent(event);
    6. this->m_isDrawing = false;
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    and in the calling function, I use this->repaint();


    But, it seems that the default "QGraphicsView:aintEvent(event);" will help to trigger the overloaded function "drawBackground" and draw the image. But when I tried to use the above mechanism to grab images from the webcam, there is some times a white dot in the middle of captured image. Seriously no idea of why it is so. And this white dot seems only happen in Linux, but now WindowsXP.


    Best Regards
    JIA Pei
    Welcome to Vision Open
    http://www.visionopen.com

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Must QPainter be in paintEvent ??

    Why are you calling that drawBackground() method? You shouldn't need to call it anywhere... What is the purpose of that?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Sep 2009
    Location
    Surrey, BC, Canada
    Posts
    110
    Thanks
    1
    Thanked 2 Times in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Unhappy Re: Must QPainter be in paintEvent ??

    Quote Originally Posted by wysota View Post
    Why are you calling that drawBackground() method? You shouldn't need to call it anywhere... What is the purpose of that?

    Thank you for your suggestion. However, if I only do

    Qt Code:
    1. void CImageView::paintEvent(QPaintEvent *event)
    2. {
    3. if(this->m_isDrawing)
    4. {
    5. QPainter painter(this);
    6. painter.drawImage(this->m_QTScene->sceneRect(),*m_QTImage);
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    The image will not show at all. I really don't know what happens in the overloaded function
    "drawBackground",but if I put the line

    Qt Code:
    1. painter.drawImage(this->m_QTScene->sceneRect(),*m_QTImage);
    To copy to clipboard, switch view to plain text mode 

    in the overloaded "drawBackground", my program draws !!!

    So, can you please tell me how to use paintEvent to draw a QImage on a "QGraphicsView" ? (BTW, I don't want to do something like QImage->QPixmap, this will slow down the processing I guess.)

    Cheers
    JIA
    Welcome to Vision Open
    http://www.visionopen.com

  4. #4
    Join Date
    Sep 2009
    Location
    Surrey, BC, Canada
    Posts
    110
    Thanks
    1
    Thanked 2 Times in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Must QPainter be in paintEvent ??

    Quote Originally Posted by wysota View Post
    Why are you calling that drawBackground() method? You shouldn't need to call it anywhere... What is the purpose of that?
    By the way, you may simply refer to

    http://qtextended.org/modules/newbb_...id=890&forum=5


    It seems to "drawImage" in "drawBackground" is not only feasible, but also fast !

    Any suggestions?

    Rgds
    JIA
    Welcome to Vision Open
    http://www.visionopen.com

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Must QPainter be in paintEvent ??

    Quote Originally Posted by jiapei100 View Post
    Thank you for your suggestion. However, if I only do

    Qt Code:
    1. void CImageView::paintEvent(QPaintEvent *event)
    2. {
    3. if(this->m_isDrawing)
    4. {
    5. QPainter painter(this);
    6. painter.drawImage(this->m_QTScene->sceneRect(),*m_QTImage);
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    The image will not show at all.
    Well... that's obvious. The code doesn't make sense with graphics view.

    I really don't know what happens in the overloaded function
    "drawBackground",but if I put the line

    Qt Code:
    1. painter.drawImage(this->m_QTScene->sceneRect(),*m_QTImage);
    To copy to clipboard, switch view to plain text mode 

    in the overloaded "drawBackground", my program draws !!!
    Sure it does. I wouldn't expect anything different. The question is why are you calling drawBackground() if Qt already calls this method for you when appropriate.

    So, can you please tell me how to use paintEvent to draw a QImage on a "QGraphicsView" ?
    But why would you want to do that? If you really have to, reimplement drawBackground() or drawForeground(). Just don't touch the paint event.

    (BTW, I don't want to do something like QImage->QPixmap, this will slow down the processing I guess.)
    The image will be converted to a pixmap either way, so this doesn't make any difference if you do the conversion yourself or let Qt do that.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Sep 2009
    Location
    Surrey, BC, Canada
    Posts
    110
    Thanks
    1
    Thanked 2 Times in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Must QPainter be in paintEvent ??

    Thanks for your prompt reply. Now, let me ask you how to solve the problem correctly.
    And it's better you teach me one by one.

    1)
    Qt Code:
    1. void CImageView::paintEvent(QPaintEvent *event)
    2. {
    3. if(this->m_isDrawing)
    4. {
    5. QPainter painter(this);
    6. painter.drawImage(this->m_QTScene->sceneRect(),*m_QTImage);
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    The image will not show at all.

    Well... that's obvious. The code doesn't make sense with graphics view.
    Yes, painter only draws an image on the scene, but how can I make the scene able to be seen on the view? (Sorry, according to my understand, a view is something quite similar to a canvas or whatever views. )


    2)
    I really don't know what happens in the overloaded function
    "drawBackground",but if I put the line

    Qt Code:
    1. painter.drawImage(this->m_QTScene->sceneRect(),*m_QTImage);
    To copy to clipboard, switch view to plain text mode 

    in the overloaded "drawBackground", my program draws !!!

    Sure it does. I wouldn't expect anything different. The question is why are you calling drawBackground() if Qt already calls this method for you when appropriate.

    Do you mean that drawBackground() is something like a paintEvent? which will be callbacked? Otherwise, what do you mean by "Qt already calls this method when appropriate?" I'm trying to grab the images from the webcam and update the image scene in real-time !! So, it's ok for me not to change the background image, but how can I update the captured image on the view in real-time? Yes, you may suggest to change the foreground... But, I suppose you might be able to suggest a more reasonable and suitable and classical way to do so, right? So, can you show me your code? Cheers

    3)
    So, can you please tell me how to use paintEvent to draw a QImage on a "QGraphicsView" ?

    But why would you want to do that? If you really have to, reimplement drawBackground() or drawForeground(). Just don't touch the paint event.
    As I said, I have to grab the real-time images captured from the webcam. I think there must be a way to just revise paintEvent without reimplementing drawBackground(), right? Do you know how?

    4)
    (BTW, I don't want to do something like QImage->QPixmap, this will slow down the processing I guess.)
    The image will be converted to a pixmap either way, so this doesn't make any difference if you do the conversion yourself or let Qt do that.
    Yes, it's better QT affords a more compatible and convenient way for the users to draw both static and dynamic images (dynamic means image sequence) with various inputs (QPixmap, as well as QImage) on "QGraphicsView" .



    In sum, you suggest not to overload drawBackground() to draw images on a QGraphicsView. But, you didn't show anything useful till now. What's more, even the QT demo "svgviewer",
    Qt Code:
    1. SvgView::paintEvent(QPaintEvent *event)
    To copy to clipboard, switch view to plain text mode 
    seems to be cheating:

    Qt Code:
    1. void SvgView::paintEvent(QPaintEvent *event)
    2. {
    3. if (m_renderer == Image) {
    4. if (m_image.size() != viewport()->size()) {
    5. m_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied);
    6. }
    7.  
    8. QPainter imagePainter(&m_image);
    9. QGraphicsView::render(&imagePainter);
    10. imagePainter.end();
    11.  
    12. QPainter p(viewport());
    13. p.drawImage(0, 0, m_image);
    14.  
    15. } else {
    16. QGraphicsView::paintEvent(event);
    17. }
    18. }
    To copy to clipboard, switch view to plain text mode 

    m_image only occurs in this paintEvent(QPaintEvent *event); that means, m_image is not used to open an image file or grab an image from the webcam.

    Therefore, in sum, can you please use QGraphicsView to realize video capturing without overloading "drawBackground"? Please do help!!!

    Thanks in advance !!

    Best Regards
    JIA Pei
    Last edited by jiapei100; 4th September 2009 at 23:47.
    Welcome to Vision Open
    http://www.visionopen.com

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Must QPainter be in paintEvent ??

    Quote Originally Posted by jiapei100 View Post
    Yes, painter only draws an image on the scene,
    No, it doesn't. What you are doing here is trying to draw directly on the view bypassing the scene. That's why it doesn't work.

    but how can I make the scene able to be seen on the view?
    QGraphicsView::setScene()
    (Sorry, according to my understand, a view is something quite similar to a canvas or whatever views. )
    Not really. Scene is a canvas, the view is only a possible look (frustum) on it (imagine that you want to take a photo of a picture - the picture is a scene and your camera is the view).


    Do you mean that drawBackground() is something like a paintEvent?
    No. It is a method that is called from the implementation of QGraphicsScene::render() which in turn is called from the paint event of the view.

    which will be callbacked?
    Callback is not a proper word here. It will just be called.

    I'm trying to grab the images from the webcam and update the image scene in real-time !!
    I'm not sure if graphics view is the proper architecture for you. Do you want to place something apart the webcam images on the scene?

    What do you mean by "I don't touch the paint event"?
    Don't reimplement it.

    So, do you mean that without overloading paintEvent(), the real-time images captured from the webcam will be updated automatically??
    Actually yes.
    What an intelligent QT!!!! My god.... I don't thingk QT is that intelligent yet.
    I know you meant it as a joke so let's keep the convention.
    QT is not that intelligent yet... Qt is.

    Yes, it's better QT affords a more compatible and convenient way for the users to draw both static and dynamic images (dynamic means image sequence) on "QGraphicsView" .
    I think we understand the terms "static" and "dynamic" differently. Graphics View is nowhere more dynamic than any other (QWidget+QPainter based, to be exact) approach.
    If all you want is to display an animating image then graphics view is a wrong solution to this problem. Based on experience of myself and others on this forum for this specific purpose I would advise to use a QGLWidget with your images treated as textures displayed on an orthogonal rectangle. It's easy to implement and can save you some processing power of converting between image representations back and forth (in simpler terms - it will be faster). Once you have the images it's about 20-30 lines of code to get them displayed.

    But, you didn't show anything useful till now.
    Well... sorry But maybe that's because before I give a solution I'm trying to understand what you did and what you wanted to do. Most of the time it's just a matter of the person not describing the problem very well. If you described your problem ("I want to paint a fence") instead of assuming you were using the right tools for the job ("How do I make the coffee machine spill the paint in a constant speed?" with an obvious answer "Why would you put paint into a coffee machine?").

    Read this, it's really useful: http://www.catb.org/~esr/faqs/smart-questions.html (especially on this forum where recently more advanced users tend to lose patience when reading an incorrectly asked question)

    What's more, even the QT demo "svgviewer",
    Qt Code:
    1. SvgView::paintEvent(QPaintEvent *event)
    To copy to clipboard, switch view to plain text mode 
    seems to be cheating:
    It's not cheating, it's providing a special case if you're painting on an image - so that it renders to both the image and the screen. It's certainly not what you're after, right?

    Therefore, in sum, can you please use QGraphicsView to realize video capturing without overloading "drawBackground"?
    Sure, I can.
    Please do let everybody here know.
    Well... I'd start by reading the docs about QGraphicsView too see how to use it. I would probably discover that it's object oriented and based on something called "items". Then I would probably say "Hey, it's not the right architecture for me, I don't have any items" and use some other approach. If I still thought I should use QGV, I would probably implement an item class for my webcam and place the aforementioned item on the scene. Then I would have noticed that it didn't animate, so I'd open Qt Assistant (actually it would probably be open all the time) and type in "QGraphicsView animation" in the search tab and then clicked the first result which would be (and actually is) "QGraphicsItemAnimation Class Reference". Then I'd use it with my item and have rest of the day off.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. QPainter reuse within a paintEvent
    By Micawber in forum Qt Programming
    Replies: 2
    Last Post: 2nd May 2008, 16:51
  2. Replies: 3
    Last Post: 27th November 2006, 09:56
  3. QPainter ouside of paintEvent with a pixmap
    By bitChanger in forum Qt Programming
    Replies: 10
    Last Post: 22nd March 2006, 19:45
  4. Replies: 7
    Last Post: 20th March 2006, 20:03
  5. Replies: 12
    Last Post: 5th February 2006, 10:34

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.