mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-22 14:20:35 +08:00
wxQt: Fix Qt objects destruction
Fix crashes start to appear when porting to Qt version 6.x
This commit is contained in:
@@ -83,17 +83,9 @@ public:
|
||||
// Set immediately as it is used to check if wxWindow is alive
|
||||
wxWindow::QtStoreWindowPointer( this, handler );
|
||||
|
||||
// Handle QWidget destruction signal AFTER it gets deleted
|
||||
QObject::connect( this, &QObject::destroyed, this,
|
||||
&wxQtEventSignalHandler::HandleDestroyedSignal );
|
||||
|
||||
Widget::setMouseTracking(true);
|
||||
}
|
||||
|
||||
void HandleDestroyedSignal()
|
||||
{
|
||||
}
|
||||
|
||||
virtual Handler *GetHandler() const override
|
||||
{
|
||||
// Only process the signal / event if the wxWindow is not destroyed
|
||||
@@ -383,42 +375,44 @@ protected:
|
||||
|
||||
bool touchEvent(QTouchEvent *touch)
|
||||
{
|
||||
wxWindow *win = wxWindow::QtRetrieveWindowPointer(this);
|
||||
bool handled = false;
|
||||
|
||||
for (const QTouchEvent::TouchPoint& tp : touch->touchPoints())
|
||||
if ( wxWindow *win = wxWindow::QtRetrieveWindowPointer(this) )
|
||||
{
|
||||
wxEventType evtype = wxEVT_NULL;
|
||||
|
||||
switch (tp.state())
|
||||
for (const QTouchEvent::TouchPoint& tp : touch->touchPoints())
|
||||
{
|
||||
case Qt::TouchPointPressed:
|
||||
evtype = wxEVT_TOUCH_BEGIN;
|
||||
break;
|
||||
wxEventType evtype = wxEVT_NULL;
|
||||
|
||||
case Qt::TouchPointMoved:
|
||||
evtype = wxEVT_TOUCH_MOVE;
|
||||
break;
|
||||
case Qt::TouchPointReleased:
|
||||
evtype = wxEVT_TOUCH_END;
|
||||
break;
|
||||
switch (tp.state())
|
||||
{
|
||||
case Qt::TouchPointPressed:
|
||||
evtype = wxEVT_TOUCH_BEGIN;
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
case Qt::TouchPointMoved:
|
||||
evtype = wxEVT_TOUCH_MOVE;
|
||||
break;
|
||||
case Qt::TouchPointReleased:
|
||||
evtype = wxEVT_TOUCH_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
wxMultiTouchEvent evt(win->GetId(), evtype);
|
||||
|
||||
// Use screen position as the event might originate from a different
|
||||
// Qt window than this one.
|
||||
wxPoint2DDouble pt = wxQtConvertPointF(tp.screenPos().toPoint());
|
||||
wxPoint ref = pt.GetFloor();
|
||||
|
||||
evt.SetPosition(win->ScreenToClient(ref) + (pt - ref));
|
||||
evt.SetSequenceId(wxTouchSequenceId(wxUIntToPtr((unsigned)tp.id())));
|
||||
// Qt doesn't provide the primary point flag
|
||||
|
||||
handled |= win->ProcessWindowEvent(evt);
|
||||
}
|
||||
|
||||
wxMultiTouchEvent evt(win->GetId(), evtype);
|
||||
|
||||
// Use screen position as the event might originate from a different
|
||||
// Qt window than this one.
|
||||
wxPoint2DDouble pt = wxQtConvertPointF(tp.screenPos().toPoint());
|
||||
wxPoint ref = pt.GetFloor();
|
||||
|
||||
evt.SetPosition(win->ScreenToClient(ref) + (pt - ref));
|
||||
evt.SetSequenceId(wxTouchSequenceId(wxUIntToPtr((unsigned)tp.id())));
|
||||
// Qt doesn't provide the primary point flag
|
||||
|
||||
handled |= win->ProcessWindowEvent(evt);
|
||||
}
|
||||
|
||||
return handled;
|
||||
@@ -448,11 +442,9 @@ protected:
|
||||
|
||||
void tapandholdTriggered(QTapAndHoldGesture *gesture, QEvent *event)
|
||||
{
|
||||
wxWindow *win = wxWindow::QtRetrieveWindowPointer( this );
|
||||
|
||||
if (gesture->state() == Qt::GestureFinished)
|
||||
if ( wxWindow *win = wxWindow::QtRetrieveWindowPointer( this ) )
|
||||
{
|
||||
if ( win )
|
||||
if (gesture->state() == Qt::GestureFinished)
|
||||
{
|
||||
wxLongPressEvent ev(win->GetId());
|
||||
ev.SetPosition( wxQtConvertPoint( gesture->position().toPoint() ) );
|
||||
@@ -461,15 +453,14 @@ protected:
|
||||
win->ProcessWindowEvent( ev );
|
||||
event->accept();
|
||||
}
|
||||
|
||||
}
|
||||
else if (gesture->state() == Qt::GestureStarted)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->accept();
|
||||
else if (gesture->state() == Qt::GestureStarted)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ public:
|
||||
long style = 0,
|
||||
const wxString &name = wxASCII_STR(wxStaticTextNameStr) );
|
||||
|
||||
~wxStaticText();
|
||||
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString &label,
|
||||
|
||||
+13
-10
@@ -61,17 +61,20 @@ void wxQtPushButton::action()
|
||||
|
||||
bool wxQtPushButton::event(QEvent* e)
|
||||
{
|
||||
switch ( e->type() )
|
||||
if ( GetHandler() )
|
||||
{
|
||||
case QEvent::EnabledChange:
|
||||
case QEvent::Enter:
|
||||
case QEvent::Leave:
|
||||
case QEvent::FocusIn:
|
||||
case QEvent::FocusOut:
|
||||
GetHandler()->QtUpdateState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch ( e->type() )
|
||||
{
|
||||
case QEvent::EnabledChange:
|
||||
case QEvent::Enter:
|
||||
case QEvent::Leave:
|
||||
case QEvent::FocusIn:
|
||||
case QEvent::FocusOut:
|
||||
GetHandler()->QtUpdateState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QPushButton::event(e);
|
||||
|
||||
@@ -35,6 +35,24 @@ wxStaticText::wxStaticText(wxWindow *parent,
|
||||
Create( parent, id, label, pos, size, style, name );
|
||||
}
|
||||
|
||||
wxStaticText::~wxStaticText()
|
||||
{
|
||||
// Dissociate the buddy before QLabel get destroyed to avoid this assertion:
|
||||
//
|
||||
// ASSERT failure in QLabel: "Called object is not of the correct type (class
|
||||
// destructor may have already run)", file...
|
||||
//
|
||||
// Explanation:
|
||||
// ------------
|
||||
// When setBuddy() is called to set the buddy (see Create() below), Qt (internally)
|
||||
// connects the QLabel to the QObject::destroyed() signal to be notified of the
|
||||
// buddy's destruction and to dissociate it. Since the QLabel and its buddy are
|
||||
// the same object, setBuddy() will be called on an already destroyed object, producing
|
||||
// the aforementioned assertion message.
|
||||
|
||||
GetQLabel()->setBuddy( nullptr );
|
||||
}
|
||||
|
||||
bool wxStaticText::Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxString &label,
|
||||
|
||||
+5
-18
@@ -350,36 +350,23 @@ wxWindowQt::~wxWindowQt()
|
||||
{
|
||||
if ( !m_qtWindow )
|
||||
{
|
||||
wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::~wxWindow %s m_qtWindow is null"), GetName());
|
||||
// Pseudo windows don't have a valid m_qtWindow, so just return.
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete only if the qt widget was created or assigned to this base class
|
||||
wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::~wxWindow %s m_qtWindow=%p"), GetName(), m_qtWindow);
|
||||
|
||||
if ( !IsBeingDeleted() )
|
||||
{
|
||||
SendDestroyEvent();
|
||||
}
|
||||
|
||||
// Avoid processing pending events which quite often would lead to crashes after this.
|
||||
QCoreApplication::removePostedEvents(m_qtWindow);
|
||||
|
||||
// Block signals because the handlers access members of a derived class.
|
||||
m_qtWindow->blockSignals(true);
|
||||
|
||||
if ( s_capturedWindow == this )
|
||||
s_capturedWindow = nullptr;
|
||||
|
||||
DestroyChildren(); // This also destroys scrollbars
|
||||
SendDestroyEvent();
|
||||
|
||||
if (m_qtWindow)
|
||||
QtStoreWindowPointer( GetHandle(), nullptr );
|
||||
QtStoreWindowPointer( GetHandle(), nullptr );
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
SetDropTarget(nullptr);
|
||||
#endif
|
||||
|
||||
DestroyChildren(); // This also destroys scrollbars
|
||||
|
||||
delete m_qtWindow;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user