Exception on setStyleSheet(). Can't figure why.
-
Hello.
I have pretty big project and unfortunately I can't provide small reproducible piece of code. But I glad to hear ideas. I have a 2 main windows. When I open a new one I delete previously opened. And at some point I'm calling:
qApp->setStyleSheet(styleSheetStr);
And this line fails with exception
read access violation at: 0x0
.
The call stack after calling of the method looks like this:QJsonObject::value Qt5Cored 0x66f535ca QUndoGroup::cleanChanged Qt5Widgetsd 0x6427bb1c QUndoGroup::cleanChanged Qt5Widgetsd 0x643cfcfd QUndoGroup::cleanChanged Qt5Widgetsd 0x643c49ac QUndoGroup::cleanChanged Qt5Widgetsd 0x6429fc8b SkinManager::setSkin SkinManager.cpp 30 0x13f410965
So the actual fail happens in
QJsonObject::value
. What can cause this behavior or how can I debug a problem? -
'''
With no code, it is just random guesses/questions, but sometimes that does work too :)where does styleSheetStr lives?
Can it run out of scope.if you remove the line, it will not fail ?
the qApp remains valid and non zero at all times?
if you do not delete the previously opened main window (for test) does it still fail ?
-
Since QApplication knows about all the top level widgets, my guess here is that you are deleting one of the QMainWindow objects and your application doesn't realize it happened by the time you try to set a style sheet.
If you are doing something like
delete mainWindow1
thenqApp->setStyleSheet()
that may be your issue. Try changing to amainWindow1->deleteLater()
and see if the crash goes away.Also definitely check into @mrjj's suggestions, especially making sure qApp is a legit pointer.
You can also try calling the change to stylesheets later, after the event loop has had a chance to clean up the main window that was destroyed. You can do this with a
QTimer::singleShot
. This of course assumes thedeleteLater()
doesn't fix the issue. -
Thank you guys. The problem exactly related to deleting a window. Without deleting it everything works ok. Unfortunately nothing from the above helped and with minimal example the issue does not reproduces. But now I know where to dig. Thanks.
-
An update. After investigating I found the problem. But I have a lack of knowledge in the field.
For my project I need borderless windows. I'm using aQWinWidgets
from qt-solutions . It uses some undocumented functions to obtain window handle (on Windows). And my problem arises when I'm destroying this window withDestroyWindow()
. I don't know what's happens inside, but somehowQApplication
,HWND
and stylesheets relates to each other. -
This is pure speculation:
In the QwinWidgets code for its event handler it has
case QEvent::Close: ::SetActiveWindow(hParent); if (w->testAttribute(Qt::WA_DeleteOnClose)) deleteLater(); break;
so if you set that flag on your window, and do not delete it yourself. will it still crash ?
window->setAttribute(Qt::WA_DeleteOnClose);
That way the QwinWidget controls the deletion since it seems to manage it.
Also, if you are only using QwinWidget for a borderless window, you could maybe just use a normal window and
window->setWindowFlags ( Qt::Popup | Qt::Dialog | Qt::FramelessWindowHint );
(might need to adjust flags)
-
@mrjj, thank you for reply. I can't use just flags with a normal window for several reasons. One of them - I have to keep standard window functionality like minimize/maximize anumations, aero shake, aero snap. The
QEvent::Close
also not works - the program simply never reaches this line. -
Ok, so QWinWidgets does provide more than borderless. Just checking.
Looking In qapplication.cpp file, at
setStyleSheet, i see nothing that looks like anything from the call stack dump. ?It does call QApplication::setStyle(QStyle *style) which will
iterate over all Widgets.So if you deleted QWinWidgets still to be found, that would explain it.
But why should it be there still.you could check it fast with
foreach (QWidget *widget, QApplication::allWidgets()) qDebug() << widget->objectName();
-
@mrjj
Yes, withQWinWidget
I'm able to grab native handle and do whatever I want.
I did the check and didn't found anything suspicious.
One thing that helped me - is a call toqApp->style()->unpolish(qApp);
. After this line I'm able to callqApp->setStyleSheet()
without an exception. -
@nikitablack
ok, so its not due to it sticking around in widget list.so
qApp->style()->unpolish(qApp)
is kinda a "fix" even we never know the real reason.