Page 1 of 2 12 LastLast
Results 1 to 20 of 29

Thread: Minimize window = images gone

  1. #1

    Default Minimize window = images gone

    Hello,

    I am using the paintEvent method to show images on a QFrame. When starting the program, the images are shown correctly most of the times (sometimes they do not appear or in the wrong places). When I minimize the window or it gets overlapped by another, all images disappear. Any ideas what the problem might be?

    Thanks!

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

    Default Re: Minimize window = images gone

    The problem might be with your code.
    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

    Default Re: Minimize window = images gone

    Thanks for replying. In WeatherFrame.cpp I am doing the drawing - not sure what is wrong.


    Qt Code:
    1. #include "WeatherFrame.h"
    2.  
    3. WeatherFrame::WeatherFrame(QWidget *parent)
    4. : QFrame(parent)
    5. {
    6. mEngine = new GoogleEngine();
    7. connect(mEngine, SIGNAL(weatherReady()), this, SLOT(handleData()));
    8. connect(mEngine, SIGNAL(weatherError()), this, SLOT(handleError()));
    9.  
    10. mEngine->location().city() = "Salzburg";
    11. mEngine->update("Salzburg");
    12. }
    13.  
    14. WeatherFrame::~WeatherFrame()
    15. {
    16. delete mEngine;
    17. }
    18.  
    19. void WeatherFrame::handleData()
    20. {
    21. mCurrentLocation = mEngine->location();
    22. mCurrentWeather = mEngine->weather();
    23. mListForecast = mEngine->forecast();
    24. mReady = true;
    25. update();
    26. }
    27.  
    28. void WeatherFrame::handleError()
    29. {
    30. qDebug() << "handleerror";
    31. }
    32.  
    33. void WeatherFrame::paintEvent(QPaintEvent* event)
    34. {
    35. if (mReady) {
    36. Q_UNUSED(event);
    37. QPainter painter(this);
    38. painter.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform);
    39.  
    40. // draw current temperature
    41. painter.setPen(Qt::black);
    42. painter.setFont(QFont("Arial", 16));
    43. painter.drawText(QRect(5,2,100,30), Qt::AlignLeft, "Wetter -");
    44.  
    45. // draw location's city name
    46. painter.setFont(QFont("Arial", 16));
    47. painter.drawText(QRect(100,2,100,30), Qt::AlignLeft, mCurrentLocation.city());
    48.  
    49. // draw condition pixmap
    50. painter.drawPixmap(QRect(10,55,50,50),mCurrentWeather.pixmap());
    51.  
    52. painter.setFont(QFont("Arial", 12));
    53. painter.drawText(QRect(20,25,60,40), Qt::AlignCenter, "HEUTE");
    54.  
    55. painter.setFont(QFont("Arial", 14));
    56. painter.drawText(QRect(20,105,40,40), Qt::AlignCenter,
    57. QString::number(FahrenheitToGrad(mCurrentWeather.temperature())));
    58.  
    59. for (int i = 0; i < mListForecast.count(); i++) {
    60. Weather weather = mListForecast.at(i);
    61.  
    62. // draw forecast day
    63. painter.setFont(QFont("Arial", 12));
    64. painter.drawText(QRect((i+1)*100+20,25,40,40), Qt::AlignCenter, weather.day().toUpper());
    65.  
    66. // draw condition pixmap
    67. painter.drawPixmap(QRect((i+1)*100+20,55,50,50), weather.pixmap());
    68.  
    69. // draw forecast low and high temperature
    70. painter.setFont(QFont("Arial", 10));
    71. painter.drawText(QRect((i+1)*100+20, 95,40,40), Qt::AlignCenter, QString::number(weather.lowTemp()));
    72. painter.drawText(QRect((i+1)*100+20, 110,40,40), Qt::AlignCenter, QString::number(weather.highTemp()));
    73.  
    74. }
    75.  
    76. mReady = false;
    77. } else {
    78. QWidget::paintEvent(event);
    79. }
    80. }
    81.  
    82. int WeatherFrame::FahrenheitToGrad(int f)
    83. {
    84. int c = (f-32) / 1.8;
    85. return c;
    86. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 22nd June 2011 at 11:23. Reason: changed [qtclass] to [code]

  4. #4
    Join Date
    Nov 2010
    Posts
    57
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 1 Time in 1 Post

    Default Re: Minimize window = images gone

    Put a break point in your paint event. Check the value of mReady. Or put in some logging.

    You will notice how often it repaints and how often your mReady is false. This should help you see why it is not repainted after you have minimized.

  5. #5

    Default Re: Minimize window = images gone

    ouch, somehow I thought it must be a much more severe problem... Thanks!

  6. #6
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    It is quite obvious to me what is happenig. You are drawin the widget only once when the data is available and then you draw nothing. However you must draw something when window is being restored.

    Much better solution would be do have some QPixmap m_weatherPixmap declared as your private member variable. Then also declare something like updatePixmap, where you draw your weather info into a pixmap;

    In handleData you should clear the pixmap: m_weatherPixmap = QPixmap();

    in paintEvent:

    Qt Code:
    1. if(m_weatherPixmap.isEmpty())
    2. {
    3. if(mReady)
    4. {
    5. updatePixmap(m_weatherPixmap);
    6. }
    7. }
    8.  
    9. QPainter p(this);
    10. p->drawPixmap(0,0,m_weatherPixmap);
    To copy to clipboard, switch view to plain text mode 


    Hope this helps.
    Last edited by wysota; 22nd June 2011 at 11:24. Reason: missing [code] tags

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

    Default Re: Minimize window = images gone

    Changing any variable value in paintEvent is a sure misdesign.
    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.


  8. #8
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    Not really, I have never heard of anyone saying that before, in many situations that is the only way you can do something, especially when performance comes into the game.

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

    Default Re: Minimize window = images gone

    Example please.
    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.


  10. #10
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    Example:

    You have a QWidget that draws itself based on some multiple properties. This code will be run on a very slow machine. Drawing the widget from the beginning every time is slower than using stored pixmap. Now, if you don't want this pixmap to be redrawn every time you change a property, what do you do?

  11. #11
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    8
    Thanked 133 Times in 128 Posts

    Default Re: Minimize window = images gone

    Quote Originally Posted by Rachol View Post
    Example:

    You have a QWidget that draws itself based on some multiple properties. This code will be run on a very slow machine. Drawing the widget from the beginning every time is slower than using stored pixmap. Now, if you don't want this pixmap to be redrawn every time you change a property, what do you do?
    Sorry to pop in, Your sentence is little bit confusing to me. Can you give some sample code and we will see if we can improve upon it?

  12. #12
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    I don't see anything confusing in there, it is quite simple. Where is the confusing part? And why should I get a code for imaginary case? I just try to prove that saying that "changing a variable in paintEvent is a misdesign" is totally wrong.

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

    Default Re: Minimize window = images gone

    Quote Originally Posted by Rachol View Post
    You have a QWidget that draws itself based on some multiple properties. This code will be run on a very slow machine. Drawing the widget from the beginning every time is slower than using stored pixmap. Now, if you don't want this pixmap to be redrawn every time you change a property, what do you do?
    Then you render the widget to the pixmap before the paint event is invoked and then only render the pixmap in the event. But I'm not sure why you wouldn't want it the widget to be redrawn when its contents change...
    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.


  14. #14
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    Because sometimes you can change couple properties and you don't want the pixmap to be rendered twice, or more times before the paintEvent comes.

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

    Default Re: Minimize window = images gone

    Why would the pixmap be rendered twice? You can delay your pixmap generating code the same way as paint event is delayed. I agree you can generate the pixmap in the paint event but there are alternatives that have their advantages. Like doing the rendering in an external thread.
    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.


  16. The following user says thank you to wysota for this useful post:

    Rachol (22nd June 2011)

  17. #16
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    Thanks for agreeing that indeed changing variables in the paintEvent ain't misdesign. Delaying... can't be as optimized as drawing in paintEvent, cause paintEvent is called only and only when necessary. You could of course do it so it is done just before paintEvent is called, but then it is quite much the same thing, but more complicated and unnecessary work is done. Then rendering in a separated thread could be done, but then again it depends on the case. I used to work with a embedded device that couldn't handle well multithreading applications..., so I agree that there are many options it just to choose the option that fits best your case.

  18. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Minimize window = images gone

    Quote Originally Posted by Rachol View Post
    Thanks for agreeing that indeed changing variables in the paintEvent ain't misdesign.
    I said nothing like that. I said you could do it in paintEvent but I didn't say it's a good design. Unless of course you like having frozen GUI. Paint event should be executed as fast as possible and all unnecessary code should be stripped out of the event handler.

    Delaying... can't be as optimized as drawing in paintEvent, cause paintEvent is called only and only when necessary.
    I don't see your point. The amount of work to be done is the same -- you need to render to a pixmap and then render the pixmap to the widget. It's the decision when to do it that makes a difference. There is nothing "optimal" in drawing to the pixmap in paint event. If you change a property that affects the looks of the widget then eventually you'll want to display those changes so every update of the pixmap involves triggering a repaint. And every repaint doesn't have to check and update the pixmap because if there was something to update, pixmap updating code would have triggered a repaint.

    You could of course do it so it is done just before paintEvent is called, but then it is quite much the same thing
    No, it's not the same thing. Especially if your point is that you're working with a slow machine. In that case you want to save every cycle you can.

    Then rendering in a separated thread could be done, but then again it depends on the case. I used to work with a embedded device that couldn't handle well multithreading applications...
    That's not an argument. If you have a device that's not fit to be used with some solution then you don't use that solution. Extreme cases sometimes require extreme measures. However it doesn't make those measures good solutions. And it doesn't make a good design bad just because there exists a device that involves some special treatment.

    I've seen many people do such crazy flag resetting in paint events. It's caused by a false assumption that the painting code will be called only in conditions they specify which is not the case because the code can be called an arbitrary number of times per second. Updating pixmaps in paint events is also such a false assumption. If you start updating pixmaps at this pace in every paint event (assuming some changes indeed trigger those repaints), you'll be creating pixmaps your user will never even have a chance to see simply because the eye is not able to spot differences at such pace. It's enough to update the pixmap one-two times a second (depending on the nature of the data you are displaying) even if you happen to miss 1000 repaints that will render a stale pixmap. Eventually you'll render the right pixmap and it doesn't matter if it happens at repaint 1000 or 1001. What matters is that you'll render the pixmap once which, as you said yourself, is an expensive operation. You don't have such abilities if you update the thread in paint event --- you'll have to do it in every paint event.
    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.


  19. #18
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    Unless of course you like having frozen GUI
    Most ridiculous thing I have read in this thread. So you mean doing heavy operation anywhere else in one threaded app will not freeze the GUI?

    If you change a property that affects the looks of the widget then eventually you'll want to display those changes so every update of the pixmap involves triggering a repaint. And every repaint doesn't have to check and update the pixmap because if there was something to update, pixmap updating code would have triggered a repaint.
    Again wrong. So in case where 10 of properties change, you will update the pixmap 10 times? Yeah... that sounds like a solution...

    That's not an argument. If you have a device that's not fit to be used with some solution then you don't use that solution.
    Isn't that exactly the same thing what I have written?

    You don't have such abilities if you update the thread in paint event --- you'll have to do it in every paint event.
    Do you actually follow what I am writing? Please take a look at the code I have posted already in this thread. Short version:

    Qt Code:
    1. if(m_weatherPixmap.isEmpty())
    2. {
    3. updatePixmap(m_weatherPixmap);
    4. }
    To copy to clipboard, switch view to plain text mode 

    I do only an update when it is needed. I am updating something in every paintEvent?

    Final word:

    I see this conversion becoming unpleasant and I start seeing no point in going with it any forward. We can point out our imaginary situations and keep fighting over stuff, when in most cases we are both right. One thing for me is clear in here with all the respect, you are wrong and you can't say it is a misdesign to set a member variable in paintEvent. If it was so, then I bet that paintEvent would be declared as const method and it isn't. sizeHint() for example is a const method.

    And now grande finale:

    Take a look at http://doc.qt.nokia.com/latest/paint...gview-cpp.html and its implementation of paintEvent.
    Last edited by Rachol; 22nd June 2011 at 21:52. Reason: Extra content added

  20. #19
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Minimize window = images gone

    Quote Originally Posted by Rachol View Post
    Most ridiculous thing I have read in this thread. So you mean doing heavy operation anywhere else in one threaded app will not freeze the GUI?
    If it is not trying to redraw at this point then no.

    Again wrong. So in case where 10 of properties change, you will update the pixmap 10 times? Yeah... that sounds like a solution...
    No, I will update it at most once. Which part of the sentence I have written suggests that each property change will cause a separate update of the pixmap?

    Isn't that exactly the same thing what I have written?
    Please don't cut out my thoughts in half. A special case doesn't change a bad solution into a good one (we usually call them "workarounds" then).

    Do you actually follow what I am writing? Please take a look at the code I have posted already in this thread. Short version:

    Qt Code:
    1. if(m_weatherPixmap.isEmpty())
    2. {
    3. updatePixmap(m_weatherPixmap);
    4. }
    To copy to clipboard, switch view to plain text mode 

    I do only an update when it is needed. I am updating something in every paintEvent?
    Consider the following logic. Suppose you have a property "prop" that influences the way a widget looks.
    Qt Code:
    1. void Cls::setProp(... val) {
    2. if(m_prop == val) return;
    3. m_prop = val;
    4. update();
    5. }
    6. // ...
    7. QTimer *t = new QTimer;
    8. connect(t, SIGNAL(timeout()), SLOT(doSomething()));
    9. t->start(10); // 100Hz
    10. // ...
    11. void Cls::doSomething() {
    12. clsObj->setProp(...);
    13. }
    To copy to clipboard, switch view to plain text mode 
    Your pixmap will be updated 100 times a second, the sequence of events will be timeout, paint, timeout, paint, timeout, paint. I take it that you are a super human and will notice all those changes. Most people won't. A much better implementation will schedule a pixmap rebuild instead of calling update() in setProp. And the routine will make sure the pixmap is recreated at most X times a second where X is a sufficiently low value. I'm sure your slow device will benefit more from such solution than updating the pixmap at 100Hz.

    I see this conversion becoming unpleasant and I start seeing no point in going with it any forward. We can point out our imaginary situations and keep fighting over stuff, when in most cases we are both right. One thing for me is clear in here with all the respect, you are wrong and you can't say it is a misdesign to set a member variable in paintEvent. If it was so, then I bet that paintEvent would be declared as const method and it isn't. sizeHint() for example is a const method.
    It can't be const because you are passing a pointer to "this" to QPainter constructor which would break constness. In other words it wouldn't be possible to paint on a widget from within a const method without breaking constness.

    And now grande finale:

    Take a look at http://doc.qt.nokia.com/latest/paint...gview-cpp.html and its implementation of paintEvent.
    So your argument is that all code in Qt is perfectly designed? It's a pitty it is not so Just take a look at the "threaded fortune cookie" example and ask Bradley Hughes what he thinks of it Or look at one of the last Qt blog entries introducing ideas for Qt5 to see how much of Qt4 is considered "flawed design".

    My opinion is that you should act as if paintEvent() was const and so far I haven't heard anything that would convince me otherwise. Your pixmap updating idea is of course fine and it's often used (I often use it myself) but it is not necessary to violate "constness" of paintEvent to use such an approach. Not every simple code is good code. Simple solutions are often the best but not in every case. Please don't take it personally, I find this discussion very interesting and useful. It's one of those times when you have to really stretch your skills instead of just pointing people to Qt docs as it is the case with 90% of issues people come here with.
    Last edited by wysota; 22nd June 2011 at 22:37.
    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.


  21. #20
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo
    Thanks
    1
    Thanked 26 Times in 26 Posts

    Default Re: Minimize window = images gone

    I like your solution, but it is with some disadvantages:

    it just makes me do extra stuff ( handle updates every X ms ->extra timer, connection, method).
    If during the update time, m_prop changes twice, coming back to previous value, I miss that... Updating in paintEvent would do the update as soon as possible after update() is called. In such situation it is about changing the update value to something really small, which brings as back to the same thing, updating pixmap rapidly and then we can still miss the change. On the other hand a hidden widget wouldn't have to update itself, but in your solution it still has to do some extra checks and repainting. Going further it forces you not to do unnecessary updates when widget hidden and also show the correct content of the widget when it becomes visible, most probably without a delay. All this introduces a huge amount of things you have to take care of, that you wouldn't even think of if the logic was in paintEvent.

Similar Threads

  1. Restore the size of the window after minimize
    By SkripT in forum Qt Programming
    Replies: 10
    Last Post: 22nd September 2016, 17:23
  2. How to minimize a window to the taskbar
    By mooreaa in forum Qt Programming
    Replies: 2
    Last Post: 14th April 2011, 03:24
  3. Intercept minimize window event
    By vereteran in forum Newbie
    Replies: 8
    Last Post: 17th October 2009, 07:33
  4. Minimize other Window
    By johncharlesb in forum Qt Programming
    Replies: 1
    Last Post: 14th October 2007, 17:22
  5. Problem hiding main window on minimize
    By bpetty in forum Newbie
    Replies: 5
    Last Post: 18th September 2007, 18:41

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
  •  
Qt is a trademark of The Qt Company.