Share a single idle timer for all event loops in wxQT

This commit is contained in:
Graham Dawes
2019-01-23 13:55:20 +00:00
parent 0c28952ff6
commit 6aecaa8845

View File

@@ -21,33 +21,48 @@
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
class wxQtIdleTimer : public QTimer class wxQtIdleTimer : public QTimer, public wxRefCounter
{ {
public: public:
wxQtIdleTimer( wxQtEventLoopBase *eventLoop ); wxQtIdleTimer();
~wxQtIdleTimer();
virtual bool eventFilter( QObject * watched, QEvent * event ); virtual bool eventFilter( QObject * watched, QEvent * event );
private: private:
void idle(); void idle();
void ScheduleIdleCheck();
private:
wxQtEventLoopBase *m_eventLoop;
}; };
wxQtIdleTimer::wxQtIdleTimer( wxQtEventLoopBase *eventLoop ) wxQtIdleTimer::wxQtIdleTimer()
{ {
m_eventLoop = eventLoop; // We need a QCoreApplication for event loops, create it here if it doesn't
// already exist as we can't modify wxAppConsole
if ( !QCoreApplication::instance() )
{
new QApplication(wxAppConsole::GetInstance()->argc, wxAppConsole::GetInstance()->argv);
}
connect( this, &QTimer::timeout, this, &wxQtIdleTimer::idle );
setSingleShot( true ); // Pass all events to the idle timer, so it can be restarted each time
// an event is received
qApp->installEventFilter(this);
connect(this, &QTimer::timeout, this, &wxQtIdleTimer::idle);
setSingleShot(true);
}
wxQtIdleTimer::~wxQtIdleTimer()
{
qApp->removeEventFilter(this);
} }
bool wxQtIdleTimer::eventFilter( QObject *WXUNUSED( watched ), QEvent *WXUNUSED( event ) ) bool wxQtIdleTimer::eventFilter( QObject *WXUNUSED( watched ), QEvent *WXUNUSED( event ) )
{ {
// Called for each Qt event, start with timeout 0 (run as soon as idle) // Called for each Qt event, start with timeout 0 (run as soon as idle)
if ( !isActive() ) if ( !isActive() )
m_eventLoop->ScheduleIdleCheck(); ScheduleIdleCheck();
return false; // Continue handling the event return false; // Continue handling the event
} }
@@ -59,35 +74,45 @@ void wxQtIdleTimer::idle()
wxTheApp->ProcessPendingEvents(); wxTheApp->ProcessPendingEvents();
// Send idle event // Send idle event
if ( m_eventLoop->ProcessIdle() ) if (wxTheApp->ProcessIdle())
m_eventLoop->ScheduleIdleCheck(); ScheduleIdleCheck();
}
namespace
{
wxQtIdleTimer *gs_idleTimer = NULL;
}
void wxQtIdleTimer::ScheduleIdleCheck()
{
wxQtEventLoopBase *eventLoop = static_cast<wxQtEventLoopBase*>(wxEventLoop::GetActive());
if ( eventLoop )
eventLoop->ScheduleIdleCheck();
} }
wxQtEventLoopBase::wxQtEventLoopBase() wxQtEventLoopBase::wxQtEventLoopBase()
{ {
// We need a QCoreApplication for event loops, create it here if it doesn't // Create an idle timer to run each time there are no events (timeout = 0)
// already exist as we can't modify wxAppConsole if ( !gs_idleTimer )
if ( !QCoreApplication::instance() )
{ {
new QApplication( wxAppConsole::GetInstance()->argc, wxAppConsole::GetInstance()->argv ); gs_idleTimer = new wxQtIdleTimer();
}
else
{
gs_idleTimer->IncRef();
} }
// Create an idle timer to run each time there are no events (timeout = 0) m_qtIdleTimer = gs_idleTimer;
m_qtIdleTimer = new wxQtIdleTimer( this );
// Pass all events to the idle timer, so it can be restarted each time
// an event is received
qApp->installEventFilter( m_qtIdleTimer );
m_qtEventLoop = new QEventLoop; m_qtEventLoop = new QEventLoop;
} }
wxQtEventLoopBase::~wxQtEventLoopBase() wxQtEventLoopBase::~wxQtEventLoopBase()
{ {
qApp->removeEventFilter(m_qtIdleTimer); if ( gs_idleTimer->GetRefCount() <= 1 )
gs_idleTimer = NULL;
delete m_qtEventLoop; delete m_qtEventLoop;
delete m_qtIdleTimer;
} }
void wxQtEventLoopBase::ScheduleExit(int rc) void wxQtEventLoopBase::ScheduleExit(int rc)