Application stylesheet
-
Hi,
I have a very difficult stylesheet problem. I use a huge stylesheet in my application. Since Qt's stylesheet system is, let's say, very buggy I have to call the qApp->setStyleSheet( something ); several times. I display many QMainWindows with toolboxes and dialogs. I have to call qApp->setStyleSheet in every mainwindow instantiation (example because of this: http://stackoverflow.com/questions/24447276/qcombobox-text-colour-wont-change-with-style-sheet and many other reasons). That's ok.
Sometimes this call cause a crash (because some dangling pointer by Qt), so I'm using it something like that:bool applyAppStyleSheet() { QString styleToApply = appStyleSheetFile.readAll(); try { qApp->setStyleSheet( styleToApply ); return true; } catch(...) { try { //try it again... sometimes works, no idea why... qApp->setStyleSheet( styleToApply ); return true; } catch(...) { //nightmare... return true; } } }
In the qss stylesheet I'm using properties selector nearly for every widget:
QWidget[Style="ToolRack"] QToolButton { border: blablabla etc }
Of course in code I use
xyWidget->setProperty( "Style", "ToolRack" ), to apply my style in qss.In the app I'm using some QWidgets for a QPainter helper (own special painting, but doesn't matter). It's a difficult story, but I have to paint something and I'm using the widget's render function to draw something. I cannot change this. I'm using a hard coded stylesheet for this special, local widget. I set it's property to something, I set it's parent to nullptr, but somehow the application's stylesheet applied to this widget:
void xyViewer::Draw( QPainter* aDC ) { m_TableWidget->setProperty( "Style", "xyViewer" ); //for sure not find style in qss by [Style="ToolRack"] m_TableWidget->setParent( nullptr ); //just to be sure not to reach it at all QString style = "QTableWidget { " + QString( "gridline-color: rgb(%1, %2, %3);" ).arg( m_TextColor.red() ).arg( m_TextColor.green() ).arg( m_TextColor.blue() ) + //gridcolor QString( "background-color: rgb(%1, %2, %3);" ).arg( m_BgrColor.red() ).arg( m_BgrColor.green() ).arg( m_BgrColor.blue() ) + //backgroundcolor " }"; m_TableWidget->setStyleSheet( style ); aDC->save(); m_TableWidget->setFont( m_font ); m_TableWidget.setGeometry( something ); //positioning aDC->translate( m_Bounds.left(), m_Bounds.top() ); aDC->scale( scalingFactor, scalingFactor ); m_TableWidget.render( aDC ); //main step QWidget's render aDC->restore(); inheritedViewer::Draw( aDC ); }
The real problem: If in applyAppStyleSheet something went wrong, somehow the application stylesheet applied to my local, separated m_TableWidget. Doesn't matter that I call setStyleSheet in every Draw call, and I set a different Property, and has no parent. Only helps if I restart the whole application.
-
@Fegyi I have no idea why setting your stylesheet should cause problems - the project I currently work in has a similar setup, and we have never had such problems (that had the root cause in the stylesheet area).
What we did discover, is that dynamically changing a property, does not cause a recalculation of the stylesheet. This is not very well documented, well, not at all, except here: https://wiki.qt.io/Dynamic_Properties_and_Stylesheets - see the last paragraph. The sequence
unpolish()
,polish()
andupdate()
needs to happen each time you dynamically change a property -
First of all thanks for your comment. I know that the property changes cause no update. My problem is: if once something went wrong (crash) in qApp->setStyleSheet call, from that point the style system become sick, and doesn't matter if I can call it again without crash. I debugged it, and I figured out, that it has the crash in the polish() function when qt go through some cached widget vector, and polish them one by one. The cache vector contains some dangling pointers. I dont know how to rebuild that cache.
Now I figured out that the crash happens if I call it after a QMainWindow close. I thought if I call a qApp->proceesEvents may helps (because maybe the setStyleSheet called while deletion is still in progress), but not... Now I just removed the function call after window closing. It healed the symptom, but the real problem is still exist.Thanks!
Fegyi -
Hi and welcome to devnet,
Can you reproduce this with a minimal compilable example ?
-
@Fegyi If your actual concern is the crash, then maybe you could try to focus an that a bit more - can you get to a minimum compilable example? Your story sound actually quite well known - I had the same issue in the application I currently work on. Also there we used to have mysterious crashes, that seemed related to the stylesheet, because it always crashed because of some dangling pointers in that area. However, it turned out eventually, that we actually made a subtle memory management error in the base-layer of the application, which was only surfacing in the stylesheet-related parts of Qt.
Therefore, try to create a minimal example, that compiles (and crashes ;-) ). It is that particular exercise that actually showed me what we did wrong (because I couldn't create a minimal compilable, crashing example)