What can cause a QWidget to 'magically' revert to the previously painted state?
Since some time we are encountering a weird error, which only seems to be happening if we enable some specific combination of options in the application. Because I have not the vaguest clue where to look, I'm starting of with a bit of a vague question, hoping to get some pointers, which may lead to more direct questions (or maybe a solution)
What is happening is that we are updating the state of a bunch of QPushButtons programmatically (C++, Qt5.6.1-1) when some processing step finishes. Essentially, some buttons are disabled during the processing, and they are re-enabled when the processing finishes. What we now see happening is that the buttons indeed go back to the enabled state for a very short period of time, and then immediately go back to the previous disabled state. But this is only visually .... as soon as I move the mouse, the resulting paint event causes the buttons to redraw as they should. Apparently the internal state of the buttons is correct, but the way they are painted somehow flips back to the previous state.
Again, because I have no idea where to start looking: what can cause this? Has anyone noticed this before maybe?
I believe painting in Qt has some sort of double-buffer mechanism - could we be doing something weird that can cause this mechanism to misbehave? Could this behaviour be caused by a threading problem? Or should we really look into a totally different direction?
Hard to say. This needs to be debugged.
The question is why does
QStyle::State_Enabledto the style-option's state.
And actually this value is taken directly from
QWidget::isEnabled(), so i suspect that this issue is in your code.
as soon as I move the mouse, the resulting paint event causes the buttons to redraw as they should.
Well, do you call
update()manually after setting the desired state? Qt won't do that for you, so if you don't have a mouse move event or a window being obscured or something to trigger it, the widget will show the result of the last paint operation, not the current state.
@kshegunov Maybe it got hidden a bit in the long question, but the button initially does appear correctly, but after a short (< 0.1 secs) period of time the button flips back to the previous, disabled state. So if anything, I'd say there is a paint event with the old state of the button too much.
@raven-worx So you are suggesting I should put a breakpoint in
InitStyleOption()and have a look?
Btw, I have no doubt that I'm looking at a problem in our own code, as we didn't have the problem some time ago. I'm also planning to take some time at some point to do a 'binary search' for the release that introduced the problem (we have daily builds I can use for that), but that will take up considerable time, and before/while doing that exercise I wanted to see if someone on the forum maybe recognized the symptoms.
Maybe it got hidden a bit in the long question
Yes, I suppose.
I'd start by making sure that the state of the button(s) are correct at each paint event. Painting is pretty hard to debug, but a few
qDebug()calls inside a
paintEventoverride should take care of that. If the state(s) are indeed correct while the paint event is processed, then I'd start investigating the order in which events come in (if that can be an issue) - e. g. queued slot calls (from another thread). And finally if that's not the case I'd go to the double-buffering mechanism, although I haven't had issues with it up to now.
Not exactly an answer, but I hope it helps.
Are you aware of some sort of pastebin with this forum I could upload this mp4 to?
Any external site should do, but I can't advise on any one particular as I haven't had the need to upload videos, sorry.
Hi, for smaller videos dropbox also great.
Simply place in dropbox and right click to get a link.