Qt4-preview-feedback Archive, May 2007
Re: Update: Re: Crash: Qt4.3 bug
Message 1 in thread
Hello,
Le mercredi 02 mai 2007, David Faure a écrit :
> On Monday 30 April 2007, Kleag wrote:
> > I have no idea why it happens, particularly because I use only two
> > KToolBar that are never deleted.
>
> valgrind would tell ;)
Well, I tried before to use valgrind. It's right, It reported the error. But
it wasn't very useful to me as it just printed out the same stack trace as
gdb, deep inside the Qt control loop. As I don't now Qt internals enough,
this does not give me valuable data.
I already posted a valgrind output previously in this thread, on april first
and it wasn't a fish :-)
But I (finally!!) found the origin of the crash and, as Thiago asked,
created "a small, self-contained testcase that illustrates the bug". The
problem appears when I replace the central widget. It seems to be a
regression from Qt4.1.3 which announced this bug as corrected.
The code below crashes:
*****************************
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QTimer>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMainWindow w;
QPushButton* b1 = new QPushButton("Abc",&w);
w.setCentralWidget(b1);
w.show();
QPushButton* b2 = new QPushButton("Def",&w);
w.setCentralWidget(b2);
return app.exec();
}
*****************************
Furthermore, as a direction to look at, the following diff allows the above
program to work:
******************************
Index: qmainwindowlayout.cpp
===================================================================
--- qmainwindowlayout.cpp (révision 660602)
+++ qmainwindowlayout.cpp (copie de travail)
@@ -1561,17 +1561,17 @@
void QMainWindowLayout::animationFinished(QWidget *widget)
{
-#ifndef QT_NO_TOOLBAR
- if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) {
- QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(tb->layout());
- if (tbl->expanded && tbl->collapsing) {
- tbl->expanded = false;
- tbl->collapsing = false;
- tbl->invalidate();
- tb->update();
- }
- }
-#endif
+// #ifndef QT_NO_TOOLBAR
+// if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) {
+// QToolBarLayout *tbl = qobject_cast<QToolBarLayout*>(tb->layout());
+// if (tbl->expanded && tbl->collapsing) {
+// tbl->expanded = false;
+// tbl->collapsing = false;
+// tbl->invalidate();
+// tb->update();
+// }
+// }
+// #endif
if (widget != pluggingWidget)
return;
******************************
I hope this will allow the bug to be corrected.
Best regards,
Kleag
--
[ signature omitted ]
Message 2 in thread
Kleag wrote:
> The code below crashes:
> *****************************
> #include <QApplication>
> #include <QMainWindow>
> #include <QPushButton>
> #include <QTimer>
>
> int main(int argc, char **argv)
> {
> QApplication app(argc, argv);
>
> QMainWindow w;
> QPushButton* b1 = new QPushButton("Abc",&w);
> w.setCentralWidget(b1);
> w.show();
> QPushButton* b2 = new QPushButton("Def",&w);
> w.setCentralWidget(b2);
>
> return app.exec();
> }
Ah, you nailed it. :)
Fixed for 4.3.0.
Jacek
--- gui/kernel/qapplication.h 2007/03/01 07:25:45.000000000
+++ gui/kernel/qapplication.h 2007/05/04 13:00:16.000000000
@@ -309,6 +309,7 @@
friend class QETWidget;
friend class Q3AccelManager;
friend class QTranslator;
+ friend class QWidgetAnimator;
#ifndef QT_NO_SHORTCUT
friend class QShortcut;
#endif
--- gui/widgets/qwidgetanimator.cpp 2007/03/14 13:40:28.000000000
+++ gui/widgets/qwidgetanimator.cpp 2007/05/04 13:00:16.000000000
@@ -16,6 +16,8 @@
#include <QtGui/qwidget.h>
#include <QtGui/qtextedit.h>
#include <QtGui/private/qwidget_p.h>
+#include <QtGui/qapplication.h>
+#include <QtGui/private/qapplication_p.h>
#include <qdebug.h>
#include "qwidgetanimator_p.h"
@@ -63,6 +65,21 @@
{
QRect final_geometry = _final_geometry;
+ /* If QApplication::exec() hasn't been called yet, there is no point
trying to animate
+ anything. It won't work, since there are no timers, and it will
crash when the
+ finshed(QWidget*) signal is delivered through the qeued connection
to QMainWindowLayout,
+ if the widget is deleted before QApplication::exec() is called. This
happens when
+ you f.ex. call QMainWindow::setCentralWidget() twice before exec().
*/
+ if (qApp != 0 && !qApp->d_func()->in_exec) {
+ if (!final_geometry.isValid() && !widget->isWindow()) {
+ // Make the wigdet go away by sending it to negative space
+ QSize s = widget->size();
+ final_geometry = QRect(-500 - s.width(), -500 - s.height(),
s.width(), s.height());
+ }
+ widget->setGeometry(final_geometry);
+ return;
+ }
+
QRect r = widget->geometry();
if (r.right() < 0 || r.bottom() < 0)
r = QRect();
@@ -70,9 +87,6 @@
if (r.isNull() || final_geometry.isNull())
animate = false;
-// if (r != final_geometry)
-// qDebug() << "QWidgetAnimator::animate():" << widget << r <<
_final_geometry;
-
AnimationMap::const_iterator it = m_animation_map.constFind(widget);
if (it == m_animation_map.constEnd()) {
if (r == final_geometry) {
To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx